Live data from Hacker News

Notes on the Go2 Generics Draft

jmoiron.net

91–100 of 116 posts

Re: Notes on the Go2 Generics Draft

#91
I have written about 10+ medium and big projects in Go for production over last 6 years. They were written mostly for CI/CD, APIs, cron jobs and various pipelines in e-commerce and consumer electronics domains. Have personally never needed generics or have felt that I can improve the code by using generics. I also have quite a bit of Java experience so I do know why you would need generics, but it just never came up in Go. Maybe my opinion will change with the new proposal getting implemented, but at this point I don't see how.

Re: Notes on the Go2 Generics Draft

#92
post #71

Earlier quoted context omitted.

I'm curious, what's a better solution for generics if you want some kind of container which doesn't need to care what type it contains? Is the better solution to just use the current C-style void* s everywhere and manually cast your objects to and from void* (or in Go's case, interface{}), leaving type safety to the programmer? Or is the argument that people shouldn't need to write containers, and all necessary conta…

Code generation by means of Go's standard template library has worked nicely for me. Best of all, gdb sees the concrete type, so value inspection stays easy. Only snag, minor enough, is that emacs auto-indent becomes confused by the double braces, as in "{{.templateVar}}".

I've learned to be wary of the interface type. Although the run-time overhead is negligible anywhere outside tight loops, induced debugger overhead can become a misery.

Re: Notes on the Go2 Generics Draft

#93
post #86

Earlier quoted context omitted.

Writing the exact same code for float and double (and possibly complex float and/or complex double) sucks. You've created some straw man about dopamine junky programmers because you don't need generics for whatever it is you do. If you wrote numerical algorithms you'd be annoyed at any language which lacks generics.

Maybe that's the issue. From what I have seen, the lack of generics mainly becomes painful when working in the numerical space. If I work on mapping JSON, doing APIs and CLIs I don't really need generics. If I work on algorithms and data bags then it starts to be annoying re-implementing the same thing over and over again. So in these discussion you have devops-type people mainly dealing with APIs that are perfectly…

I think you're exactly right: People who live and breathe JSON and strings don't (and probably shouldn't) care about use cases where the choice between float or double matters...

I also see this with graphics people who live and breathe small (2x2, 3x3, and 4x4) matrices don't care about "type level integers" (as Rust calls them) to make 6x9 matrices efficiently live on the stack or in an array.

> Is it possible that a boxed "Number" type would solve most of the problems?

If you mean it the way I think you do, not for me. I can easily afford to fit a billion 4 byte floats in memory, but I can't afford a billion 8 byte box pointers to a 4 byte box with an n-byte tag, and the cache locality could be horrible.

However, if Go had an elegant macro system (Rust's doesn't seem too bad), I could get by though.

Re: Notes on the Go2 Generics Draft

#94
post #29

I’m a fellow generics pessimist. Having come to Go from Java some 6 years ago I initially found the lack of generics a curious, sometimes frustrating omission. After years of using Go daily and reading a long succession of posts on the go-nuts mailing list wherein Rob Pike, et al, repeatedly and staunchly defended the lack of generics as necessary – even beneficial – in the pursuit of designing a small, readable, coh…

Speaking of Rob Pike, don't see his name on any of the Go2 proposals. His lucidity and circumspection are sorely missed.

Could we be witnessing the psychological phenomenon of a "second-system effect" -- as described in The Mythical Man-Month -- writ very large?

Re: Notes on the Go2 Generics Draft

#95
post #71

I'm glad I'm not the only one sad to see generics invading a perfectly good language. Programmers love generics because they enable higher-order abstractions, and programmers love abstractions -- code that isn't DRY is like an itch we need to scratch. Programmers also hate special cases, because they feel restrictive and inconsistent: I recall quite a few people protesting that Go's 'range' keyword shouldn't be restr…

I'm curious, what's a better solution for generics if you want some kind of container which doesn't need to care what type it contains? Is the better solution to just use the current C-style void* s everywhere and manually cast your objects to and from void* (or in Go's case, interface{}), leaving type safety to the programmer? Or is the argument that people shouldn't need to write containers, and all necessary conta…

