I set myself a challenge this year to try out a new programming language, and this is a write up of how I got on with ‘go’, outlining the installation process, basic coding and then packaging the program for end use, with some comparisons along the way with Python (what I normally use).
The aim was not to use ChatGPT for writing code (I did use it for debugging), but there’s lots of other help available online which I used, including the tour of go : https://go.dev/tour/welcome/1 I use VS code for editing and installed the go lang extension.
For a test project I decided to write a crontab prettifier. My co-worker has been complaining about the state of the crontab on the system we work on – because each line is so long its unreadable. So I thought this would be a nice toy project to test out go and parse the crontab and print it in a more readable way. Currently, it looks rubbish:
Why Go?
- It’s supposed to have the benefits of the ‘C’ language with a more modern / improved take, and especially suitable for web apps – which is how most software gets delivered these days!
- It’s different to Python – statically typed – i.e. your variables MUST only hold one type, unlike Python, which is often the cause of errors (although there’s benefits too)
- It’s a compiled rather than interpreted language, which is faster, and I wanted to see how that affected the development process
Go lang installation & getting started
On Mac: brew install go
There are ways to install different versions of go and build from source, but compared to Python, that was a total breeze!
To run ‘hello world’ (code below), go run hello.go
. This is really interesting because that must be compiling and running it all at the same time – seems like that will make it easy to test changes!
package main import "fmt" func main() { fmt.Println("Hello, 世界") }
Coding Process
Here’s the code gist described below:
1 and 2 – get command line args and current user
For my crontab prettifier I want to make the crontab user selectable by a command line argument, but to drop back to the current user if none was supplied. After looking that up, it seemed like the flag package would do the job to get the command line args, and os/user package could get the current user. I noticed:
- When I added some code that required a module import, if it wasn’t there, the VS code extension added it upon saving, and if there was an unused import, it was removed. Really like that!
- Strings are immutable in go. It was a bit annoying / verbose to have to declare another variable for the username, I couldn’t just overwrite the empty string if no command line argument was found. I’m sure there are reasons for that, but it’s quite different coming from Python!
3 – open text file
Pretty easy to understand after looking that up – I did run into permissions issues and had to run as sudo but that’s a system rather than language issue. I noticed:
- Go has the
defer
keyword to postpone executing something until the end of the function, i.e. to close an open file. A bit like how thewith
context manager works in Python, at least on the surface.
4 – for loop over each line
I used the `lines := bufio.NewScanner()
function and then for lines.Scan()
which didn’t seem quite as understandable as looping over a list or file lines in python but worked ok
5 – parsing the crontab
This was basically just splitting up each line / string, removing what I didn’t need (the days of the week, and the long path to the python executable, and long path to the python script), and then printing it with colours (hex codes). I notiticed:
- String immutability made this more verbose than Python, but perhaps clearer to see what each string actually is…
Final thoughts – you’ll obviously see that I’ve hardcoded what I wanted to split strings on, and haven’t done error handling if those aren’t present – it’s just a learning project! At first, It tested it on a text file, and it worked ok, but then with the real crontab it failed. The program crashed but gave which line the error was on, which helped me realise that the first few lines of all crontabs are comments starting with #, so those parts needed skipping – again easy using the continue
keyword.
Compilation and Packaging
To compile the code: go build cronlist.go
Really easy and fast – it was 2.4Mb but dead easy to copy to another computer and have it work straight away, nothing else needed installing – much better than Python on that front. The end result is great as well:
Next steps
What I’d like to know more about is the third party ecosystem and packages, what is available and how easy they are to incorporate into a go project. Python is fantastic with so many different packages that help you build complex and versatile things really fast. I’d be interested to discover if go has equivalents of numpy, django, streamlit etc, but for now, I really like go, and I definitely want to learn more!
Leave a Reply