Why I like Go’s interfaces

When I hear people talk about Go, a lot of the discussions focus on its concurrency features. Whilst it has a good concurrency story, the language landscape is currently filled with languages that have an equally good or better concurrency story – F#, Erlang, Elixir, Clojure, etc…

Personally, what I found really interesting from my time with Go was how its interfaces work. In short, interfaces do not need to be explicitly implemented – i.e. no implement keyword. Instead, interfaces are satisfied implicitly.

 

Duck Typing

In dynamic languages such as Python, you have the concept of Duck Typing.

“if it looks like a duck and quacks like a duck, it’s a duck”

Suppose you have a say_quack  function in Python which expects its argument to have a quack  method. You can invoke the function with any object so long it has the quack  method.

image

Duck typing is convenient, but without a compiler to catch your mistakes you are trading a lot of safety for convenience.

trade_off_1

 

What if there’s a way to get the best of both worlds?

In F#, this can be achieved through statically resolved type parameters:

image

But syntactically, statically resolved TP is kinda clunky and not the easiest to read. Go’s interfaces represent a more elegant solution in my view.

 

Implicitly Implemented Interface

In Go, suppose you have an interface for a Duck:

image

Any struct that has a Quack  method will implement the Duck  interface implicitly and can be used as a Duck.

image

(try it yourself here)

If you have another struct, Dog, which doesn’t have a Quack  method and you tried to use it as a Duck  then you’ll get a compile time error:

image

(try it yourself here)

so there, the convenience of duck typing with the safety of static checking!

trade_off_2

 

Beyond Convenience

The design for Go’s interface stems from the observation that patterns and abstractions only become apparent after we’ve seen it a few times.

So rather than locking us in with abstractions at the start of a project when we’re at the point of our greatest ignorance, we can define these abstractions as and when they become apparent to us.

When you create a new interface, you don’t have to go back and tag every implementation, which sometimes might not be possible if the implementation is owned by a 3rd party.

This makes Go interfaces incredibly cheap, and encourages you to create very granular, precise interface definitions.

 

All and all, even though I don’t enjoy writing code in Go (as you tend to write imperative style of code), I think there are some very interesting ideas and lessons to take from the language.

It’s also a very relevant language of our time, with some important products (ahem, Docker) having been written in Go.

It’s a very small language still, and its website does a good job in helping you get started. Take a tour of Go if you’re interested in learning more about the language.

 

Links