Attempting to define a generic Map function turns out to be somewhat troublesome[1]. This would be really painless if you had type arguments, instead, we have to define an interface to allow peeping into the type and creating a type from a zero value.
Don't get me wrong, I do applaud the efforts for better type system, it's just a weakness in the proposal.
1. https://go2goplay.golang.org/p/P7CVwOW9wig (note this panics currently)
I have to agree with other commenters that the syntax leaves something to be desired. A lot of parentheses competing for attention.
Perhaps we could take a leaf from the Modula-3 book — Go was influenced by Modula-2, which didn't have generics — and be more explicit in declarations. I feel this would be more in the tradition of Go.
For example, instead of
func Max(type T Comparable)(a, b T) T {
if a > b {
return a
}
return b
}
This could instead be enveloped by a "generic" declaration like so: generic T Comparable
func Max(a, b T) T {
if a > b {
return a
}
return b
}Experimenting with wrapping as you suggest, seems a good way to see if that separates concerns in syntax enough to make generics "fun again". Programmed for long time in C++ w/templates . Any and everything that avoids the hells of those syntax and compiler error/messages, could even be called innovative if hitting the right spots. I see generics as convenience, but only if the costs doesn't accumulate over time * complexity.
Generics need to be something natural, not bolted onto a language, or sneaked in. Unlike precompiler defines, and templates to some degree. To that end, maybe it deserves its own nomenclature, form and space, to properly distinguish those special cases from more concrete cases of syntax. Just like we distinguish looping with "for".
You're basically telling the compiler to generate new versions of the same function, or struct, or whatever. The mental challenge with just adding type parameters is that you're thinking of the type as generic, which creates "what colour is my code" distinctions; either types are generic or they're not.
I had another syntax in mind that would reuse the "for" keyword:
for type T:
func Max(a, b T) T {
...
}
Both syntaxes work fine for other declarations; structs and methods, for example: for type T:
type Atomic struct {
v T
}
for type T:
func (a *Atomic) Get() T {
...
}
Of course, you still need some syntax to specify types in expressions, but that's also solvable. // generic works like an interface
type T generic {
comparable // generic allows additional constraints
}
// we know the type parameters by the use of T
// (because T is generic type)
func Same(a, b T) T { ... }
// calls may still need to include the type parameters,
// but type inference will generally make them unnecessary
s := Same(type string)("hi","howdy")
s := Same("hi","howdy")What would instantiation of the function look like?
With the current design it is
maxInt := Max(int)
which has a positional symmetry to the declaration. (type $T Comparable) func Max(a,b $T) $T {
if a > b {
return a
}
return b
}It also means that for a function that requires no type constraints, nothing more is needed:
func WorksWithAllTypes(val $T) {
...
}
I don't like the type constraint syntax, though. I think it could be done like this: func Max(a, b $T Comparable) $T {
...
}
The idea here is that we only need to annotate the first instance of $T; all others will implicitly share the same type constraint. maxInt := Max(1,2)
maxUnk := (SomeType).Max(k,z)
or maxUnk2 := Max@SomeType(k,z)
or just maxUnk3 := Max(SomeType(k), SomeType(z))You should watch the Hype Cycle very carefully with Rust. Rust is no doubt on its way to a Plateau of Productivity, but right now we're at the point where "My company only uses Rust!" or "I rewrote my foobarlang app in Rust!" will get you to the first page... but "Wow, my CI system spent 387 CPU days building my Hello World app last week!" is also starting to show up (on its way to the Trough of Disillusionment).
I hate when things fall into rigid categories because it seems overly simplistic, but the Hype Cycle is spot on. Look for it and you'll see it everywhere.
I'm writing as a regular Go user who's found it very productive, tho I'm worried about its future
[1] https://trends.google.com/trends/explore?date=today%205-y&q=...
[0] https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...
While this is a subset of "new data structures", I'm really looking forward to generic immutable structures that can be read by many goroutines but have some coherent update story. I've got several places in my code where I have a structure I want to update infrequently and have read access in a lot of places, where I'm reading it enough that a traditional read/write lock is a real problem. I've got some stuff hacked together but what I have can't be shared as a library, and I shouldn't anyhow, because a real library ought to be stronger and better.
(I recognize that Go doesn't have immutable data types, but I was programming in Python for many years before Go and have made my peace with "Just don't do that.")
Libraries that operate on maps and slices in a type-agnostic manner.
Probably some numeric libraries with nicer types than you can get now, though I still think Go will be a bad choice for highly numeric code even post-generics.
Several hundred map/filter/reduce libraries that nobody will use for very long.
Data structures are the one I'm really looking forward to, though. Network servers, nominally Go's wheelhouse, is one of those places that we tend to like some obscure data structure choices because of the performance needs. It has been a frustrating hole in the language for a while.
(Personally, I'm not looking forward to generics in Go, I enjoy the simplicity of not having them and haven't encountered situations where they'd make a huge difference.)
The thing I worry about the most is that Go without generics works very well for 95-99% of code. The code is very clear and not overly abstract. The remaining 1-5% of code is hard to write in an efficient, type safe, and DRY way, but I don't see how we can have generics and clear, appropriately-abstract code. I strongly suspect this will change the quality of the ecosystem for the worse. I don't think people consider this tradeoff very often.
Go is not your (as in mine, ours) language. It's a language owned by a corporation that turned evil, that spies on all of us and hands out data to governments. An evil corporation that cooperates with totalitarian regimes, because their mindset is similar anyway, so what's the deal, right? All just business as usual. Screw the public, we own the place. .|.. Google and the Go developers