The conclusion is pretty weird to me.<p>Go <i>does</i> rely on monomorphization for generics, just like C++ and Rust. The only difference is that this is an implementation detail, so Go can group multiple monomorphizations without worrying about anything else [1]. This form of hybrid monomorphization is being increasingly common, GHC does that and Rust is also trying to do so [2], so nothing special for Go here.<p>On the other hand, explaining variance as a lifted polymorphism is---while not incorrect per se---also weird in part because a lack of variance is at worst just an annoyance. You can always make an adapter to unify heterogeneous types. Rust calls it `Box<dyn Trait>`, Go happens to call it an interface type instead. Both languages even do not allow heterogeneous <i>concrete</i> (or runtime) types in a single slice! So variance has no use in both languages because no concrete types are eligible for variance anyway.<p>I think the conclusion got weird because the term "subtyping" is being misused. Subtyping, in the broadest sense, is just a non-trivial type relation. Many languages thus have a <i>multiple</i> notion of subtyping, often (almost) identical to each other but sometimes not. Go in particular has a lot of them, and even some relation like "T implements U" is a straightforward record subtyping. So subtyping is indeed a red herring here. Given this, it is no surprise that the non-uniform value representation has the largest influence, and only monomorphization schemes and hetero-to-homogeneous adapters vary in this particular group.<p>[1] <a href="https://github.com/golang/proposal/blob/master/design/generics-implementation-dictionaries-go1.18.md">https://github.com/golang/proposal/blob/master/design/generi...</a><p>[2] <a href="https://rust-lang.github.io/compiler-team/working-groups/polymorphization/" rel="nofollow noreferrer">https://rust-lang.github.io/compiler-team/working-groups/pol...</a>
In my opinion the interface system in Go is largely redundant, because interfaces are mostly equivalent to… structs of function pointers. And the single function interface case is just equivalent to a single function pointer.<p>If Go had a slightly better syntax for that, a lot of the interface use cases could be largely simplified. The interface implementation as subtype could be replaced with explicit instantiation using an “extends” keyword, plus sum types, and it would have been a simpler approach.
The statement "An interface type A is assignable to interface type B if A’s methods are a subset of B’s." is wrong. It is not in the current language specification of Go. The author misunderstood the term type set from the Go language specification. The type set of an interface is the set of types implementing the interface and not the set of methods of an interface. If you use the right meaning of type set, the subset makes sense again.
The "Variance of slice types" paragraph is confusing as hell. The type Tree implements interface Barker, after all. To me it looks like this is more about what I call "accidental implementation" (which is one of the many reasons why I don't like Go).
Can somebody please explain what I'm missing?
> <i>When that happens, all of the types the type checker poked at have cracked out of their chrysalides and emerged as beautiful runtime value butterflies flitting around in memory.</i><p>This sentence will forever change how I feel when debugging running programs.
It is amazing what length people are willing to go in the hope of "safety".<p>Is there anybody out there who successfully build their <i>own</i> product, not via VC or other investments, but on their <i>own</i> time and <i>own</i> money who likes types?<p>To me it seems that types are something consultants and people who get paid for their <i>time</i> instead of their productivity like. Because it makes things more complex. So to achieve the same task, you can bill more time.<p>I have not seen anybody successfully build something on their own time, money, risk who like types. If there is someone here, I would love to see it!<p>On the other hand, I have seen many examples of lean code like the following turning into successful life style businesses and companies:<p><a href="https://gist.github.com/nikcub/3833406" rel="nofollow noreferrer">https://gist.github.com/nikcub/3833406</a>
go doesn't have inheritance it just has composition, where you write the name of a parent class inside a child class, and get all its fields and methods<p>but you don't <i>inherit</i> them, and unlike <i>some</i> languages you type the parent's name inside the class rather than in the typedecl<p>generics? we won't need them. okay yes maybe not having generics will lead to an outcome where it is impossible to publish reusable code for sorting and lists, but surely if we <i>gave</i> people generics they would simply abuse them and live in filth<p>there should be a name for the type of language designer who thinks you can give people generics without ruining the package ecosystem<p>it is Good and Right that most lines of code are `if x, err := thing(); err { return err }`. from a language design perspective, manually plumbing errors around prevents Pollution of the package ecosystem. we can Lint the % of tokens that are `err` and if the % is low that is a bad language to which ours is superior