Go 2016 Survey Results
blog.golang.org
blog.golang.org
Life became less ambiguous
The types also make it hard to change one small thing and make everything go wrong. Sure, the standard library source looks like a trainwreck, but it has structural strength. And it's easy to use.
Hmm. That's some great results, but is that survey representative of Go users as a whole? The respondents are self-selected, right?
I can imagine such a survey is reliable for things like best/worst features, how the language is used and other things that probably aren't correlated with enthusiasm for the language. Simply asking people who already chose to do a survey whether they like the language or not seems kind of pointless: if they didn't they'd presumably not bother spending time to say they didn't.
It is however illuminating how many of Go's developers are attracted by simplicity. The top adjectives for "like most" are: simplicity, easy, concurrency, simple, fast.
So that's 3 of the top 5 things people name basically being "it is simple".
On the other hand, the top "improve the most" adjective is generics.
This appears to put Go in a somewhat awkward spot. There's clearly a large population of developers who have been left behind by static typing and its consequent complexity (generics in particular being a fertile source of confusing error messages in most languages), and Go caters to these people, hence its attraction to former dynamic language users.
But at the same time, people are saying they want more complexity in the form of generics. If Go were to add good generics would it really be any simpler than Java? I'd struggle to identify any major complexity gap between them after that, unless you consider OOP to be too complex (unlikely given the Python/JavaScript backgrounds of many Go users?).
I wonder if it's the same people giving the top answers. Are Go users split into those who are happy with its current level of complexity and others who chafe against it? If so, is it possible for them to satisfy both camps simultaneously?
and:
>What changes would improve Go most? (first: Generics)
Number one issue mentioned.
So much for all those insisting that Go users have no issues with the missing Generics and don't miss/need them in practice.
There are just the N ways PL research has found for implementing generics. Either they implement them, and tackle the complication one of those N ways entails, or they don't.
Besides, has anyone seen much experiments, with actual coding or at least design, for finding this "non-complicated" way anyway? Not just some post once in a blue moon re-iterating the basic well known tradeoffs.
Proposal from Ian Lance Taylor, Go developer at Google
https://github.com/golang/proposal/blob/master/design/15292-...
View of Russ Cox, Go developer at Google
Ian's just reiterates the various options (Rob Pike has already written similar things), and Russ Cox is just several vague ideas for future additions to the language.
As for going further, I think covariance and contravariance, while conceptually simple, will always be too complicated to wrap your head around.
I think the future is invariant types + advanced generics functions. But research hasn't explored that direction yet. I might want to do that in the future.
If it's relevant to anyone's interest, feel free to contact me.
So much for all those who claim generics remain overwhelming concern for Go developers.
I mean, parametric polymorphism is achievable with different approaches...
In Go, you don't have subclassing, so you cannot implement YourClass<T extends SomeAncestor>.
There is no opposition between ADT and generics. In fact most language that have ADT have generics…
> In Go, you don't have subclassing, so you cannot implement YourClass<T extends SomeAncestor>.
There is no link between generics and inheritence, functionnal languages usually don't have OOP mechanism but they still have generics.
if err != nil {
return nil, err
}
blocks. But it would most definitely be a pain in the ass to integrate this with the toolchain.Not really, since you can always just use interface{} for everything and get all the dynamism back.
Generics is when you want to have both (dynamism and safety).
There are, of course, some users, that can make substantial comments about design, but they cannot be represented in a survey.
Other similar answers:
2% easy to learn, 2% simple syntax, 2% simple language, 1% easy to use, 1% easy to write, 1% ease of use
In the case of generics there's another 1% answer on generic
[1] yes, I'm a C++ programmer
If you are a C++ programmer then you know that the latest features that were added aim at making C++ programming simpler and easier. Adding something to a language to fix its flaws is not necessarily adding some complexity.
Go is designed to be a much simpler tool, with the spirit that constraints are liberating.
A simple macro system would maybe fit better the second philosophy than a significantly more complex type system.
In any case, I agree with you, but given the Go's culture I guess that is the closer we will ever get to compile time code generation.
How would Generics restrict you any more than the numerous variations on the same functions for different types (that you need today)?
Except if the alternative is using interface{} for everything, in which case, yes, Generics would be more restrictive.
(Honest question ... I'm interested to hear what you have in mind.)
If you keep dynamic dispatch, you pay almost no compilation penalty.
So I applaud the Go architects with being conservative about it. More languages should take their time thinking about implementing features, no matter how needed they seem to be initially. You only get one chance, and then if it's a bad choice you live with the consequences.
[0] http://www.jprl.com/Blog/archive/development/2007/Aug-31.htm...
* JVM
* Haskell runtime
* ML family of languages
* Modula-3
* Ada
The problem with specialized generics in the runtime is that they bake the type system of the language into the runtime itself, making the runtime more difficult to work with. Type erasure, for instance, makes it much easier to implement alternative languages on the JVM such as JRuby, Clojure, Scala, or Kotlin, than on .NET.
As another example, C# in 4.0 added the concept of generic type variance, which is completely at odds with specialized generics. To implement this feature, the C# language designers had to modify the underlying runtime itself and add special bytecode instructions for the feature. The feature itself is also incompatible with specialized generics, so when you use it you silently lose specialization. In contrast, thanks to type erasure, the Scala language designers could easily add the same feature on top of the JVM as-is without needing Oracle to add special bytecode instructions.
Specialization has advantages for performance when doing number crunching with data structures and algorithms operating directly on integral or floating point data types. At the end of the day, though, if you really need performance for this very narrow field of use cases, you're probably not going to be using generic data structures and algorithms anyways. It takes an incredible amount of effort to build a data structure or algorithm that is both generic and also performant in all possible usage scenarios. It is however, much easier to build a data structure or algorithm that is specific and performant relative to your use case alone.
Case in point: when I was in college doing a NLP assignment that needed to be fast, my data structures were arrays of doubles because that was the easiest way to reason about and ensure performance.
As a C++ programmer I would mention templates as something similar.
> The problem with specialized generics in the runtime is that they bake the type system of the language into the runtime itself, making the runtime more difficult to work with.
When inheritance comes in to play Java ends up storing generic type information in the child classes. It even has to generate bridge methods since Runtime does not really deal with int compareTo( Comparable<? extends T> ) vs. int compareTo ( MyInteger ) .
> if you really need performance for this very narrow field of use cases, you're probably not going to be using generic data structures and algorithms anyways
An ArrayList<Integer> makes sense in very few cases and is extremely slow, 64 bit pointers to objects that contain useless metadata and a immutable 32 bit int. Sadly an IntList is neither generic nor is it compatible with anything that operates on List<T>s, which results in duplication of a lot of algorithms just to sort primitives.
> when I was in college doing a NLP assignment that needed to be fast, my data structures were arrays of doubles because that was the easiest way to reason about and ensure performance.
Case in point: In C++ std::vector<double> and the standard algorithm header take care of most of that. If there is some specialized implementation of some algorithm for double values then you can still use that without copy pasting the implementation of everything else.
At runtime any Java List is a list of Objects, you cannot distinguish an ArrayList<Integer> from an ArrayList<Double> both are a raw ArrayList. What runtime support do they have?
> I feel bad for the C++ linkers that have to sift through all the template bloat to dedupe them :(.
If you have a template used often enough you can declare it extern and force instanciation in a specific cpp file.
You're right though that saying templates are different from generics is based on opinion, not fact. There's no widely-accepted definition of both that would separate them as distinct from one another.
And this is the first time I've heard that the JVM is easier to target for non-Java languages. .NET has had multi-language support an official design goal, the JVM is just for Java. Even simple stuff like pointers, so you can do ref/out parameters. Or unverified instructions. The CLR is simply more all-around capable.
I am pretty sure the CLR always supported variance, it was just unused up until C# 4.0. AFAIK, there haven't been any changes to the runtime bytecode since CLR 2.0, when generics were added.
The performance benefits of specialization are pretty nifty. The Mono guys ported Android to C# and got quite the performance improvement on some code: https://blog.xamarin.com/android-in-c-sharp/ - so that's existing code that got a perf benefit "for free" due to not using type erasure.
Edit: A quick skim of the specialization proposal for Java[1] makes no mention of other languages. Just the general pain of integrating it in a compatible way.
1: http://cr.openjdk.java.net/~briangoetz/valhalla/specializati...
As for multi-language support on the CLR, compared with the old 1.x days, there seems to be less focus on it.
With C# getting most of the focus, followed by VB.NET and F# playing catchup.
Also outside MSR, most researchers focus on the JVM, in spite of its caveats, and nowadays LLVM as well.
ETHZ is the only one I am aware that also designs languages with CLR in mind. The Active Oberon successors, like Zonnon.
There are some companies selling compilers for .NET, like Cobol, Eiffel and Pascal. Not sure how well they are doing it.
Clojure also targets the CLR, but they don't seem to have a story for .NET Core.
For example, if everyone played the ball into the same direction, probably Longhorn could have been what UWP is becoming.
https://www.google.com/webhp?sourceid=chrome-instant&ion=1&e...
Here's a post from a JRuby developer saying he prefers a simpler VM.
In the comments section of the same post you'll see Martin Odersky, creator of Scala, saying he also prefers a simpler VM. I could probably find more examples if I dug further.
>I am pretty sure the CLR always supported variance, it was just unused up until C# 4.0
Nope. They were introduced to both the CLR and the C# language in 4.0. See https://www.codeproject.com/articles/72467/c-4-0-covariance-... https://blogs.msdn.microsoft.com/rmbyers/2005/02/17/generic-...
> To implement this feature, the C# language designers had to modify the underlying runtime itself and add special bytecode instructions for the feature
I think this argument is misconstrued. This is inherent to the way the CLR was designed. It is not meant to be something that is kept as-is in terms of the bytecode it accepts. It is constantly being improved upon. Most new language features to C#, F#, or other CLR languages mean an update to the CLR if they're related to a new feature in the abstract.
While there's an argument to be made on whether this better than a more generic runtime, the point is that requiring a change to the CLR is not a big deal; that's part of their plan.
I remember one time someone proposed a patch to the JVM to add tail cail optimization and it was basically rejected or deprioritized into oblivion: http://mail.openjdk.java.net/pipermail/mlvm-dev/2010-October...
These VMs are complicated machines and Oracle/Microsoft aren't going to risk modifying them unless it fits their respective agendas.
When one language added a feature has no bearing to when another should add it.
Channels is specific concurrency paradigm. Java utilizes others, not less powerful.
generics = 16%
management+dependency+package+dependency management = 38%
(what a crappy survey. I'm not sure is it even possible to just sum these)
generics = 16%
so it's a good chunk of the people who answered the survey.
2% mention types and 1% type system so it might be possible these come from people dissatisfied with the type system.
Finally, it's not clear whether people who mentioned dependency management where also counted in dependency and management.
All we know is that "generics" was the word the came out the most often.
I ran the numbers just now, and 571 responses contain the (case-insensitive) text substring "package manage" or "dependenc", compared to 623 for substring "generic". These two topics are very clearly the top two. They're also both on my list for this year (research.swtch.com/go2017). It doesn't seem that important which one "won".
If you have suggestions for how to summarize free-response text in a way that lets the data speak rather than lend itself to cherry-picking, please let us know. I'm certainly open to improved analysis next time.
[0] https://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=...
As I noted in a comment elsewhere on this page, if you have suggestions for how to summarize free-response text in a way that lets the data speak rather than lend itself to cherry-picking, please let us know. I'm certainly open to improved analysis next time.
> Other popular responses were GUIs, debugging, and error handling.
I really like the ease of defining Exceptions and just being able to "raise" them in Python - provides an easy early exit and the caller can handle them nicely in "except" clauses.
Edit: grammer
Instead of getting some abstract exception and stack trace over several pages, the error message is usually pretty specific. Yes, it forces to handle errors locally, but that is a good thing, because locally you know what can go wrong. Your user, who is going to be separated by several layers, won't know that and the specificity is a godsend to him.
If I could raise an exception, taking example of Python, I can choose not to worry about handling it in the intermediate methods and it'll float right to the top level subroutine with error message etc and I can handle it there anyway I wish.
$ go build -o my-program .
$ ./my-program
error: SQL syntax error at column 9
$
Now have fun figuring out which of your dozens of db.Prepare() caused that. Of course, when you manually add context at every step of the error return chain, you can just as well show a stacktrace for the same amount of (if not more) information.What changes would most improve the Go documentation?
Collectively examples gets 26%
What Go libraries do you need that aren't available today?
Lots of demand for UI libraries and mobile support - both very hard to get right and would really require corporate backing. Sometimes I suspect large corporations (MS/Apple/Google) churn their OS APIs/languages simply to keep devs busy learning their one platform. This would be hard to do and hard to support long term.
What changes would improve Go most?
The G word comes first (not being worked on), and then package management (being worked on), also library discovery is highlighted as an issue. I'd prefer if they took a step back and prepared a Go 2.0 which removed some of the inevitable cruft (comments as directives, struct tags), and rethought some other features - mostly taking things out rather than adding things, though it would be nice also to see a solution to generics and better containers built-in.
And https://golangnews.com makes an entry in news sources, even if it is near the bottom :)
It'd be nice to see the raw data too (some of the data points require a bit of tidying up (mostly the write in responses for which 1-2 word breakdowns don't really help much and split up similar responses like example/more examples/examples/code examples/tutorials) and words like 'great' are not really helpful without context. Now that they have the data presumably they could merge some of those categories or if they released it others could look at this sort of thing for them.
Here's a chart that shows the number of new golang questions created on SO each month: https://apps.axibase.com/chartlab/c1acecc0/5/
golang is trending up, 20% increase year on year.
In short, types, especially interfaces in returns, are strictly bound to their location which might be a vendor. If two libraries are using vendors[1] then the types are inherently incompatible between the two libraries. My most common point of failure for this is running into Logging interfaces that return themselves. That interface is completely incompatible with the other package's vendored logger, and so you have to have two instances of a logger - one for each package.
[1]: (ie, they both have a main package and a library package, so they both have vendors). It's to the point where if you have a main and a library, like many repos, you should simply move the main to another repo entirely.. which sucks, imo.
Obviously despite what some people kept on suggesting for years on HN, the 2 main concerns regarding the language are 1 - dependency management and 2 - lack of generics.
Strings and comments as band-aid meta-data is one of Go's glaring weaknesses.
That's not the same as a straight gender m/f question. I can imagine that some women felt they weren't under-represented and didn't primarily "identify as a woman" even if they were one. Consider the reverse question with s/woman/man/ - how many men would pick "I identify as a man" vs "I do not identify as part of an underrepresented group". It's a leading question. Bear in mind on that question the vast majority of respondents were just a shrug: either no response, explicitly saying they didn't want to answer, or not identifying as part of such a group.
I think it's a real shame that vi, VSCode, Atom, IntelliJ & Sublime Text come in ahead of emacs — emacs & go-mode are a wonderful way to write Go, particularly if one's using projectile or spacemacs. It's really worth a shot!
As usual you, coldtea, have posted an uninformed, polarising comment with the intent to provoke. Not surprised.
Actually many have maintained exactly that, here on HN. Do you want me to post excerpts of such comments?
Heck, from this very thread: "I admit that I missed generics for the first several weeks but then just moved forward. Nowadays I don't really think I actually need them anymore."
>For at least a year several people on the Go team have acknowledged the demand for generics. Ian Lance-Taylor even added a doc to the go repo which summarised the entire discussion on the various possible implementations and their pros and cons.
I've read the summary, and most of the related blog posts. It has been close to a decade of Golang now. At which point can no practical progress in an area finally be considered as a neglect of indifference? After 7-10 more years?
Besides, regarding the acknowledgement I've posted sometime ago that I consider the standard "Generics are difficult, we just want to make sure we create them perfect before we attempt at adding them" position of the team as a discussion-stopper more than anything else. Perhaps you have some reason why I should be disallowed to be of and express that opinion? Because you don't seem satisfied to point that you consider it wrong.
>As usual you, coldtea, have posted an uninformed, polarising comment with the intent to provoke. Not surprised.
My intent is to express my position on the issue. Which is more or less the same, all these years, and I'm not sure why you'd expect that it should change, or that people who disagree with you should just shut up or something.
Plus, I don't care for your ad hominem.
It's been ~7 years, so there's still two more years before it reaches the amount of time it took Java to get generics.
I'm confident generics will come to Go (I sure hope so), but even if it doesn't, Go's impressive uptake shows that it's not something it desperately needs in order to be a successful language.
Or Docker guys hadn't used it?
Case in point, how interested were people in using Limbo?
The point being that unless you have a huge rich company behind you, you will remain a footnote ?
That crosses into personal attack and so is not allowed here.
coldtea is a forceful arguer but stands out in my mind as one of the users who has done the most to improve the quality of their comments (and thus HN) over the years by becoming more civil and substantive. Admittedly Go+generics isn't likely to hit any peaks of either civility or substantiveness.
We detached this subthread from https://news.ycombinator.com/item?id=13803300 and marked it off-topic.
I get the impression the Go devs have been stoking the flames a bit by refusing to countenance the extension of the language even into areas where it was clearly lacking.
As a Go programmer since the 1.0 days, the concept of the GOPATH that existed when I started using the language is long gone.
In my ideal world, I should be able to clone a go project anywhere on my system, fetch the dependencies from the internet, yes the internet, because its 2017. (if you're that concerned with security fine, include them in your repo) but I should be able to call go build in that directory wherever it is.
Again from an outside perspective, it also seems that these camps talk about their viewpoints to outsiders more than to each other.
Personally, I always thought the reality is probably closer to "Not adding generics prematurely is a design feature, and it hasn't moved forward yet since the core team doesn't need it enough, and no proposal developed critical mass of community support to consider it appropriately vetted."
We're not talking about wanting the new iPhone or a Tesla here, it's about wanting something that simplifies code / improves the expressiveness of a language.
What does "right" mean? All kinds of languages, even pet projects, managed to implement them just fine.
Except if we mean "perfect, in a way that avoids all engineering tradeoffs".
But why would Generics especially need to be perfect in a language full of other engineering tradeoffs?
They've been researching ways to add generics to Go for a long time, here is some background: