Leipzig Gophers

🔗Winter Drinkup #33 wrap-up

Drinkup Notes

We met 2022-12-20 19:00 at Café Cantona, with no specific Go agenda, for a great exchange of ideas and experiences - too many to capture them in a blog post, so here’s just a fraction of the topics we passed (slightly categorized):

Reading list

Software General

If you have wget (1.14 or later) installed, you can already create WARC files yourself:

$ wget -rkc --warc-file golangleipzig.space --warc-cdx https://golangleipzig.space

Since web archiving aims for a complete preservation, the whole HTTP exchange is recorded - which can be analyzed later. The HTTP Archive creates various reports, e.g. a yearly state of the web report.

There’s a new wave of big data and analytics tools written in rust, e.g. the distributed SQL query engine ballista (NY statprog meetup recording), and others


Quamina implements a data type that has APIs to create an instance and add multiple Patterns to it, and then query data objects called Events to discover which of the Patterns match the fields in the Event.

Gogu is a versatile, comprehensive, reusable and efficient concurrent-safe utility functions and data structures library taking advantage of the Go generics. It was inspired by other well established and consecrated frameworks like lodash or Apache Commons and some concepts being more closer to the functional programming paradigms.

A Go interface puzzle

Declare an interface where it is used, not where it is implemented. Unless the interface is well discovered.

Via: 1605116543553019905 – join the conversation

Our take: It’s a - slightly subtle - consequence of structural typing: An interface can be added later, in an ad-hoc style, e.g. to facilitate testing or to establish a protocol of limited scope.

Example: A function only uses client.Do for HTTP requests. We can create an ad-hoc interface, so we are able to use the default HTTP client from the standard library or some third-pary library as well (as long at it has a suitable Do method). We can define a Doer:

type Doer interface {
    Do(req *http.Request) (*http.Response, error)

and let our function work with this Doer interface instead of a concrete type. This interface should be defined where it is used (and not in the net/http package, for example). On the flipside, sometimes you need central interfaces, e.g. io.Reader, or a database abstraction layer, or a filesystem abstraction layer, and so on. These are well discovered.

In a structural setting, a type expression is a closed entity: it carries with it all the information that is needed to understand its meaning. In a nominal system, we are always working with respect to some global collection of type names and associated definitions. This tends to make both definitions and proofs more verbose.

More on nominal and structural typing can be found in Chapter 19.3 of Types and programming languages TAPL.


API Design

Related, from Cloud Native Go (a book we gave away in #30, courtesy of O’Reilly Media), page 168:

Holly Cummins, the worldwide development community practice lead for the IBM Garage, famously said that if cloud native has to be a synonym for anything, it would be idempotent.


Running Kubernetes with rootless podman is documented on both kind and minikube but to get it up and running on WSL2 requires some additional tweaks as by default WSL2 uses init daemon, instead of systemd and you have to enable cgroupv2 explicitly.


Happy holidays!