At least some work is being done, even if "This is the beginning of the story, not the end".
At least some work is being done, even if "This is the beginning of the story, not the end".
Featherweight Java is an idealized language, small enough for doing experiments. These experiments often involve the necessity of a formal proof. But being a small language, still capturing the crux of the full language, greatly simplifies the problem space.
Featherweight Go serves the same purpose: find the core. Give the core generics. Then you have a good chance at implementing generics for the full language.
Most languages which end up with type parametrization do so when the language is small and somewhat pliable. Neither Java nor Go did, even though both languages had plenty of prior work in the area. Hence, you have to "reconstruct" a world in which there is such a small language such that your experiments run fast.
It was a mistake in Java that they corrected with a lot of pain. It is a mistake in Go they are going to correct and most likely with a lot of pain. If they cannot do it seamlessly it may end up being a Python 2/3 platform split.
Those who fail to learn from history are doomed to repeat it.
It's also not at all clear that Go will have similar problems as Python did, since the Go team considers backward compatibility important and might approach the problem differently, learning from Python what to avoid.
Counterfactual reasoning is difficult. Learning from history isn't as easy as some make it look.
Because there were languages that are much better suited for what Go was designed for. To name a few: Erlang (concurrency that is better than Go's, "channels" and types on par with Go with Dialyzer), Haskell (thread concurrency better than Erlang's, channels, transaction memory, etc and types well beyond Go) and many others.
Go was successful despite mistakes.
Certainly, a lot of people are attracted to Rob Pike's rather idiosyncratic preferences, tastes, and nostalgia for the early days of Unix, which are on display in a lot of Go's design decisions, like the lack of generics. But lots of random people have preferences and nostalgia for all sorts of things; we usually only pay attention to such things when it's a person with a famous pedigree who has them.
Was there something in this paper that you felt unfairly treated Rust, the language you represent on these threads? Because otherwise, I can't see what would motivate you to join this thread to snipe.
I'm with David, for what it's worth. Lack of generics has mostly helped me be productive in Go, and the extreme prevalence of generics in every Rust library I deal with has definitely slowed me down a bit. I'm looking forward to generics support in Go, but mostly for what I hope it does to message board threads.
Let me put it another way: Virtually all languages that have become popular recently have done so because of the backing of some large organization or another. There was a time when languages like Perl, Python, and PHP could arise out of basically nowhere and become popular. That time is gone, and now languages essentially need organizational backing of some kind to succeed. That was true for TypeScript, it was true for Rust, it was true for Swift, it was true for Kotlin, and it was true for Go. They also benefit from some sort of well-known thought leader, a role that Rob Pike plays well. If you think Go would have gotten popular without having a Google and a Rob Pike behind it, then, well, I don't know what to tell you. I don't think Rust would have been popular either without the Mozilla association.
Or, more succinctly: I see no world in which Go having simple ML-style generics, without typeclasses or functors, would have made it any less popular. Other factors dominate when it comes to success of a programming language. TypeScript, in fact, shows that you can have generics that are more complex than those of Rust and still become wildly popular.
But the bigger problem is just that Rust programmers use generics absolutely everywhere (my early impression is you basically can't avoid it, because of lifetimes), and it simply does make everything harder to understand. I know I'm going to be told that if I buckle down all of this stuff will make sense and I'll be fluent with it, and sure, I managed to grok Alexandrescu C++, too. But adding new layers of indirection everywhere just has to impede comprehension; that's always the tradeoff for parameterizing and indirecting!
The flip side of this is, I've built some fairly serious things in Go --- a compiler, a couple emulators, a disassembler, a symbolic evaluator; not just the server stuff Go is supposed to be good at --- and I have complaints about Go, but almost none of them are its lack of generics.
(There are things I like about Rust! But this isn't the thread for it.)
Reading the esbuild discussion at the time, it definitely read to me as "our language is definitely faster and if you're not getting the same performance you're holding it wrong", but looking at it now I can see how it wouldn't be intended that way.
Regardless, sorry; I think I was projecting some frustrations with the wider RESF on to you.
I’ve now resigned myself to wishing it treated its magic generics with proper typing.
You are right, Go got more initial momentum because it came out of google and had Rob and Ken's names attached to it. But the useful part is why people actually use it.
I hear this a lot, but the counterexample is always Dart. Google is behind it, and Lars Bak is definitely not a nobody, yet the language struggled to gain momentum; not until Flutter came on the scene, and it wasn't an official Google project when it started.
for i := len(a)/2 - 1; i >= 0; i-- {
opp := len(a) - 1 - i
a[i], a[opp] = a[opp], a[i]
}
Actively hurts reading code as you have to credentialize in a code base to begin to be able to file entire code blocks into copy and pasted "idioms".Without generics you have to hope the stdlib gets a blessed generic function like reverse() one day since you can't build one without rolling your own monomorphization code-gen or a goofball interface{}+cast hack.
For people who supposedly prefer the lack of generics (which seems more like cargo culting or Stockholm Syndrome), no problem. We can just add a config option to golint that prohibits you from using generics. That way you don't need to hold up the rest of us. win-win.
That's a recurrent issue with Go: you can either have ergonomic tools (with interface and reflection), or performant code (with no allocation) but you generally can't have both at the same time. Sure it's better than scripting language where you need to use another language when you need performance, but it's still kind of sad.
If writing a function that can take an array or slice of any type of data requires providing a generic argument (I.e. so you can specify that the function returns a slice of the same type of data as it was given), then you can name it "reverse" if it reverses the array, write it only once, and every timr you use it, you read "reverse" and know what it does.
For loops dont have those names, and so have to be rewritten every time you use them. As such, every time you see a for loop, you have to read and parse every statement to see what it is doing, and if it has any unexpected side effects or bugs introduced via copy-paste or what not.
https://github.com/gcanti/io-ts/blob/master/src/Schema.ts#L2...
Granted, genetics don't need to be done that way, but it is among the more common and popular approaches. The type information is tangled up in the implementation, making focusing on either more challenging. Perhaps we need modes for syntax highlighting- one for types, one for implementation?
Which is why Go had already a good example to learn from on how not to do language design.
As much as I like generics, Go's popularity is a success: programmers have spoken, and they value other things more than generics.
Hindsight is 20/20, and even this isn't a commitment to introduce generics in Go.
Both its main influences, Oberon-2 and Limbo had zero traction on the market, and Limbo not only is quite close to Go, it had an whole OS full of the Plan 9 ideas to come along, yet it failed on the market.
Lack of generics has already been publicly acknowldge as problem.
> In three years of Go surveys, lack of generics has always been listed as one of the top three problems to fix in the language.
https://blog.golang.org/why-generics
And yes, there is no place on the 21st century for typed languages without generics, we already have enough of them from the previous century already.
CLU and ML, the first languages to support genericity are from the mid-70's, they are older than C++ and contemporary to C.
It can also feel sometimes like a dynamic language which has attracted people from ruby, python, JS, etc... communities.
You say there's no place for it in the 21st century, yet it already has a place and it doesn't really need generics to continue living.
I agree Go cannot offer similar things due to a weaker type system.
I willingly code Go day-to-day. I miss Java streams, and sometimes the codebase is slightly worse due to the lack of Java streams (or equivalent).
I accept a weaker language because I spend less time debating the Right Way to do things (Go is too inexpressive to support a Right Way), and because I can widen my hiring pool from those that know Java, to those that any language, knowing that they can easily pick up Go.
Why isn't Dart seeing the same type of success?
Original Go team did not suffer from this.
That's from people who complain because they want Golang to be like Java
If I had to write a list of “tools I would have preferred to have”:
1. Perfect serialization libraries - Serde is the gold standard here, and IIRC the macro system from Rust is as important a part of it as the traits part.
2. Mutability of types in shared caches - to build efficient controller patterns you need fast and efficient caches - an immutable type that protects against mutation would have saved a lot of ugly mutation testing code
3. Client library definitions shared across types - we could have reduced a fair amount of boilerplate with generics, although most bugs are in the serialization part these days as types evolve
But most of these are dwarfed by the need to scale reviewer time across hundreds of people submitting PRs that change fundamentals of the code. The simplicity of Go and ability to review stupid, obvious, absolutely critical code is the reason why I love it.
Having a strong way to reduce cleverness has been a godsend. It doesn’t mean cleverness is bad, or I don’t want more tools in Go. But I appreciate that aspect of Go in a way that others may not.
Edit: I have been watching kube-rs mature, but to get the same level of scale and performance we’d have to reproduce the shared index informers and that’s a lot of drudge work to get right. That’s one place where someone motivated could really help Rust become a first place way to extend Kubernetes, which would be exciting.
Don't mind.
It’s just ugly because that’s how it evolved after a community formed and that’s what real evolved software looks like. :)
Not saying it is a bad language, but it really helps that Go had Google's blessing.
Or perhaps Google has many hearts and no one knows exactly how many or where they are at any given point in time :-)
How exactly is Google "shoving it down our throats"?
Second what Sun choose to implement was a smaller subset and not that close to Featherweight Java/pizza compiler. It was only generics, not first class functions at the time, nor algebraic types/pattern matching.
> " We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it."
I mean if you are going to use 2001 technology, you could have found it long back.
> In three years of Go surveys, lack of generics has always been listed as one of the top three problems to fix in the language.
https://blog.golang.org/why-generics
By the way, they could have gone to 1974 (CLU), 1973 (ML), 1983 (Ada), 1986 (Eiffel), 1988 (Modula-3), 1990 (Sather & BETA), 1998 (C++), 2007 (D), 2009 (Java & Delphi).
These are just the most well known examples, CS literature in SIGPLAN and IEEE has plenty more to choose from. I bet Google employees can afford the respective subscriptions.
When there isn't any political willingness, there isn't anything to be found.
If I understand you right, you are suggesting that instead of doing what they are doing now, they should have just used an existing design from your list, right from the beginning?
Is there any specific design from your list that you think would have been good to use in Go? Or, do you think it would have been better to have a less-capable generics implementation available right away instead of a more-capable one later?
For example the one you mention the most (Java) requires code duplication to work with 32 and 64 bit floats. I think even the previous proposals that have been rejected for Go have at least had that ability.
Not to mention the open invitation for concrete proposals on how to add them Go.
You might find this post by one of the Go team members interesting:
For example, while Valhalla has taken several years so far, OpenJDK team has experimental builds that you can go and play around with value types in Java.
Where are the experimental builds for generics support in Go?
Actually Valhalla is pretty interesting to think about. For what I'm currently working on, the inability to have a list of points without individually heap-allocating each one makes a language much more of a non-starter than the lack of user-defined parameterized types does.
Even back when Java was invented, there was plenty of prior art (going back decades) about efficiently representing a list of points in memory. Probably most of its predecessors could do it. Yet Java has lacked this basic ability for 25 years.
I even expect that when they eventually implement it it will work similarly to other popular languages, compared to Go which seems to be drawing on more recent developments (like concepts etc) for its generics design.
Despite this, I don't accuse the Java team of political machinations every time the topic comes up. Mainly because I don't believe that to be the case. Maybe they've prioritized a critical feature for me lower than I would like, but it seems like a substantial amount of work to implement because (like generics) it interacts with other language features in a complex way and (like generics) once they ship a design they will be stuck keeping backwards compatibility with it basically forever, so they only have one chance to get it right.
Even stuff like error handling improvements and type alias were almost shot down.
Sure, I think it's fair to say they've focused a lot more on implementation and library changes and not language changes up until recently. Things like rewriting the compiler from C, improving code generation / escape analysis / GC, more platform / architecture support, improving the standard library, getting a reasonable package manager, etc.
So it seems a little premature to read some secret anti-generics stance into it (and it not just being a matter of priorities) since there were all these other areas that they were also way behind Java in.
After package management was in generics started showing signs of life again, so it all seems reasonably consistent with the Go team just wanting to clear other stuff off their plate first before tackling it. Hopefully we see it in a similar timeframe to major Java/C++ features now that it's being worked on more.
If there's any silver lining the actual proposals seem pretty ambitious, seems like they want to enable a lot more than just new type safe collections if they add the feature.
https://github.com/ccbrown/wasm-go-playground/tree/master/ex...
So this is the prototype used at the GopherCon talk.
Secondly, I also kind of like Go, just see it as lost opportunity to have been with little more than a C like type system, even C has some genericity support in the meantime.
And whatever gets out of it, will be rather clunky as proven by late adoption in Java.
On another note, every other Go thread has you and @pcwalton bashing Go. Makes me wonder if Go's success causes some sort of discomfort in some people. It's almost religiously guaranteed to have you both regurgitation the same crap over and over.
What about that then?
But I guess you're actually consistent: you often lament about people ignoring or reinventing approaches that proved themselves in older languages. Here are people that actually take clues from one such language, and you lament that they didn't do it earlier. I see now that it's not really ironic. Rather, you're seeing the glass half empty while I was seeing it half full.
While I am sure Java will get value types, it already has had several experimental releases and the features have been incrementally integrated, after the switch to 6 months release cadence, I am not so sure in regards to Go.
All we get is a source code repository full of comments showing how much is left to be done, if ever. Untouched since last August.