Origin of Go's interface design

840 views
Skip to first unread message

michae...@gmail.com

unread,
Oct 11, 2015, 8:38:40 AM10/11/15
to golang-nuts
Could anyone tell where the idea of Go's interface design originates form (or where this design was used first)? 
In particular the idea that any object conforming the interface is assignable to a variable of the interface type.

Henrik Johansson

unread,
Oct 11, 2015, 8:56:32 AM10/11/15
to michae...@gmail.com, golang-nuts
I believe it originates with https://en.wikipedia.org/wiki/Duck_typing

sön 11 okt. 2015 kl 14:38 skrev <michae...@gmail.com>:
Could anyone tell where the idea of Go's interface design originates form (or where this design was used first)? 
In particular the idea that any object conforming the interface is assignable to a variable of the interface type.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jan Mercl

unread,
Oct 11, 2015, 10:13:04 AM10/11/15
to golang-nuts
On Sun, Oct 11, 2015 at 2:56 PM Henrik Johansson <dahan...@gmail.com> wrote:

> I believe it originates with https://en.wikipedia.org/wiki/Duck_typing

IMO it's not really related to duck typing. I'd say tagged union[0] is a much closer concept.

  [0] https://en.wikipedia.org/wiki/Tagged_union

--

-j

Henrik Johansson

unread,
Oct 11, 2015, 10:31:36 AM10/11/15
to Jan Mercl, golang-nuts

But it sure feels like duck typing when coding.


--

Kevin Malachowski

unread,
Oct 11, 2015, 1:36:08 PM10/11/15
to golang-nuts
When I was learning Go I saw it as a less restricted form of Java's interface: rather than needing to explicitly mention a class implements an interface, in Go a type implements an interface automatically (as long as it has the appropriate methods).

Brad Fitzpatrick

unread,
Oct 11, 2015, 2:08:55 PM10/11/15
to Henrik Johansson, Jan Mercl, golang-nuts

peterGo

unread,
Oct 11, 2015, 2:18:57 PM10/11/15
to golang-nuts, michae...@gmail.com
Henrik,


"I believe it originates with https://en.wikipedia.org/wiki/Duck_typing"

However, if you read the Wikipedia article on duck typing:

Duck typing

https://en.wikipedia.org/wiki/Duck_typing

Structural type systems

https://en.wikipedia.org/wiki/Duck_typing#Structural_type_systems

Duck typing is similar to, but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time.

The OCaml, Scala, and Go languages use structural type systems.

Structural type system

https://en.wikipedia.org/wiki/Structural_type_system

Peter

Ian Lance Taylor

unread,
Oct 11, 2015, 2:56:40 PM10/11/15
to michae...@gmail.com, golang-nuts
The idea that any object that implements an interface can be assigned
to a variable of the interface type is a form of structural typing.
This idea can be found in other languages like OCaml or Scala, where
you can write a function that applies to any value that supports some
set of methods. These form of structural typing can be fully checked
at compile time.

Go of course also permits independent variables--not just function
parameters--to have interface type. This in turns permits dynamic
type assertions from values of one interface type to another. These
dynamic type assertions can not be checked at compile time, except by
a whole-program compiler. This idea can be found, at least in the
more limited form of querying whether a value supports a specific
method, in various dynamic programming languages, such as PHP.

I'm not aware of any other language that combines the various features
of Go interfaces. This doesn't mean there aren't any such languages,
just that I'm not aware of any.

ian

adon...@google.com

unread,
Oct 11, 2015, 6:44:22 PM10/11/15
to golang-nuts, michae...@gmail.com
On Sunday, 11 October 2015 14:56:40 UTC-4, Ian Lance Taylor wrote:
I'm not aware of any other language that combines the various features
of Go interfaces.  This doesn't mean there aren't any such languages,
just that I'm not aware of any.


