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.
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.
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.
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.
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.
[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.
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