Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

[flagged]


I don't think you read the Interfaces section properly. Rob is not claiming go invented interfaces.

If you want to level such a charge that he is rewriting history, you need to take special care yourself in representing his views accurately.


I came away with the impression they were saying they'd invented interfaces, so I reread it:

> That idea was exciting for us, and the possibility that this could become a foundational programming construct was intoxicating.

Talking about interfaces as an idea that could become a foundational programming construct definitely sounds like they're saying they invented it.


go's version of interfaces is fairly unique, if you read that as them inventing interfaces you misread. If you read it as them having a unique twist on interfaces they felt was powerful, then you read it correctly.

It never even occurred to me that someone would suggest they're claiming to have invented interfaces, mostly because obviously they didn't.


I was careful to try read what was said; the language might be a bit loose because it's a transcript of a live talk. That said, the example they gave, and their motivating problem of the qsort API in C don't show anything about using nominal interfaces, and instead look like a normal use of interfaces, combined with language about being wowed of how powerful they could be.


The text is recreated below:

> It's clear that interfaces are, with concurrency, a distinguishing idea in Go. They are Go's answer to objected-oriented design, in the original, behavior-focused style, despite a continuing push by newcomers to make structs carry that load.

> Making interfaces dynamic, with no need to announce ahead of time which types implement them, bothered some early critics, and still irritates a few, but it's important to the style of programming that Go fostered. Much of the standard library is built upon their foundation, and broader subjects such as testing and managing dependencies rely heavily on their generous, "all are welcome" nature.

> I feel that interfaces are one of the best-designed things in Go.

> Other than a few early conversations about whether data should be included in their definition, they arrived fully formed on literally the first day of discussions.

> And there is a story to tell there.

> On that famous first day in Robert's and my office, we asked the question of what to do about polymorphism. Ken and I knew from C that qsort could serve as a difficult test case, so the three of us started to talk about how our embryonic language could implement a type-safe sort routine.

> Robert and I came up with the same idea pretty much simultaneously: using methods on types to provide the operations that sort needed. That notion quickly grew into the idea that value types had behaviors, defined as methods, and that sets of methods could provide interfaces that functions could operate on. Go's interfaces arose pretty much right away.

> That's something that is not often not acknowledged: Go's sort is implemented as a function that operates on an interface. This is not the style of object-oriented programming most people were familiar with, but it's a very powerful idea.

> That idea was exciting for us, and the possibility that this could become a foundational

> programming construct was intoxicating. When Russ joined, he soon pointed out how I/O would fit beautifully into this idea, and the library took place rapidly, based in large part on the three famous interfaces: empty, Writer, and Reader, holding an average of two thirds of a method each. Those tiny methods are idiomatic to Go, and ubiquitous.

> _THE WAY INTERFACES WORKED became not only a distinguishing feature of Go, they became the way we thought about libraries, and generality, and composition. It was heady stuff.

emphasis at the end there is mine.

how the hell _anyone_ reads that and comes away with the idea that they're claiming they invented the idea of interfaces is beyond me.

my only guess here is that many people are not familiar with the sort problem they're describing.

very famously, C++'s sort is more performant than C's sort because C uses a void pointer and C++ uses templates. The extra type information allows C++ to optimize the sort in a way that C cannot, so while C is generally more performant than C++ in a lot of ways, this is one particular area where C++ shines.

So it's no surprise that Rob Pike, et al, paid close attention to sort as something to improve over C and the way to do that is having more type information available (C++ very clearly has shown this).


> That's something that is not often not acknowledged: Go's sort is implemented as a function that operates on an interface. This is not the style of object-oriented programming most people were familiar with, but it's a very powerful idea.

I feel like most of this is just ignoring the prior art. C#'s sort works the same way. Admittedly, this isn't obvious because of the way it's implemented. But if you're a language designer you don't have much of an excuse there.


it would behoove you to quote the entire context

> Robert and I came up with the same idea pretty much simultaneously: using methods on types to provide the operations that sort needed. That notion quickly grew into the idea that value types had behaviors, defined as methods, and that sets of methods could provide interfaces that functions could operate on. Go's interfaces arose pretty much right away.

> That's something that is not often not acknowledged: Go's sort is implemented as a function that operates on an interface. This is not the style of object-oriented programming most people were familiar with, but it's a very powerful idea.

What he actually said is that being able to pass a value type into a sort function and have it work without needing to explicitly define and implement an interface was not a style that most people are familiar with.

and indeed, C# absolutely does NOT work that way.

It probably would have been better for you to claim that Ruby had prior art, but even that's implemented in an entirely different way it's just that the behavior is closer to Go's behavior than C# is.


