Hacker News new | past | comments | ask | show | jobs | submit login
Golang: How to Update APIs for Generics (github.com/golang)
126 points by 0xedb on Sept 15, 2021 | hide | past | favorite | 63 comments



Can't wait for the thing to land. My only remaining wish is sum types


Any updates regarding the if-hell of error handling?


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 :)


"Try another language instead" is always a valid option.

There isn't anything wrong with a language just not jiving with your sensibilities.


Problem is, perfect language with perfect libraries and perfect tools doesn't exist.


Somewhere in the middle of Go, Julia and Rust is the programming language I'd really like to use.


I'd throw in Swift into the mix


I just took another fresh look at it and on the surface the syntax looks really attractive.


No, it's not. It's just being dismissive because your wants are being met by the current state.


(Not attacking you) Do you write a substantial amount of Go very frequently?


I have never used golang but from my reading of the type parameters proposal, it also includes an approximation of "Sum types".

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.


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.


THIS ! and "pattern-matching" :)


So, in the end all of languages move closer to StandardML :D Like even python has sum-types and pattern matching now!


Lol I know I know... but it is so useful :)


That would be awesome!


And exceptions :)


Please, just not exceptions.


Too late, Go already has exceptions since 1.0.


Indeeed,

    func ThrowIfError(err error) {
        if err != nil {
            panic(err)
        }
    }
    // ....
    name, err := FuncWithError()
    ThrowIfError(err)


Panic and recover already exist, which are semantically exceptions.


Were there discussions? What is the general impression, is there hope?


This is the way:

Use new major versions for stdlib packages, e.g., sort/v2


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?


I don't think it would be that easy.

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.


It irks me that they have both votes and reactions.


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.


I agree, that is a great feature. Now we can separate what is a true project issue than a broad question/discussion


> I'm going to go out on a limb and suggest that we use the Of suffix for generic container types

do people ever learn anything.. conventions don't work, only things checked by the language grammar matter


This is explicitly the language for not learning things we've figured out over the last decades so ... no ;-)


Doesn't matter, the standard library simply has to set a consistent example for people to follow. They can choose to ignore it.


Given that some of the language designers had the same approach for safety in C versus the existing alternatives, yep people don't learn much.


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.


Because it's far from basic stuff when you have to consider stability guarantees.


You know how to avoid those problems?

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.

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.


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.


Those key persons are exactly the ones that decided Go should not have generics.

Heck, they're pretty much just succumbing to peer pressure.


I for one like not having things rushed in which then cannot be changed later on.

Does this mean Go is perfect? Not at all.

It just means I'd rather have generics late than fundamentally broken.


For the time we have waited already, what is a couple of years more, right?

Now if that would have been part of Go 1.0....


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.


Indeed, only Google paychecks, and two historical figures of UNIX and Plan 9 history, no marketing at all.


"Generics" or parametric polymorphism, first appeared in the 70's. So I don't think including this with Go 1.0 would have been rushing!


Yeah, about that: just because the theory exists doesn't make it less work to design new elegant typesystems around them.

Go actively decided against generics in the beginning to make a small and simple language. We will lose that now.


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.


I mean basic in that it's like the feature can't even be added if you don't solve that.


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.


They will still compile with a Go 2.0 compiler, try to run a Python 2.7 script on Python 3.9.


Surely this is more like... when Java 5 introduced Generics, and everything changed a lot (eventually)?




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: