They spent months consolidating feedback and made two proposals. The community didn't want change. Now they are no longer working on it and are focusing on getting generics out.
I would guess they start looking into it again after the generics transition is done. But I think it is a good practice not to force things but let certain ideas rest, if no agreement can be reached. Probably the best solution hasn't been found yet :)
Approximating closed sum types is easy already, by creating an interface with a stub private method and implementing it for all variants. Then it's not possible to implement it using a type outside of that package.
The main thing that's lacking is compile time checks whether variant matching is exhaustive.
Certainly this is true, but I wouldn't put it past rsc & co to find some magical incantation that provides full backwards compatibility. In particular the alias keyword was quite succinct and not abused much.
Sounds like a nightmare for newbies getting started. If this is the way forward, and I agree its the most Go-like, I would like to see good support for warning users to use v2 and why they need to.
Quite the opposite. Naive users will not be affected. They’ll just use generics and not realize that for certain types the code generated is more specific.
Or are you assuming newbies read the standard library source?
Think how the maintainers of third-party package will maintain their package after this: before, they just need to target the one and only `atomic` (or any other package mentioned in the GitHub discussion), now they might have to target both `atomic` and `atomic/v2` just to support generics.
I really hope they could come up a cleaner solution than this.
I know a lot of “get started with Go” blog posts, books, etc recommend going through the standard library code to see conventions in practice. Go’s stdlib is relatively easy to read, especially if the consumer has some previous experience with other languages.
just an aside but that github discussions feature looks amazing -- first time i am noticing it. so many "issues" are really just discussions. kudos to the github team.
You can have a funny/ insightful comment that doesn't add to the discussion, so it makes sense to me at least. It's like Facebook + Reddit/ HN voting systems at once.
The problem is that there is a convention of using :thumbs-up: for voting on an issue. Many people forget that discussions have their own voting mechanism, independent on reactions.
Plus, when migrating an issue to a discussion, the reactions are transferred, but since people were using :thumbs-up: for voting, the new system isn't used for old issues turned discussions, and this whole thing becomes a mess.
They're still trying to decide basic stuff like how to transition existing APIs to generics!? Wow, that means it will be a long time for generics to land on stable Go.
No. The generics can be added without this discussion to be resolved. It is about upgrading existing APIs to make full usage of generics. Take math.Min for example. Currently it compares floats. Without changes, it continues to do exactly that. The question now is, how to have a new version math.Min that fully uses generics, without destroying backwards compatibility for existing code. Resolving this most elegantly is desirably, but not a necessity. Especially it can be added a few releases later than the generics themselves.
By having them since the begining, it is not as other languages haven't gone through the path of bolting on generics after the fact, as an example for others to learn from.
You mean like how Rust had async from the beginning? Oh wait. I guess we'll have to wait till 2040 for these languages to be complete before we can have a release then.
The massive success Go has been suggest that their decision to start simple, without generics, was objectively a good one, even if unpopular to.somr.
Heck, not even sure if it'll really be Go anymore when it ships...
Good idea to bring Rust into the table, async is also not fully backed and there are several use cases that will only be taken care in years to come, if at all.
With incompatible runtimes.
So another good example of what happens when things aren't baked on 1.0 release.
If Go did not had UNIX/Plan 9 key persons and Google money attached to it, or killer projects like Docker and Kubernetes, it would have fizzled away.
As it is, even those that would rather not use it, must do so, specially when we use DevOps hats from time to time.
But it seems like this type of "replacing stdlib features" discussion mostly evaporates for Rust.
In Rust an edition changes the prelude and new code that looks the same now gets the desirable new behaviour, even though backwards compatibility is undiminished for old code.
It feels like several of the Golang proposals are in the same spirit (I noticed one explicitly invoking Rust) but as hacks rather than a built-in language feature.
It only evaporates, because most people aren't language geeks that waste part of their life reading SIGPLAN and IEEE papers. :)
Currently in Rust async/await generators discussion has been put on hold as being a hot topic, and as library writer one can't still be sure the library will properly work across all async runtimes.
Same kind of 1.0 issues apply to Java, D, C#, C++,.... and they are specially bad in guest languages that take decisions on syntactic sugar for missing platform features, and when the platform adds those features, they usually end up with two ways of doing the same thing.
This seems once again to have returned to talking about async, for whatever reason, rather than the topic "How to Update APIs for Generics".
> as library writer one can't still be sure the library will properly work across all async runtimes.
If you have assumptions that the runtime can't deliver, your library won't be useful with that runtime. True. Most obviously if you require async to mean "It just magically happens on another thread", and that's not what this runtime offers, too bad, that's not what you get.
It is conceivable that Rust will settle on Async always meaning Threads, and then this problem goes away, but I suspect it's far more likely (since Rust is adopted in embedded systems where nobody has any intention of "just" dropping in a complete threading system) that this persists, if you needed Threads then you'd better make sure you've actually got Threads, because duh, if there's only a single thread of execution then whenever you're not waiting for the async task to happen it isn't being worked on.
Latency has a similar issue, if you need latency guarantees you need a runtime with actual latency guarantees, Rust's async does not do that work for you.
But again, if down the road this is magically resolved (which I doubt) Rust can just ship a new edition with the new behaviour, which is the point you entirely ignored.
The problem is how to move forward, and I believe Editions are a significant improvement over the status quo for most languages in that regard. You can't expect to get everything correct in 1.0, and so you should already be planning for how to improve.
So far I prefer this approach to any other. I know this type of discussion happens under any go submission, but still - need in generics is overrated, there a ton of code written for all sorts and purposes and scales and it works just fine. And all that without a gigantic marketing push which means that developers simply like it that way it is.
Go is about compatibility, being able to control your code base and being confident about results and I'd really prefer them to take their time thinking through a non-critical feature rather then rushing it and exploring all sorts of unexpected side effects down the road.
As they will need to be retrofitted just like Java had to do, yes I'm sure there'll be warts. Had they been considered from the start, I'm sure it could have been much simpler.
Of course it can, the problem isn't writing APIs, it's rewriting old APIs that have static types to also be generic without breaking old code that rely on the static types.
E.g., if you write the number constant "1" as arg to a method taking "float64", it's implicitly converted to that. If the method takes a T, you instead have an int.
This is Go's Python 3 moment. This creates a hard fork of the ecosystem, with a before and after, and all existing Go code is now un-idiomatic and will have to be refactored, rewritten, or replaced.
Not really. Python 3 introduced breaking changes requiring modification of your code base. That's absolutely not the case here for Go. You can still compile and run your code unchanged. You are also overestimating the magnitude of the number of line of codes impacted by the new style using generics.
It's not a breaking change, but it is a radical change for what it means for Go programs to be Go programs. All Go programs are now written the "wrong" way. Or, in other words: all present Go programs would not pass a code review if they were introduced following the release of Go 2. This also affects many libraries throughout the ecosystem, increasing the API churn and burden on downstream projects. It will create millions of man-hours of work for Go users.
Every Go program written using interface{} to provide psuedo-generics was known to be "wrong" at the time it was written, unfortunately the "right" way wasn't a part of the language so people put up with it. I don't believe that generics are going to radically shift any facet of Go programming and I predict that a year from now they'll be just another feature of the language.
If somebody's refactoring some area of code that heavily uses interface{} or code generation maybe they'll considered rewriting parts, but interface{} and code generation are not deprecated or made obsolete by generics.