In his defence, their interfaces do work somewhat differently to Java's, because they don't need to be explicitly implemented. I don't know if that matters enough to make them a novel invention, though.


> I don't know if that matters enough to make them a novel invention, though.

That's called structural typing, which is at least as old as OCaml, i.e. 25+ y.o.


Java's interfaces are nominal. What you're describing is called structural interfaces, and they exist in other languages like Scala.


Yes, they work the same way as Modula-3's did in 1988. Still not exactly innovation.


It sounded like it to me. I kept thinking didn't java have interfaces to prevent multiple inheritance? All go did was replace all inheritance with interfaces


Which I’m pretty sure CLU did first (honestly, I’m pretty sure nearly every good idea was in CLU first).


What other languages of comparable popularity do you know that had concurrency similar to Go's, and interfaces?

Actually, name just one that has either, even today!


Go's concurrency isn't even that good. It just looks good for anyone coming from the languages which don't have that (which are the majority).

One of the earliest high level languages with powerful concurrency and parallelism APIs are C# and F# (TPL and Parallel/PLINQ, some of which was available back in 2010).


Java has had interfaces for a _long_ time, and it definitely meets the popularity requirement.

EDIT: Since its 1.0 release in 1996


There's nothing similar about Java's and Go's interfaces, except the name.

Java interfaces must be implemented explicitly (they're nominal).

Go interfaces are automatically satisfied by any type that declares matching methods (similar to protocols in other languages) (they're structural).


They are certainly different, but to say there is nothing similar is plainly untrue - apart from nominal vs structural, they are pretty much the same.

I'm not sure how significant the nominal vs structural distinction even is. In Go, a struct can implement an interface without declaring it, but the programmer still needs to deliberately write the struct to conform to the definition of the interface, so they're still coupled, just not explicitly [1]. Yes, it is possible to define a new interface which fits existing structs which weren't designed for it - but how common is that? That is, how common is it for two or more structs to have a meaningful overlapping set of methods without being designed to conform to some pre-existing interface?

[1] which is obviously a bad thing


Go's nominal interface feature is definitely interesting, but that section doesn't talk about how amazing it was to implement interfaces implicitly:

> That notion quickly grew into the idea that value types had behaviors, defined as methods, and that sets of methods could provide interfaces that functions could operate on. Go's interfaces arose pretty much right away.

If you replace Go with Java, this would've accurately described Java ~30 years ago.


You missed this:

> Making interfaces dynamic, with no need to announce ahead of time which types implement them


Yeah, they managed to recreate the advantages and disadvantages of Modula-3's typing system within three decades. Groundbreaking.


Scala had it 2 years before golang, OCaml more than decade. https://en.wikipedia.org/wiki/Structural_type_system


So they're like python's Abstract Base Classes? (No idea which came first)


Fibers were implemented by Microsoft in Win32 API in 1996:

https://devblogs.microsoft.com/oldnewthing/20191011-00/?p=10...

As the review Chen links discusses, it turns out that M:N threading (i.e. goroutines) and good C compatibility are mutually exclusive. Go went one way, every other language went the other way. The most common alternative is stackless coroutines, which are much more widely implemented than the Go model.


That review is by Gor Nishanov: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p136... The most relevant quote:

> DO NOT USE FIBERS!


And COM interfaces. They could be clunky in C/C++ but Delphi implemented interfaces quite nicely[1] back in 1999[2].

And being for Windows, Delphi had full access to Win32 API.

[1]: https://docwiki.embarcadero.com/RADStudio/Sydney/en/Using_In...

[2]: https://en.wikipedia.org/wiki/History_of_Delphi_(software)#B...


Even stackless coroutines aren't very popular. No other popular language specification has them (except maybe Haskell/GHC, but it's not that popular).


JavaScript?


Elixir and Erlang have both, and Go's concurrency model is just a poor imitation of what you get from Erlang, that's been around since the 80's.


C#? It has channels and good concurrency stuff. I don’t know if it was as mature in 2007 when they did this work.

edit: Concurrency, not the language itself. That was mature.


C# not only has channels, it has async/await, which he concedes is the actually popular form of concurrency in that others have adopted it.


To the extent that Go has features that no other popular language has, it is not influential. To the extent to which it invented those things, it's not influential. And that's why he didn't make that claim, he made a much broader one. The only problem is, if you make the broader one, it's obvious it's F#/C# that's been influential.


Erlang


> of comparable popularity


It was more popular than go in 2009


Erlang's processes might have similar semantics to Go's goroutines (green threads) but Erlang is a much simpler language, because it doesn't have shared state.

A lot of work went into optimizing Go's GC to be able to cope with concurrency.


Erlang is not a popular language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: