News for hackers. Stuff that matters.
Re:Functional Programming in Go with Generics by judofyr on Thursday May 27, 2021 @01:23AM (#27299679)
As someone who's working on code base at ~100k LoC I'd say that generics would be great to have:

- We have some utilities (e.g. caching layer) which now either needs to use interface{} (and lose all type safety) or hard-code the type their dealing with (and thus be duplicated).

- Lack of iterators are annoying. We often need to stream data from a database and now we need to introduce a separate iterator-interface for each thing that can be streamed (`Next() (Entry, error)`). Working with these iterators are clunky since we can't write common tooling around it (e.g. "fetch the first entry").

Re:Functional Programming in Go with Generics by cle on Thursday May 27, 2021 @01:37AM (#27299748)
I've written quite a few containers that use interface{} like that...they don't really "lose all type safety", you write a typed container around it (usually a one line implementation) that does the type assertion in one spot, and that's it, you never deal with interface{} again. For all practical purposes, it's just as type safe.

I agree that lack of iterators is one area where there is permanent annoyance. Personally, I think that annoyance is a lot less than the other problems that come with generics (at least in other languages).

I'm not saying there aren't legitimate scenarios where generics simplify things. I'm completely convinced that there are. But holistically I don't think they outweigh all the other baggage that they come with.

Re:Functional Programming in Go with Generics by nicoburns on Thursday May 27, 2021 @11:31AM (#27304288)
> I've written quite a few containers that use interface{} like that...they don't really "lose all type safety", you write a typed container around it (usually a one line implementation) that does the type assertion in one spot, and that's it, you never deal with interface{} again. For all practical purposes, it's just as type safe.

At that point aren't you just writing out the generics by hand? Why would you not want a built in language feature for that which saves you the trouble while simultaneously ensuring the code is correct.

Re:Functional Programming in Go with Generics by cle on Thursday May 27, 2021 @03:33PM (#27307164)
You're writing out the concretization by hand. Generics as a language feature are much more complicated than their concretizations, which is my point. Generics are to their concretizations as "-e^(iπ)" is to "1".
Re:Functional Programming in Go with Generics by nicoburns on Thursday May 27, 2021 @04:31PM (#27308029)
If you're writing generic code using interface{} and then wrapping that in concrete wrappers then you're actually doing both!
Re:Functional Programming in Go with Generics by cle on Thursday May 27, 2021 @06:33PM (#27309419)
I’m talking about formal generics, where there are type system mechanisms for specifying type parameters and constraints. I suppose there are really three things we’re considering here: the generic implementation that operates on some arbitrary type, the concretization that has only concrete types, and a generic type specification which is only required if the compiler emits the concretization instead of the programmer. (I'm ignoring interfaces as they aren't really relevant here, that I can see. And hopefully I'm using the right terminology here.)

What I’m arguing is that for most cases, the implementation and concretization are so easy to write by hand, are safe enough, and perform well enough, that I don’t think the downsides of having the compiler emit the concretizations are worth it. The downsides being the new complex language primitives that have lots of consequences that trickle out to the compiler, runtime, and ecosystem.

Re:Functional Programming in Go with Generics by nicoburns on Friday May 28, 2021 @05:38AM (#27313359)
> a generic type specification which is only required if the compiler emits the concretization instead of the programmer. (I'm ignoring interfaces as they aren't really relevant here, that I can see. And hopefully I'm using the right terminology here.)

Unless I'm mistaken, the "generic type specifications" are just interfaces. Instead of specifying the concrete type of a function parameter, you specify which interface it needs to implement, and then everything else is the same (except you may need to define getters/setters if you need access to struct fields). There's no need to have a new language primitive. That's certainly how Rust does it anyway. And given that Go's interfaces are structurally typed, it'll be even simpler in Go.

I don't really understand the argument that generics are complex. As far as I can see, they're super simple.

Re:Functional Programming in Go with Generics by moldavi on Thursday May 27, 2021 @02:03AM (#27299878)
I've often wondered about this. Does this technique (a type safe wrapper around an interface{}ing class) kind of accomplish the same thing that generics do for Java? It would result in the same kind of type-erasure in the end, I'd assume.

In a weird way, with this technique, did Go have "manual generics" all along?

Re:Functional Programming in Go with Generics by masklinn on Thursday May 27, 2021 @03:28AM (#27300350)
> In a weird way, with this technique, did Go have "manual generics" all along?

In the exact same way every langage without generics had generics all along: not in any meaningful way.

You could also use codegen hook to instantiate your pseudo-generics after all: https://www.reddit.com/r/rust/comments/5penft/comment/dcsgk7...

Re:Functional Programming in Go with Generics by pharmakom on Thursday May 27, 2021 @02:43AM (#27300119)
Except you still have to write out the typed implementation - even if it is small. In Java this is not necessary.
Re:Functional Programming in Go with Generics by cratermoon on Thursday May 27, 2021 @12:22PM (#27304842)
Not really, but aside from the functional aspect that tends to come with them, all generics are really saying is "this operation will performed on a type to be named at runtime", optionally with a constraint that says the type-to-be-named-later will adhere to a certain interface (contract).
Re:Functional Programming in Go with Generics by cben on Friday May 28, 2021 @10:30AM (#27315742)
On a type to be named _separately_.

To-be-named-at-runtime is simply dynamic typing. It's polymorphism without static typing.

Generics based on type erasure, e.g. Java, wrap that with a type system hoping* to prove safety at compile time, yet compile to a single dynamicly typed implementation, that does not use this type info at runtime.

Generics based on code generation / specialization, e.g. C++, generate distinct run-time implementations with the type hard-coded. (Though you can plug in dynamic typing by making the hard-coded type a pointer.) In C++ this is more than optimization, it's semantics — you can specify distinct behavior for specific types.

JIT compilers can start from a single dynamic-dispatch implementation and generate specialized implemetations for some types, bridging the divide.

But in any case, the common meaning of "generics" is not merely polymorphism, it's polymorphism plus a type system where you _name_ the type you're gonna use.

* https://3fx.ch/typing-is-hard.html#java

Re:Functional Programming in Go with Generics by hajile on Thursday May 27, 2021 @11:39AM (#27304377)
That's just going back to dynamic typing.
Re:Functional Programming in Go with Generics by cle on Thursday May 27, 2021 @03:41PM (#27307278)
It's not anywhere close to that. There's a tiny expression where we override the type system, but everything else in the program is still statically typed, and we get to avoid all the complexity of generics.