2024-06-08

Go katas

I’ve been working in the DevOps (sysadmin) and cybersecurity domains. That means I work with computer programs all the time. I have to understand how they work so I can (help other people to) use them and protect them. From time to time I also write programs, like when building tools or automating tasks.

In order to understand and create programs you have to know a programming language’s constructs (their syntax and semantics), libraries and the idiomatic way of using them. In other words you need to learn to program well in your language of choice. But how if you don’t get to program every day?

There’s a similar situation in martial arts. You don’t want to be discovering and learning fighting techniques in a fight. Martial arts’ solution is called kata. It’s a set of fighting techniques that are regularly practiced until internalized. Gokatas is my implementation of this idea for Go programming.

The get started install the gokatas command line tool:

go install github.com/gokatas/gokatas@latest

One practice cycle looks like this:

  1. Choose a kata and clone it. By default katas are shown in alphabetical order but you can sort them by number of lines.
❯ gokatas -sortby lines -wide
Name       Description                      Lines  Done  Last done    Standard library packages      URL
----       -----------                      -----  ----  ---------    -------------------------      ---
bcounter   io.Writer implementation         22     5x    22 days ago  fmt                            https://github.com/gokatas/bcounter.git
netcat     TCP client                       26     1x    6 days ago   io log net os                  https://github.com/gokatas/netcat.git
dup        duplicate lines in files         30     4x    11 days ago  fmt os strings                 https://github.com/gokatas/dup.git
clock      TCP time server                  38     4x    12 days ago  io log net time                https://github.com/gokatas/clock.git
proxy      TCP middleman                    39     1x    6 days ago   io log net                     https://github.com/gokatas/proxy.git
areader    io.Reader implementation         43     7x    2 days ago   bytes testing                  https://github.com/gokatas/areader.git
shop       HTTP server                      43     1x    6 days ago   fmt http log                   https://github.com/gokatas/shop.git
direction  enumerated type with iota        45     3x    12 days ago  fmt rand                       https://github.com/gokatas/direction.git
books      sorting                          49     5x    20 days ago  fmt os sort strings tabwriter  https://github.com/gokatas/books.git
errgo      errors are values                49     2x    9 days ago   fmt io os                      https://github.com/gokatas/errgo.git
fetch      HTTP client                      49     4x    11 days ago  fmt http io os time            https://github.com/gokatas/fetch.git
findgo     walking filesystems              52     5x    9 days ago   cmp filepath fs fstest         https://github.com/gokatas/findgo.git
shift      simple cipher                    54     2x    6 days ago   bytes testing                  https://github.com/gokatas/shift.git
lookup     loadbalanced STDIN processing    68     2x    7 days ago   bufio fmt net os strings sync  https://github.com/gokatas/lookup.git
lognb      non-blocking concurrent logging  106    1x    46 days ago  fmt os signal time             https://github.com/gokatas/lognb.git
google     building search engine           187    3x    48 days ago  fmt rand time                  https://github.com/gokatas/google.git
boring     concurrency patterns             190    6x    19 days ago  fmt rand time                  https://github.com/gokatas/boring.git

❯ git clone https://github.com/gokatas/bcounter.git
Cloning into 'bcounter'...
❯ cd bcounter
  1. Read the documentation and code and try to understand it. You can use ChatGPT to help you out.
❯  export OPENAI_API_KEY=...
❯ gokatas -explain bcounter
# Code Explanation:

The `Bcounter` type is implemented as a type that counts bytes before discarding them. It satisfies the `io.Writer` interface, allowing it to be passed to `fmt.Fprint`.

The `bcounter` type is defined as an integer type.

The `Write` method of the `bcounter` type takes a byte slice `p` as input, updates the counter by adding the length of the byte slice, and returns the length of the byte slice and a `nil` error.

In the `main` function, a variable `b` of type `bcounter` is declared. The `fmt.Fprint` function writes the string "hello" to `b`. Then, the `Write` method is called with the byte slice containing "world". Finally, the value of `b` is printed to the console.
  1. Delete (some of) the code and try to write it back. Check how are you doing.
git diff
  1. Track your progress to stay motivated.
gokatas -done bcounter

It’s important to practice regularly because repetition creates habits, and habits are what enable mastery. Set a goal that you are able to meet and insert it into your daily routines. Start by taking baby steps. After some time it will require much less will power to practice. Your programming moves will start looking simpler and smoother. 🥋