Why I like Go’s interfaces

When I hear peo­ple talk about Go, a lot of the dis­cus­sions focus on its con­cur­ren­cy fea­tures. Whilst it has a good con­cur­ren­cy sto­ry, the lan­guage land­scape is cur­rent­ly filled with lan­guages that have an equal­ly good or bet­ter con­cur­ren­cy sto­ry — F#, Erlang, Elixir, Clo­jure, etc…

Per­son­al­ly, what I found real­ly inter­est­ing from my time with Go was how its inter­faces work. In short, inter­faces do not need to be explic­it­ly imple­ment­ed — i.e. no imple­ment key­word. Instead, inter­faces are sat­is­fied implic­it­ly.

 

Duck Typing

In dynam­ic lan­guages such as Python, you have the con­cept of Duck Typ­ing.

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

Sup­pose you have a say_quack  func­tion in Python which expects its argu­ment to have a quack  method. You can invoke the func­tion with any object so long it has the quack  method.

image

Duck typ­ing is con­ve­nient, but with­out a com­pil­er to catch your mis­takes you are trad­ing a lot of safe­ty for con­ve­nience.

trade_off_1

 

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

In F#, this can be achieved through sta­t­i­cal­ly resolved type para­me­ters:

image

But syn­tac­ti­cal­ly, sta­t­i­cal­ly resolved TP is kin­da clunky and not the eas­i­est to read. Go’s inter­faces rep­re­sent a more ele­gant solu­tion in my view.

 

Implicitly Implemented Interface

In Go, sup­pose you have an inter­face for a Duck:

image

Any struct that has a Quack  method will imple­ment the Duck  inter­face implic­it­ly and can be used as a Duck.

image

(try it your­self here)

If you have anoth­er struct, Dog, which doesn’t have a Quack  method and you tried to use it as a Duck  then you’ll get a com­pile time error:

image

(try it your­self here)

so there, the con­ve­nience of duck typ­ing with the safe­ty of sta­t­ic check­ing!

trade_off_2

 

Beyond Convenience

The design for Go’s inter­face stems from the obser­va­tion that pat­terns and abstrac­tions only become appar­ent after we’ve seen it a few times.

So rather than lock­ing us in with abstrac­tions at the start of a project when we’re at the point of our great­est igno­rance, we can define these abstrac­tions as and when they become appar­ent to us.

When you cre­ate a new inter­face, you don’t have to go back and tag every imple­men­ta­tion, which some­times might not be pos­si­ble if the imple­men­ta­tion is owned by a 3rd par­ty.

This makes Go inter­faces incred­i­bly cheap, and encour­ages you to cre­ate very gran­u­lar, pre­cise inter­face def­i­n­i­tions.

 

All and all, even though I don’t enjoy writ­ing code in Go (as you tend to write imper­a­tive style of code), I think there are some very inter­est­ing ideas and lessons to take from the lan­guage.

It’s also a very rel­e­vant lan­guage of our time, with some impor­tant prod­ucts (ahem, Dock­er) hav­ing been writ­ten in Go.

It’s a very small lan­guage still, and its web­site does a good job in help­ing you get start­ed. Take a tour of Go if you’re inter­est­ed in learn­ing more about the lan­guage.

 

Links