Wolfmans Howlings

A programmers Blog about Programming solutions and a few other issues

Adventures in learning GO

Posted by Jim Morris on 2026-02-13 12:40:24 +0000

I just turned 70, unbelievable I know. At this age and after retiring (which I did quite a while ago) it is important to keep your mind active otherwise it turns to Jello. So in addition to several other on going projects I have (continuing Robotics, Drones, and 3d Printing and CNC milling) I continue to Program for fun, even though that was my job for 40 odd years.

The languages I use the most at the moment are C++, Python, Ruby and also Assembly language (RISC-V) and occasionally Forth. I used to do a lot of Assembly back in the 70's and 80's, but not so much since then, I find it really stretches my mind. I've been doing some retro on the 6502 and 6800 assembly, and recently on the not-so-retro RISC-V on the RP2350.

However nothing really challenges you like learning a totally new programming language. Back in the day I used to pick them up really quickly, I became quite proficient in Java, Erlang and some other ones, but as I got older it was harder and harder to learn new ones, so I stuck to the ones I knew best.

I got intrigued by Go Lang, as it used to be called I believe, when I saw a project for the PicoCalc on the RP2040 for a RPN calculator written in Tinygo. Although I did not pursue that very far. I started to look at Go on Linux instead. I was hesitant at first, it was quite hard TBH to get up to speed, mainly because of my age.

These days of course you can turn to YouTube and there are a ton of Learning Go channels. Also there is a ton of online guides to getting started with Go. Not to mention that you can ask an AI like Claude to write some Go code for you, which it seems to do very well, and is excellent as a starting point for your own projects.

I found it an intriguing language, at first glance it has a very simple syntax, very similar to C. But there are nuances which take quite a bit of getting used to, especially when coming from a OOP and C++ background. Things like Interfaces are quite different to what you see in Java for instance. Also Structure embedding (or composition) which allows a sort of OOP inheritance. Overall I find Go quite intuitive and easy to program in, once you get over the initial syntax hurdles, and its odd package and file location requirements.

The one thing that really blew my mind was how easy it was to cross compile a pure Go program for other platforms (Linux, Windows and Mac), this would be great for some of the other projects I maintain, which currently I only support for Linux as I don't use Windows or Mac. One I wrote which is in relatively wide use Smoopi is written in Python and Kivy and therefore is relatively portable, except I have no way to test on other platforms.

Discoveries

Here are some interesting things I discovered while getting into the Go language.

Using a type interface to make things type safe.

I am writing a GCode viewer in Go... just because :) and the drawing is using SDL3 which all works quite well using the go-sdl3 library. After parsing the GCode file I create all the lines and arcs needed to display it. As SDL3 requires all the geometry to be redrawn every frame, rather than incrementally as some graphics packages do, I store an array/slice of geometries that it should iterate through every frame. The geometries each have a structure that just stores what they need, like a Line has x1, y1, x2, y2 and an Arc has origin x and y and start and end angles and a radius etc... Rather than create a slice of any I want to be informed at compile time if I try to put non-geometry in this slice. Now there is a syntax to create an interface that has restricted types...

type Geometry interface {
    Arc | Line
}

However this can only be used when passing parameters to a function that uses Generic types eg

func Draw[T Geometry](g T) err {
    ...
}

You can pass the Geometry into this func and will get a compile time error if it isn't a Arc or a Line, however there appears to be no way to create a slice of type Geometry so that you can only insert Line or Arc. Luckily there is a way to do this but it is rather messy IMO.

// these are here merely to make the Geometries type safe
type GeometryType  struct{}
type GEO interface {
    isAGeometry(GeometryType)
}
type geo struct {
    geo GeometryType
}
func (g geo) isAGeometry(GeometryType)  { }

// These are some of the geometries I want to draw
type Arc struct {
    geo
    CenterX, CenterY, Radius, StartAngle, EndAngle float32
}

type Line struct {
    geo
    X1, Y1, X2, Y2 float32
    Color Color
}

As GEO is a regular interface you can var geoms []GEO to create a slice of GEOs that will only accept an Arc or Line. The GEO interface defines a dummy isAGeometry to mark a struct as a GEO, that is its only purpose. The geo struct is just a convenience so that I can just insert that in any struct I want to qualify as a GEO as it has the required interface.

This works as I want but seems a little verbose as it requires two structs and an interface just for this purpose.

Database and SQL

I am very impressed with the SQL support in Go. I have done a lot of database hacking in my day and usually used a high level ORM (Spring in Java, sequel in Ruby etc).

My initial project in Go was to port my SVD database lookup tool from Ruby to Go more here

The first go around I just used the Go builtin SQL library and hand coded all the SQL statements, this was relatively easy but tedious. Then I discovered the SQLC tool, and the Goose migration tool, and I really liked these. SQLC takes a lot of the tedium out of extracting data from the databases, and the Goose migration tool makes the usual SQL migration stuff manageable. I used both of these to write the SVD web based documentation tool which is now live.

The web server stuff in Go is very easy, just a few lines of code get you started. As I have used HAML in the past (as I hate HTML) I found GOHT which provides a templating system based on HAML. Using this I was able to knock up a passable interface for displaying the peripherals, registers and fields in the web app. As usual I used a PostgreSQL database and using the above mentioned SQLC and GOOSE was able to access the database fairly easily. Also new to me was HTMX which is a useful JavaScript library for issuing AJAX requests. So putting all that together I was able to implement this lookup service in surprisingly short order.

I also added a utility to read the SVD XML files and write them to the database which is a relational database with a table of the various MCUs, then a table with all the peripherals relating back to the MCU, and then a table with all the registers relating back to the peripheral, then lastly a table with all the bit fields for the registers. So I can easily add new SVDs.

GUIS and Graphics

I was contemplating porting my Smoopi project to Go, but that is a huge undertaking and I am not sure I want to commit to that. In the process of investigating the possibilities I searched for some GUI libraries, and the foremost seems to by Fyne. This seems a fairly solid and complete GUI library for Go. Somewhat different to Kivy which I used for Smoopi (which is Python based). All the basic things are there that I would need, and I mocked up a "Smoopi-lite" to get a handle on things. It looks OK. I think I prefer Kivys .KV approach, to the Fyne everything in code, which can get a little verbose and tedious, but works. I do like the virtually seamless integration of Go routine handling in Fyne, unlike in Kivy/Python where using async is quite tedious and error prone.

Smoopi has a GCode viewer which is essential for its use as a CNC front end for graphically locating and setting the workspace coordinate systems. I wrote a fairly simple GCode parser in Go, then used a SDL3 Pure Go library to render the various layers, you only really need a way to draw lines and arcs to do this. I was able to do a simplistic GCode viewer this way in a relatively few lines of code. I spent most of the time trying to understand Go interfaces and type safety as mentioned above in this process. Also trying to find the right mapping of SDL3 calls to Go calls, they are definitely not 1:1 in this library.

Summary

Overall I quite like Go, and I think it will be my new favorite programming language for servers and CLIs (and maybe GUIS). I'll probably stick to C++ and forth for now for the MCUs I use (mostly STM32xxx and RP2350/2040). Although I may take a look at Tinygo for those in the future.

Posted in go,programming,GUI,SQL  |  Tags go,sql,gui  |  no comments

Comments

(leave email »)