I've been writing Go for five years and I've never had a pressing need to create my own generic container type. The built-in types -- arrays, slices, maps, and channels, or some composition of them -- have proved sufficient. When I do need a new type of container, it either ends up being specialized for a specific type, or it accepts generic types via interface. Like, I need a red-black tree for this one algorithm, but do I really need a generic red-black tree that can handle any type? The answer is almost always no.

I'm fine with Go having a handful of built-in generic containers+functions. In fact, I think most people asking for "generics" would have their true needs met by adding a few more built-ins to the language. I pursued that idea here: https://github.com/lukechampine/ply

I sympathize with the programmers who really do need generics and would like to program in Go, because I love the language. But the way I see it, 95%+ of programs don't truly need generics. I like the trade-off Go makes by omitting generics, and it makes me sad that the language could change in such a radical way to meet the needs of that <5%. A language doesn't need to be perfect (or even usable) for everyone! Throwing in feature after feature to satisfy everyone just creates a culture of compromise and destroys a language's character. I want a set of narrow tools that I can master. No one ever complained that a hammer makes a terrible paintbrush. So in a broader sense I think this whole discussion reflects a wider need for good languages. We need ten languages of Go's caliber! I know the "just use a different language" argument is kinda callous, but the alternative feels worse.

Re: Notes on the Go2 Generics Draft

#96
post #49

Earlier quoted context omitted.

To quote the entire sentence, "It seems most inspired by CLU and a proposed future C++ feature". Note that Stroustrup proposed C++ concepts in 2003, and they still don't exist in C++, but they might be standardized by 2020. Also note that CLU also didn't implement compile time specialization at all which is one of their core design requirements (for performance). I don't think this is the particular prior art most of…

Java-style parameterized types is not the only option and they have acknowledged that they ignored us for a long time. "They are likely the two most difficult parts of any design for parametric polymorphism. In retrospect, we were biased too much by experience with C++ without concepts and Java generics. We would have been well-served to spend more time with CLU and C++ concepts earlier." https://go.googlesource.com/…

I'm not disputing that there's prior art for their design like C++ concepts (although C++ doesn't do run-time generics and CLU didn't do compile time). I'm just disputing the view designing and implementing it will be easy, like they could have just thrown it in there without taking substantial time away from other priorities and/or delaying the language, so anything short of providing generics day 1 is disingenuous or maybe ignorant.

Take this interview with Chris Lattner (of Swift) for comparison:

http://atp.fm/205-chris-lattner-interview-transcript/.

Some of the things they want in the future but just haven't had time for (more reflection, core networking libraries, etc) are things Go provided day one. If you look at the recommended way of dealing with JSON in Swift for example, it's full of boilerplate. Go also provided green threads and GC which probably adds some implementation work compared to languages that don't have them. They've also prioritized language stability to a much greater degree than Swift.

I don't know to what degree Go has succeeded with its mission inside Google/Youtube (for new projects, obviously they aren't going to re-write everything), but it seems like the Go team has more resources than it did before, which might be part of why they're more comfortable tackling major changes like this now.

If language designers didn't want to make nuanced trade offs in the design space between compile time, performance, code size, ease of use/complexity etc and sweat all the implementation details I'm sure they could operate a lot faster. Javascript might have already cornered that niche though.

Re: Notes on the Go2 Generics Draft

#97

I'm glad I'm not the only one sad to see generics invading a perfectly good language. Programmers love generics because they enable higher-order abstractions, and programmers love abstractions -- code that isn't DRY is like an itch we need to scratch. Programmers also hate special cases, because they feel restrictive and inconsistent: I recall quite a few people protesting that Go's 'range' keyword shouldn't be restr…

Writing the exact same code for float and double (and possibly complex float and/or complex double) sucks. You've created some straw man about dopamine junky programmers because you don't need generics for whatever it is you do. If you wrote numerical algorithms you'd be annoyed at any language which lacks generics.

You can just write the types, annotate them with github.com/clipperhouse/gen, and get pre-tested, reliable implementations around your type.