There are two little languages that have similar interface systems to Go's.  One of them, School [1] by Roberto Ierusalimschy (the designer of Lua), was known to Robert Griesemer before he started work on Go. School interfaces were an attempt to give types to the "object protocols" of SmallTalk without specifying implementation.  The other language is Emerald [2], which was not known by the team until later.  It has a very similar method dispatch mechanism to Go.



[1] Noemi de la Rocque Rodriguez, Roberto Ierusalimschy, and José Lucas Rangel. 1993. Types in school. SIGPLAN Not. 28, 8 (August 1993), 81-89. DOI=http://dx.doi.org/10.1145/163114.163125

[2] Andrew P. Black, Norman C. Hutchinson, Eric Jul, and Henry M. Levy. 2007. The development of the Emerald programming language. In Proceedings of the third ACM SIGPLAN conference on History of programming languages (HOPL III). ACM, New York, NY, USA, 11-1-11-51. DOI=http://dx.doi.org/10.1145/1238844.1238855

Rob Pike

unread,
Oct 11, 2015, 8:47:23 PM10/11/15
to Alan Donovan, golang-nuts, michae...@gmail.com
Go's interfaces were designed to solve particular problems. I was unaware of other languages that worked this way and I believe Ken was too. If Robert knew about School, I do not remember him mentioning it at the time, and had he done so perhaps it would have saved us some trouble. In the event the design took quite a while to develop - it was arrived at in a series of steps.

Remember, we weren't trying to design a research language, we were trying to solve a number of problems in our programming environment. The way Go's interfaces developed was entirely about solving problems we encountered, including historical ones, immediate ones, and  hypothetical ones.

Go is not the product of a Whiggish development process. We were just trying to get something that worked for us.

-rob


--

Henrik Johansson

unread,
Oct 12, 2015, 2:39:51 AM10/12/15
to Rob Pike, Alan Donovan, golang-nuts, michae...@gmail.com
Aside from the occasional "I have to assert that these things satisfy this interface" case I think how Go's interfaces work is really nice and one very underrated feature. It really does get out of the way while allowing you to reason contractually. Neat.

Manlio Perillo

unread,
Oct 13, 2015, 5:53:31 AM10/13/15
to golang-nuts, michae...@gmail.com


Il giorno domenica 11 ottobre 2015 20:56:40 UTC+2, Ian Lance Taylor ha scritto:
On Sun, Oct 11, 2015 at 5:38 AM,  <michae...@gmail.com> wrote:
> Could anyone tell where the idea of Go's interface design originates form
> (or where this design was used first)?
> In particular the idea that any object conforming the interface is
> assignable to a variable of the interface type.

The idea that any object that implements an interface can be assigned
to a variable of the interface type is a form of structural typing.
This idea can be found in other languages like OCaml or Scala, where
you can write a function that applies to any value that supports some
set of methods.  These form of structural typing can be fully checked
at compile time.

Elm also support structural typing with fields:


> [...]


Regards  Manlio 

Jesper Louis Andersen

unread,
Oct 13, 2015, 6:55:05 AM10/13/15
to Rob Pike, Alan Donovan, golang-nuts, michae...@gmail.com

On Mon, Oct 12, 2015 at 2:46 AM, Rob Pike <r...@golang.org> wrote:
Go's interfaces were designed to solve particular problems. I was unaware of other languages that worked this way and I believe Ken was too.


The 'O' in OCaml is prior art (Doligez, I believe, from around 1995), as this is a structural subtyping system which yields many of the same properties as the Go interface subsystem. Of course, there are details which differ because language features interact with each other in complex ways. If you want to search for earlier prior art, I would wager Luca Cardelli is a good place to start.

(Aside:) It isn't a sum-type (or tagged union) because interfaces are "open" in the sense you can add another type to them later on in the program. In a standard sum-type (as found in Haskell/OCaml) the type is "closed" in the sense that once defined, it stays that way. There is a problem in those languages, called the "expression problem" which is about finding ways to augment such closed structures al'a carte as you would in interfaces, but keep the language fully type safe at the same time. (End of Aside)

