bugramming

Simplicity is Contagious

· ashish shekar

I have been programming Go continuously for a long time, I only say “long time” for a thing when I start developing opinions about it, and I’m starting to develop very strong opinions about Go (the programming language).

Go is a very simple language but I think that many don’t understand the necessity of this simplicity in this programming world. The reason I’m writing this is because I miss some of the very simple things that Go provides us and we take it for granted.

Do note that I have been doing comparison with languages which are garbage collected and claims to be productive.

Explicit use of pointers

Despite being a garbage collected language (which generally aims for developer’s productivity by hiding intrinsics), the explicit mentioning of references gives us one more flexibility to make some variables as pointers, which in turn can save memory. It is not remembering which types are “pass by value” and which are “pass-by-reference”, it is just us saying to the compiler that I want this to be a reference with * prefix operator.

Zero values

I do have some concerns on zero values used in configuration space, but it does make code look lot cleaner when used it properly. Although the concept of zero values is quite simple, where built-in types are initialized with their default values:

  • int = 0
  • float = 0.0
  • bool = false
  • string = ""
  • pointer = nil

we might make use of this to write some really neat code.

func GetPizza(userId int) (p *Pizza, err error) {
    if p, err = DB.GetFavoritePizzaForUser(userId); err != nil {
        return
    }

    if p.HasPinapples() {
        p.Tags = append(p.Tags, "pinapple lover")
    }
    return
}

Testing in stdlib

It is my personal opinion that providing good defaults for a built-in testing framework is hard. I have seen most of the programming languages not touch the testing part and leaving it to the community to provide a good testing framework. I think this makes the community more fragmented and not easy to agree on a single approach. I don’t want it to sound like it is a bad thing, as it presents us with some creative solutions, but at the same time it makes co-ordination with other libraries hard. Here is one of the code I have implemented which made me realize the power of built-in test implementation.

func TestNewUserBehaviour(t *testing.T) {
    // create a new wrapped testing context `mtest.T`
    mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
    deps := Dependencies{MongoClient: mt.Client}
    if err := PayCash(deps); err != nil {
        mt.FailNow()
    }
}

The mtest.T implements testing.T which gives mtest the ability to also have a control on our test runner and fail if any improper arguments or access is found.

Communicating Sequential Processes

I recommend everyone to give a quick read at the original CSP paper where the basic crux of a synchronization primirive is explained. Now Go’s design of channels tells us that instead of using locks to communicate data to a different thread we use channels to send references of data to the other goroutines via channels.

Let’s describe this pattern in a simple textual flow. The CSP style of programming defines data as Inputs and Outputs.

Input (i1) -> P1 -> Output (o1)
Input (o1) => P2 -> Output (o2)

Here P1, P2 are processes and i1 is the initial Input and o1, o2 are Outputs from the processes respectively. Here the first line is straightforward, we generate Output o1 but this becomes Input to process P1 and is sent by a channel (as this => symbol indicates channel). So P1 hands over the output o1 through a guarded channel and P2 is the sole owner of data o1.

I recommend reading this blog from Andrew Gerrand which swiftly explains the infamous phrase Share Memory By Communicating in Go.

Conclusion on thoughts

Although Rust has done some major strides with lifetime based memory management, I think that Go has steered the programming community with it’s focus on simplicity and raised the bar of providing developer best default tools. Now I expect every language to have atleast if not better tooling.

I’m sorry for all the new people who are learning this language by watching videos and calling this language ‘Golang’.