Generators are a legitimate solution and I wish they'd get more love.

Re: Notes on the Go2 Generics Draft

#98

I'm glad I'm not the only one sad to see generics invading a perfectly good language. Programmers love generics because they enable higher-order abstractions, and programmers love abstractions -- code that isn't DRY is like an itch we need to scratch. Programmers also hate special cases, because they feel restrictive and inconsistent: I recall quite a few people protesting that Go's 'range' keyword shouldn't be restr…

> I worry about generics because they let you abstract with wild abandon. They let you inject a little magic.

Not really.

> You can't chain together operators in point-free style, or add a property to every 'Object', or directly increment a string, or anything like that. In other words, it's a terrible language for code golfing. But that sort of code has no place in a production environment anyway.

Complete straw man.

Re: Notes on the Go2 Generics Draft

#99
post #68

I'm glad I'm not the only one sad to see generics invading a perfectly good language. Programmers love generics because they enable higher-order abstractions, and programmers love abstractions -- code that isn't DRY is like an itch we need to scratch. Programmers also hate special cases, because they feel restrictive and inconsistent: I recall quite a few people protesting that Go's 'range' keyword shouldn't be restr…

Same here, as a security consultant reading Golang is always a pleasure. I'm pretty sure that the strongest codebases I've seen were in Golang just because of how easy it is for everyone to read the code and actually spend time looking for logic bugs instead of trying to understand what is happening. Developers love to be able to write their magical code and their clever abstractions and often forget that their code…

> Developers love to be able to write their magical code and their clever abstractions and often forget that their code is paying the price by becoming less clear and less readable.

Clearly, that justifies the fact that you can't sort an array of doubles and an array of floats with the same function.

Re: Notes on the Go2 Generics Draft

#100
post #71

Earlier quoted context omitted.

I'm curious, what's a better solution for generics if you want some kind of container which doesn't need to care what type it contains? Is the better solution to just use the current C-style void* s everywhere and manually cast your objects to and from void* (or in Go's case, interface{}), leaving type safety to the programmer? Or is the argument that people shouldn't need to write containers, and all necessary conta…

I've been writing Go for five years and I've never had a pressing need to create my own generic container type. The built-in types -- arrays, slices, maps, and channels, or some composition of them -- have proved sufficient. When I do need a new type of container, it either ends up being specialized for a specific type, or it accepts generic types via interface. Like, I need a red-black tree for this one algorithm, b…

The irony is that the reason the built-in types like arrays, slices, maps, and channels are useful is because they're the only types allowed to be parameterized by types in the language. It'd be interesting to see how many people would defend this choice if they were forced to work with intArrs and stringToStringMaps, etc.

I don't have any opinions on adding generics to Go because I don't have a sense of how it interacts w/ other features of the language, but having to specialize all your types to specific uses means there are very common types of libraries that are significantly harder to find in Go than in other languages, or are much less useful, or work around the lack of generics w/ interface{} casts and are significantly less type safe. I suspect that people who deny the value of generics enjoy learning about the implementation of these things and writing them themselves rather than using libraries. Don't get me wrong, there's value in that, but it's at the expense of writing libraries with stable interfaces, boilerplate-free code, large systems that can easily be refactored, etc.

It also makes it harder to actually use a type system for the value it provides: the ability to encode facts about data irregardless of their provenance. Libraries may provide interfaces that work on a certain number of presumed useful primitive types, but your own types can encode far more constraints. Without the ability to use those types you will have to care about provenance again (has this value been validated for use by this function?) or constantly reuse a normalization process to construct those values, which may introduce conversion overhead and creates more error-prone situations. Not to mention that generics also provide constraints about what a piece of code _cannot_ do. The example made famous by haskell programmers is that an "fmap" function defined as such cannot tamper with the values being mapped over, since it has no knowledge of their concrete implementation:

fmap :: Functor f => (a -> b) -> f a -> f b

Genuinely, I don't understand why you would create a static type system in a new language that didn't allow for parametric polymorphism, it's one of the most fundamentally useful features in type-checking code.

Post reply on HN