Hacker News new | ask | show | jobs
by tshadwell 3745 days ago
All understood, and you're right, but the tone of this article and that of its kin is at least equally bad at idea discussion -- it's not weighing out positives and negatives or trying to get an idea of why things are how they are, it's just angry that it can't do the thing it wants to do, and it wants you, and everyone else to know.

I'm saddened that you feel like the Go community doesn't answer these questions, and I'd love to write an article on why these things are how they are and how they can be useful, but that's beyond the scope of a HN comment.

Yes, I disagree with the author of the article, but the primary thing I intend to satirise is his angry tone. If you've felt that the Go community has been condescending, I hope the condescending articles get equally as many critics.

2 comments

The Go community seems to throw "you're using the language wrong, do it like this..." or "copying code is the way to go" or "those things you use in other languages shouldn't be used in ours." or "I have never needed to use that in my code"

There has never been an argument on how concepts like .map, .reduce, .filter, functors, promises, futures are inferior to what Go programmers currently use. Things like simplicity are thrown around but calling these proven abstractions "complex" is wrong. That's why they're useful fundamental abstractions -- because they make code simpler and reusable.

Generics have been around for a very long time. They have been studied in-depth in academia and industry. They're universally accepted but in Go.

Generics need not be like C++ templates. There are simpler implementations of generics. They are a solution to a real problem, specifically in libraries and creating type-safe abstractions. If you don't want type-safety, then why are you using a language with static types?

- Code copying is a workaround, not a solution. - Code generators outside the compiler is a workaround, not a solution. You're essentially transpiling a language that is no longer Go into Go because of Go's lack of support for such things. - interface{} is a workaround, not a solution. It automatically shows that Go cannot express a generic variant safely. - reflections is a workaround, not a solution. See previous point.

If the Go community is happy with these workarounds than that's cool, but be honest that's it's a workaround, a stop-gap to the lacking of Go's type system.

I think they are not workarounds so much as compromises made with a deference to the language as a whole, which fall at a different optimization point than what a lot of programmers are used to. Succinctly, features in Go are chosen so that they compose well with (i.e. are orthogonal to) all other features. The bar for new features is thus very high. They must be backwards compatible, and they must interact cleanly with the language as it exists. To focus on any individual missing feature in Go as evidence of anything is to miss the point. Quite literally to miss the forest for the trees.

That said, I think the authors and the community learned a lot since 2009. I think a Go 2, correcting the mistakes of the initial implementation, and adding important missing features like parameterized types and native functional transforms, would be very compelling. But to do it without sacrificing any of the other good things about Go, like the compilation speed, or the easily parseable source, or the concurrency story, or interfaces... well, I'd love to see the (concrete, specific) proposal, because I don't know if it's feasible.

I think the mistakes Go authors recognize and Go critics talk about have very little overlap. So I won't be surprised if none of those complains get addressed. Especially since those problems can simply disappear by moving to numerous better languages available to all.
There has never been an argument on how concepts like .map, .reduce, .filter, functors, promises, futures are inferior to what Go programmers currently use.

With regard to futures and promises, I find the article What color is your function [http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...] very convincing with regards to their problems. The article touches on part of why Go's concurrency model is superior, but for an even more compelling argument, you should watch Rich Hickey's talk[http://www.infoq.com/presentations/clojure-core-async] about core.async which is Clojure's library implementation of CSP[https://en.m.wikipedia.org/wiki/Communicating_sequential_pro...], which is the concurrency model which Go has language level support for. The argument briefly is that CSP allows for concurrent code that reads sequentially and is therefore easier to reason about.

I don't think there's the same feeling of "community" with Go as with other languages, in the same way that there's not really a C community - more a bunch of authors, evangelists and contributors who have a "stake" in the language. That's sort of the point, though. Go doesn't really need much more than it has already. It's a deliberately simple language, with standard format and documentation, a plethora of examples and a comprehensive stdlib. It was designed to serve particular purposes, and it does what it does really well. All it really needs in the way of community is a bugtracker and a StackOverflow section, and I suspect that the a lot of the "Go community are arrogant/negative/dismissive" type complaints can just be attributed to it being the same few people hearing the same complaints about lack of My Favourite Feature X over and over, despite the many blog posts, release notes and list discussions explaining why it's not there.
> but be honest

You've elaborated on the benefits. What do you think the costs of generics are?

As long as we're talking about purely generics with no introduction to type classes, the obvious ones people point out:

- More compiler complexity - Compilation speeds might be effected - Without type inference, type signatures could be a pain point - Basic type parameters are not able to express all intents. Until you implement more complex like higher-kinded types.

Go's compiler already works with generics, although it might be built in an ad-hoc way. Either way, the complexity is seemingly already in the compiler.

Before saying "Compilation speeds might be effected", we should probably get some numbers to back that up. So I don't buy this cost right now.

The third reason is very valid as Go doesn't have type inference. You probably won't get Java's verbosity with signatures but you'll be specifying type information in a few places, at least.

> Either way, the complexity is seemingly already in the compiler.

I do not agree with dismissing this complexity on the hunch that the complexity is already in the compiler. Implementing generics for a few select types/functions is a completely different story than real useful generics in the hands of a user.

Consider, for example, how much larger the language specification would be. I think you've neglected this cost.

I also find your dismissal of type classes to be curious. I wonder how useful, for example, parametric polymorphism would be without some constraint based polymorphism, even neglecting higher-kinded polymorphism. I suppose ML might fall into this category at first glance, but its module system makes up for its limited parametric polymorphism in many ways.

> Before saying "Compilation speeds might be effected", we should probably get some numbers to back that up. So I don't buy this cost right now.

I think there's a mountain of real evidence that generics impacts compilation speeds, assuming monomorphization as an implementation strategy. Exactly how much isn't clear. There is a comparatively smaller amount of evidence that suggests compilation can still compete with Go's compilation speed. (I'm thinking of D's compiler, although I've never seen any rigorous benchmarking.)

My suggestion to you is: instead of being so quick to imply those that disagree with you are dishonest, perhaps you might consider that there are indeed trade offs involved with more sophisticated forms of polymorphism that Go doesn't support, and therefore, the costs may not necessarily be worth the benefits. Not only is this a valid and honest position, but it's a reasonable position. Abstractions aren't always free, and too many of them can become quite costly.

I think you are right. And I feel like if I'd read something like this about any other platform I'd feel the same as you.

However, when I think about it, If I was moved enough to write something about the pain points of Go I would probably do it like the author did here. Not because I think the tone is correct in general but because I've seen that constructive criticism got thrown out by the Go community (I mean the people in decision making, not the entirety of users) over and over. I'd just be following their lead on the tone.

Also, this article does not have the same tone as the infamous PHP article (https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/) as in mocking it. It feels more like someone passionate about Go getting angry because they can't use it in it's full potential. It's good to have people like that.

Not the best way to do it though. You are right. But as I said, this has been the way Go people have been treating criticism.