We've seen this same article re-written countless ways. Seriously, this is (intentionally or not) a rewording of every existing criticism of Go, by people who complain that it isn't a language that it isn't.
No, Go's solution to generics is not interface{}. The moment you say that, you have lost. You are trying to fight Go and make it a language that it is not.
Always remarkable that such critiques always focus on the utterly trivial, while absolutely ignoring things like concurrency or composing complex systems. As always, the color of the shed is what the laymen want to argue about.
But the fact that Go proponents don't actually have solutions to those problems is an issue.
How do you make a custom, generic data structure without syntax overhead? I have not seen any counter proposal to this aside from "maps should be enough for everybody".
How do you avoid the noise from not having operator overloading or a similar alternative? This, again, goes unadressed.
What are the succint alternatives to functional abstractions for quickly processing collections of data?
"Just use a channel" doesn't really ring like a reasonable alternative to these questions.
How do you make a custom, generic data structure without syntax overhead?
In real-world code, the need for generic data structures is shockingly uncommon. It really is. This requirement exaggeration comes about by people acting as language tourists, building amorphous code of uncertain purpose, where things like "I'm going to sum up a bunch of unknown objects" seems like a serious need.
For most people who find Go to be a compelling language, it excels for practical, real-world needs.
Notice how you're not giving an answer to Daishiman's question, merely downplaying the importance of having general data structures, though I'm sure you're quite happy that slices, maps and channels can be parametrized by the type of data they contain. Saying that general data structures are uncommon in the "real world" sounds like an example of Sapir-Whorf. I use Java at work and OCaml for a personal project and in both of them, having data structures that can be parametrized is very helpful. For instance, writing an AST with a type parameter allows to go from a AST<String> (generated by the parser) where ids are strings to a AST<Symbol> where a node's id is now a symbol (generated during semantic analysis).
You're not answering my question. I have a bunch of numeric code where I have dense matrices, sparse matrices, diagonal matrices, etc.
I have heterogenous priority queues where I want to push in JSON data and plain strings, I have custom iterators, concurrent data structures, default dictionaries, etc.
Seriously, look up Python's itertools and data structure modules and realize that there's a wealth of things that are useful and practical and, above all, reduce code size while preserving interface contracts and semantics. Go is completely unsatisfactory in this regard.
Haskell makes Go's concurrency and composition look primitive and restrictive while also giving you safer code with generics. This isn't an area that Go wins at unless you're comparing it with C, not anything modern. The lack of generics is also not a primitive issue, neither is the ease at which people can write unsafe code. You can write as unsafe code as you like in Haskell, but the pat5h of least resistance also happens to be the safest. this is my biggest issue with go; it insists on using unsafe ideas when it's simply not necessary and puts unnecessary burden on the programmer to ensure things are safe; computers exists to make lives easier, and Go ignores that
Smalltalk uses less code to do the same thing.
Smalltalk lets you offload bookkeeping to the runtime.
Smalltalk code often runs faster for actual business workloads.
Smalltalk lets you add features faster with fewer bugs.
Why Java? Because marketing.
But doing this is was a waste of community time and energy. A better thing to do is to build cool stuff.
> No, Go's solution to generics is not interface{}. The moment you say that, you have lost. You are trying to fight Go and make it a language that it is not.
There isn't one. Go, by design, does not provide generics as they would complicate the language and for insufficient benefit. (according to at least one of the authors)
While I do agree that Generics can open up a whole new dimension of programming concerns. I think they are worth the additional syntactic complexity, because they allow you absolute accuracy when it comes to types. If we as a programming community want to ever get to the point where we have provably correct programs, or even reasonably correct programs, clear definitions of functions for an exact set of types is a necessity.
And conversely if you don't care about types, you might as well use a dynamic language and get something concise and flexible. A static type system without generics is the worst of both worlds; it gets in your way a lot while still not providing guarantees of type safety.
Since concurrency and composition are important, why doesn't Go have support for immutable variables and monitoring/linking ? These are features proven to make it easier to reason about concurrent systems and to manage failures in a distributed system. From what I can tell it is completely impossible to implement supervisors in Go.
Immutable values will complicate a type system and implementation. The Go creators are very strict about adding features to the language without enough justification, which is one of the biggest features of the language imo.
There are more synchronization features than channels in Go. Channels and switches solve most problems very well. However when another synchronization method is just simply required, check out: http://golang.org/pkg/sync/
Refusing to complicate the language is nice, unless it means complicating or making every program in that language less safe.
Repeatedly, Go chooses the latter, and many people hail it while writing programs that crash on nil dereferences or duplicate their code for various basic types.
It is fine to say you want a simple language, but then please do not talk up how great it is at concurrency. It lacks basic features common to every other language with a good concurrency story.
Go is absolutely fantastic at pragmatic, practical concurrency. In most real-world cases, that does not include a strong immutability base, for instance.
Here's the thing about the "Go sucks because Haskell is the best language ever" retort: Haskell has been around for decades longer than Go. It has made essentially zero impact, and even for the case of many of those who use it as the "my big brother" comparison against Go, it isn't a viable part of their daily toolset.
It's a theoretical solution that just makes for a nice checklist comparison against Go. You know this is true. We all know this is true. And everyone goes back to Java or C# or whatever else is your daily driver.
Yet people are making Go their daily driver. Solutions are being built, en masse, in Go. People are having great degrees of success with Go.
Isn't that weird? Might it be that Go adds primitives in a way that makes them usable and intuitive, without becoming strictly theoretical?
So people can keep posting these "Haskell, which I don't actually use in any credible way, is way better" articles, but they simply miss the point. They really do.
Haskell is one example; Clojure, Rust, Erlang, Scala are mainly the ones we think about in this category but even in Modern C++ code const is used quite a lot. Go is not yet very widely known or popular outside the HN bubble; I think it is a bit early for "daily driver" argument.
> Always remarkable that such critiques always focus on the utterly trivial, while absolutely ignoring things like concurrency or composing complex systems.
But generics are a fundamental tool to solve concurrency or composition. How do you propose to compose complex systems when you can't abstract on the type?
How can you add new concurrency constructs that work safely for every type without generics?
Actually Go interfaces map pretty well to a concurrent (and likely networked environment). It's often straightforward to put a network-based implementation behind a Go interface type. When was the last time you saw a web service that is parameterised by a type?
No, Go's solution to generics is not interface{}. The moment you say that, you have lost. You are trying to fight Go and make it a language that it is not.
Always remarkable that such critiques always focus on the utterly trivial, while absolutely ignoring things like concurrency or composing complex systems. As always, the color of the shed is what the laymen want to argue about.