In my experience, the Object-oriented features in OCaml sees fairly little use by many of its programmers. People prefer using the more functional aspects of OCaml, notably sum-types and polyvariant records, the latter of which gives something like an 'open' sum-type.

--
J.

Jan Mercl

unread,
Oct 13, 2015, 6:59:09 AM10/13/15
to golang-nuts
On Tue, Oct 13, 2015 at 12:54 PM Jesper Louis Andersen <jesper.lou...@gmail.com> wrote:

> (Aside:) It isn't a sum-type (or tagged union) because interfaces are "open" in the sense you can add another type to them later on in the program. In a standard sum-type (as found in Haskell/OCaml) the type is "closed" in the sense that once defined, it stays that way. There is a problem in those languages, called the "expression problem" which is about finding ways to augment such closed structures al'a carte as you would in interfaces, but keep the language fully type safe at the same time. (End of Aside)

When I said I see Go interfaces as tagged unions, I was thinking about the implementation, not about the semantics. Sorry for the noise by not being clear enough.
--

-j

Jesper Louis Andersen

unread,
Oct 13, 2015, 7:43:36 AM10/13/15
to Jan Mercl, golang-nuts

On Tue, Oct 13, 2015 at 12:58 PM, Jan Mercl <0xj...@gmail.com> wrote:
When I said I see Go interfaces as tagged unions, I was thinking about the implementation, not about the semantics.

It is quite different. According to the document by Russ Cox, http://research.swtch.com/interfaces , an interface is two pointers: one to the concrete data structre, one to the itable of methods associated with that interface.

The usual way to implement a tagged union is to use "tag" bits in the garbage collection header word as numbers. So

type foo = A of int | B of string

will assign 0 to A and 1 to B in the tag part of the header word. Usually there are representation tricks such that stuff like

type 'a option = None | Some 'a

essentially represents the "None" as a null. An example is OCaml: https://realworldocaml.org/v1/en/html/memory-representation-of-values.html .. but other languages use other representation schemes, of course.

The distinct difference is that a tagged union needs no method table, since there is no way to bind a method to a value in sum-types. And since the representation is "closed" you can just define a mapping from a variant name to an integer. Once you execute the code at the machine code level, every type is erased anyway. Note that if I define

type bar = C of float | D of bool

then C and D also use 0 and 1 respectively. The type system keeps types 'foo' and 'bar' distinct, so I can reuse the tag numbers for those two. Hence, the compiler guarantees there can be no overlap and thus, the reuse is fine.

--
J.

Jan Mercl

unread,
Oct 13, 2015, 8:20:11 AM10/13/15
to golang-nuts
On Tue, Oct 13, 2015 at 1:43 PM Jesper Louis Andersen <jesper.lou...@gmail.com> wrote:

The early ifaces looked cca like this:

struct iface {
        vtab *tag; // NULL -> iface is nil.
        union {
                void *ptr;          // Pointer types and pointers to types with size > sizeof (long int)
                long int scalar; // any type with size <= sizeof (long int)
        }
};

A tag in a tagged union can be seen as just a number identifying what's in the payload, if anything. A pointer (to vtab) is also just such a number. Therefore tagged unions can be tagged by vtab pointers and can have methods attached.

Old school pseudo version:

type 
        iface = record
                case tag: ^vtab of 
                        nil:          nothing;
                        intVTab: integer; // Note: intVTab has no methods.
                        ...
                        ioReaderImplVTab: ^ioReaderImpl;
                        ioWriterImplVTab:    ^ioWriterImpl;
                        ...
        end;

--

-j

atd...@gmail.com

unread,
Oct 13, 2015, 10:39:38 AM10/13/15
to golang-nuts
Another interesting way to see them is as a union type.
And then embedding as a way to get intersection types.

To be honest, I don't see much difference between sum types and union types. Just as I see quite a correspondence between intersection types and product types.
This is just a matter of extensionality vs. intensionality.
Reply all
Reply to author
Forward
0 new messages