Golang: How to Update APIs for Generics
github.com
github.com
func ThrowIfError(err error) {
if err != nil {
panic(err)
}
}
// ....
name, err := FuncWithError()
ThrowIfError(err)You can define an interface with a closed set of types
type Number interface { float64, int64, ... }
Now, the value will be boxed, so you will not have no-allocation sum types but you can approximate boxed sum types with this I think.
The main thing that's lacking is compile time checks whether variant matching is exhaustive.
There isn't anything wrong with a language just not jiving with your sensibilities.
Use new major versions for stdlib packages, e.g., sort/v2
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.
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.
do people ever learn anything.. conventions don't work, only things checked by the language grammar matter
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.
Does this mean Go is perfect? Not at all.
It just means I'd rather have generics late than fundamentally broken.
Now if that would have been part of Go 1.0....
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.
Go actively decided against generics in the beginning to make a small and simple language. We will lose that now.
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...
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.
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.
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.
https://rust-lang.github.io/async-book/01_getting_started/03...
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.
> 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.
Heck, they're pretty much just succumbing to peer pressure.
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.
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.