News for hackers. Stuff that matters.
Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @06:33PM (#34619730)
It is great that Go1.20 improves compile times after generics were added in Go1.18 [1]!

Overall, I think adding generics to Go was a big mistake. It brings the following drawbacks:

- Slower compile times, even if generics aren't used. This slows down development pace in Go.

- The reduced code readability if generics are used. This slows down development pace in Go.

- The increased complexity of Go compiler. This slows down Go compiler development and increases chances for bugs.

- Very low adoption of generics in practice, since they aren't useful in most Go code bases. The generics are actively used in some freaky packages only after the year since they were released in Go1.18.

The only useful thing from Go generics is a syntactic sugar, which allows replacing `interface{}` with `any`.

[1] https://go.dev/doc/go1.20#compiler

Re:Go 1.20 Released by Macha on Wednesday February 01, 2023 @06:39PM (#34619830)
I mean, here's the Go 1.18 release notes and what they have to say about the dev team's level of faith in the stability of their implementation: https://go.dev/doc/go1.18

Is it a surprise that the low uptake is there with a discouragement like that?

Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @06:48PM (#34619924)
I'm sorry, but I don't get this comment. Go is a great programming language! It is great because it is easy to write, read and maintain programs written in Go. This is because of the following features:

- Simple syntax

- Fast compile times

- Great tooling (go fmt, go vet, go too pprof, go tool cover, race detector, ect.)

- Useful standard library

Generics do not improve any of these features :( They complicate syntax, they slow down compile times and they complicate internals of go compiler and tools.

Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @06:56PM (#34620018)
BTW, it is great to see that Go1.20 and the upcoming Go1.21 [1] return to good things instead of generics:

- Performance optimizations (profile-guided optimization, GC optimizations, etc.)

- Reducing compile times

- Reducing binary sizes (improved linker, which can throw away unused code more aggressively)

[1] https://groups.google.com/g/golang-dev/c/V8ez4YunkeE

Re:Go 1.20 Released by philosopher1234 on Wednesday February 01, 2023 @06:48PM (#34619928)
I doubt that was very widely read. I think it would be a mistake to attribute much of the adoption to that statement.
Re:Go 1.20 Released by zeeboo on Wednesday February 01, 2023 @06:36PM (#34619777)
You forgot to list the most useful feature of adding generics: people on the internet can no longer say "lol no generics", drastically reducing the amount of garbage comments about Go.
Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @06:38PM (#34619801)
Except that these people now pollute the Internet with freaky packages, which use generics in esoteric ways :)
Re:Go 1.20 Released by 0x62c1b43e on Wednesday February 01, 2023 @08:03PM (#34620595)
But if adoption is “very low”, then it’s not much pollution, is it?
Re:Go 1.20 Released by thunky on Wednesday February 01, 2023 @08:41PM (#34620914)
Those comments have now been replaced with "adding generics to Go was a big mistake".
Re:Go 1.20 Released by philosopher1234 on Wednesday February 01, 2023 @09:58PM (#34621472)
Maybe they will, but they haven't, since this is the first time I've seen that comment. The "lol no generics" was endemic.
Re:Go 1.20 Released by 0x62c1b43e on Thursday February 02, 2023 @12:35AM (#34622519)
It’s hard to be objective because of filter bubbles, but I’ve seen it a lot on Reddit last.
Re:Go 1.20 Released by 0x62c1b43e on Thursday February 02, 2023 @08:06AM (#34625993)
*lately
Re:Go 1.20 Released by 0x62c1b43e on Thursday February 02, 2023 @12:29PM (#34629998)
*lately

It pops up on /r/golang sometimes. I don’t think it gets taken super seriously but there’s usually at least someone bringing it up.

Re:Go 1.20 Released by SPBS on Thursday February 02, 2023 @12:39AM (#34622542)
They'll never go away, it just morphed into "Go was wrong and finally learnt the lesson that Java 5 did 19 years ago by adding in generics".

Go showed that useful software could be written without user-level generics. I don't think any other language today would dare to do that. In fact most languages seem to be converging into the same thing.

Re:Go 1.20 Released by pjmlp on Thursday February 02, 2023 @01:48AM (#34623049)
We already knew how to write useful software without user-level generics, we have been doing it for decades since FORTRAN came to be in 1957, no need for Go to prove anything beyond the stubbornness of its designers.
Re:Go 1.20 Released by Macha on Thursday February 02, 2023 @06:17AM (#34625064)
Useful software can also be written in asm and we have the entire early software industry to demonstrate that.

That's not the same as it being a good idea

Re:Go 1.20 Released by valyala on Friday February 03, 2023 @02:55AM (#34638432)
Go is about productivity. It allows writing, extending and maintaining big codebases with lower efforts comparing to assembly or some other programming language out there. This is because of simple "what you read is what you get" syntax without implicit code execution. Generics break this feature :(

Of course, there are other brilliant features in Go ecosystem, which simplify writing and maintaining non-trivial codebases in Go - tooling, standard library, fast compile times, statically linked binaries, etc.

Re:Go 1.20 Released by iio7 on Wednesday February 01, 2023 @07:02PM (#34620081)
Exactly this! It's such a shame generics where added.
Re:Go 1.20 Released by zxcvbn4038 on Wednesday February 01, 2023 @07:03PM (#34620087)
You missed the highlight - the best part of go generics is it shut up all the people whining that go didn't have generics! =)
Re:Go 1.20 Released by mseepgood on Wednesday February 01, 2023 @07:15PM (#34620184)
You acknowledge in the first sentence that compile times are back in line with Go 1.17 (i.e. pre generics), yet you claim that generics mean slower compile times.
Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @08:23PM (#34620771)
Go1.18 and Go1.19 have slower compile times comparing to Go1.17 even for codebases, which do not use generics. For example, VictoriaMetrics [1] - the project I work on, which is written in Go without generics.

[1] https://github.com/VictoriaMetrics/VictoriaMetrics/

Re:Go 1.20 Released by rom-antics on Wednesday February 01, 2023 @08:42PM (#34620928)
Yes but these are release notes for Go 1.20.

(1) Make it work, (2) make it right, (3) make it fast

They did 1 and 2 in the last two releases, and in Go 1.20 they did (3). So what's left to complain about?

Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @11:55PM (#34622252)
Why to spend time and efforts for adding useless generics in the first place? Maybe it would be better spending this time on performance optimizations, compile times optimizations and binary size optimizations instead.
Re:Go 1.20 Released by oauea on Thursday February 02, 2023 @01:09AM (#34622769)
Because it's extremely useful to have adaptable data structures, without byzantine code generation?
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @02:40AM (#34638277)
Could you provide links to a few Go packages, which implement useful generic-based data structures?
Re:Go 1.20 Released by oauea on Friday February 03, 2023 @01:29PM (#34645691)
Try google.
Re:Go 1.20 Released by girvo on Thursday February 02, 2023 @04:03AM (#34624021)
Because they’re not useless.
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @02:40AM (#34638283)
Thanks for very strong argument :)
Re:Go 1.20 Released by girvo on Friday February 03, 2023 @04:13PM (#34647784)
No weaker than yours :)
Re:Go 1.20 Released by vlowther on Thursday February 02, 2023 @10:28AM (#34627844)
Because I would rather write one generic container library than n slightly different ones for each data type of deal with screwing around with casting interfaces?
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @01:30AM (#34637826)
This sounds good in theory. What about practice? Could you provide a few links to popular Go packages, which benefit from using generics?
Re:Go 1.20 Released by 0x62c1b43e on Wednesday February 01, 2023 @08:05PM (#34620611)
I’m gonna be that guy, but do you have sources for any of this? That link shows that compiler performance is the same as before generics, for instance.

Are there more bugs in the compiler? Is readability reduced, and having an effect on pace? Especially if adoption is so low to begin with? Is adoption actually so low, or just rising?

Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @08:28PM (#34620817)
That link admits that the compiler performance was lower than needed in Go1.18 and Go1.19, because of generics, even when compiling Go code without generics. I can confirm this based on my own open source projects written in Go [1].

[1] https://github.com/valyala/

Re:Go 1.20 Released by 0x62c1b43e on Wednesday February 01, 2023 @09:03PM (#34621097)
I understand, but it shows that compiler performance is the same as before generics now, so any performance hit is gone.
Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @11:57PM (#34622267)
But the time spent on designing, implementing and then optimizing the generics is lost. This time could be spent on more valuable things for Go ecosystem.
Re:Go 1.20 Released by 0x62c1b43e on Thursday February 02, 2023 @09:59AM (#34627369)
Generics consistently showed up as one of the most desired features (if not the most desired) by working Go developers in the previous developer surveys, so I think it makes sense that the Go team felt the ecosystem saw much value in it relative to other features and worth the time.
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @01:42AM (#34637902)
Unfortunately, the Go team was misguided by vocal minority who was using the "missing generics" argument as an excuse why they do not switch to Go from their favorite programming languages. The majority of working Go developers were happy with Go, so they didn't take part in the debates and surveys about generics.

The irony is that vocal minority still do not use Go, since they have other excuses now - "bad error handling", "missing functional features", etc. But if these harmful features will be implemented in Go, the vocal minority will find another reason why they do not use Go.

Re:Go 1.20 Released by jen20 on Wednesday February 01, 2023 @08:14PM (#34620686)
> - The reduced code readability if generics are used. This slows down development pace in Go.

Speak for yourself: I prefer generics to the mess if copy-pasta or generated stuff that one had to use before.

Re:Go 1.20 Released by valyala on Wednesday February 01, 2023 @08:25PM (#34620789)
Could you provide a few links to popular open source projects, which switched to generics and got better code because of this?
Re:Go 1.20 Released by cpuguy83 on Wednesday February 01, 2023 @09:10PM (#34621150)
Can you point to one that had the opposite effect?
Re:Go 1.20 Released by valyala on Thursday February 02, 2023 @12:11AM (#34622342)
No. I suppose, maintainers of popular open source projects couldn't justify introducing generics into their code. This is exactly my story - I was actively seeking places in VictoriaMetrics codebase, which could benefit from switching to generics. Unfortunately, not a single place has been found yet. There was a promising place for generics [1], but it has been appeared that it is better from readability and maintainability PoV to use plain old interfaces instead.

[1] https://github.com/VictoriaMetrics/VictoriaMetrics/blob/mast...

Re:Go 1.20 Released by cpuguy83 on Thursday February 02, 2023 @03:28PM (#34632497)
Tacking on generics on a working code base is difficult.

I effectively used it in this little experimental CLI library: https://github.com/cpuguy83/go-cli/blob/main/command.go

It's pretty simple, but the nice thing is it can use any flag library you want (stdlib flag package, pflag, whatever).

Re:Go 1.20 Released by valyala on Friday February 03, 2023 @02:03AM (#34638045)
Try substituting F generic type with the FlagSet interface - and the code will become more clear without the need to use generics.
Re:Go 1.20 Released by cpuguy83 on Friday February 03, 2023 @01:09PM (#34645305)
That totally changes it as it requires type assertions to use. With generics `Flags()` returns a concrete type and not an interface.
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @03:40PM (#34647437)
The question is whether the Flags() should return the concrete type instead of FlagSet interface? Another question is whether the additional complexity related to generics worth the ability to get the concrete type from Flags()?

In fact, the generic-free implementation based on the FlagSet interface is more flexible, since it allows storing multiple different FlagSet implementations in the same Cmd.

Re:Go 1.20 Released by cpuguy83 on Saturday February 04, 2023 @11:51AM (#34655838)
I mean the generic type def there could be changed such that different Cmd's can have different flag implementations.

The main point is that generics come in handy when building libraries so that you aren't forcing callers of your library into specific types or loosing some type safety.

Re:Go 1.20 Released by jppittma on Wednesday February 01, 2023 @09:38PM (#34621339)
Suppose you're the maintainer of a popular open source project, and you have a million users running a working, stable version using code generation.

What priority would you assign a bug that migrates the existing, working code that other people are doing god knows what with downstream? What would the theoretical benefits "better code" be to your downstream, and how do they weigh against the cost of "I ran go mod tidy, and our build broke?"

Re:Go 1.20 Released by jen20 on Wednesday February 01, 2023 @11:35PM (#34622125)
Re:Go 1.20 Released by valyala on Thursday February 02, 2023 @12:17AM (#34622393)
I doubt this library is useful. Some of the provided functions such as Clone(), Clear(), Copy() and Equal() are substituted by simple and readable three-line loops. Others are plain harmful. For example, Keys() and Values() may lead to huge memory allocations when working over big maps, while DeleteFunc() worsens code readability and maintainability comparing to a simple 3-line loop. Additionally, it may slow down the resulting code.
Re:Go 1.20 Released by jen20 on Thursday February 02, 2023 @01:12AM (#34622784)
> I doubt this library is useful

It is.

> Additionally, it may slow down the resulting code.

FUD.

Re:Go 1.20 Released by valyala on Friday February 03, 2023 @02:23AM (#34638161)
Agreed, it's my fault that I didn't explain why maps.DeleteFunc() can be slower than a simple loop with "if" statement inside. The reasons for the slowdown are:

- Go compiler may fail to inline the callback passed to the maps.DeleteFunc(). This will result into an additional overhead for callback calls per each item in the map.

- Go compiler may move some variables inside the callback from stack to a heap. This will result in an additional memory allocations comparing to a simple loop, leading to an additional load on garbage collector.

Re:Go 1.20 Released by oauea on Thursday February 02, 2023 @01:13AM (#34622793)
Useful enough to be included in the standard library. https://github.com/golang/go/issues/57436#issuecomment-14125...
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @02:17AM (#34638128)
That would be a mistake :(
Re:Go 1.20 Released by oauea on Friday February 03, 2023 @01:28PM (#34645663)
FUD
Re:Go 1.20 Released by 0x62c1b43e on Thursday February 02, 2023 @02:51PM (#34632071)
By that logic we should remove bytes.Clone, strings.Split, bytes.Equal, strings.TrimLeftFunc, etc. from the standard library.
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @02:15AM (#34638116)
The bytes.Clone() uses non-trivial trick under the hood - `append([]byte{}, b...)`. Compare it to a trivial loop behind maps.Clone().

The strings.Split() implementation is non-trivial because of performance optimizations.

The bytes.Equal() is actually written in highly tuned and optimized assembly in order to achieve high performance for inputs of various lengths.

Now compare this to trivial implementations behind generic-based functions for maps. And do not forget that these implementations may hurt performance because of excess memory allocations in Keys() and Values() functions or because the compiler may fail inlining the callback passed to DeleteFunc().

Re:Go 1.20 Released by 0x62c1b43e on Friday February 03, 2023 @01:48PM (#34645997)
Those are good points about some of them being nontrivial.

Though part of why they’re optimized and in the stdlib in the first place is because they’re such common patterns. So without them people would end up writing trivial, unperformant, custom versions. So now that more routines can be moved into the stdlib, they can benefit from optimization later.

(I’m not sure how much the maps routines specifically can be optimized, but stdlib routines routines can generally be more aggressive with unsafe or asm or being coupled to the runtime and its quirks, like bytes.Clone, strings.Builder, etc.)

And there are still plenty of ubiquitous patterns that have been worth including in the stdlib even if they’re usually just simple loops that aren’t very optimizable. Like strings.Index is an easy loop to write, but it comes up so often. Or strings.Cut is basically just an if-statement. But it makes code clearer about its intentions; and optimizations to these down the road benefit everyone.

It’s also true that maps.Keys and maps.Values allocate slices, and that you could avoid this with a loop, but strings.Split, bytes.Split, regexp.FindAll, os.ReadDir return slices and are still worthwhile as opposed to specialized iterators for each one. As with any code, you’re conscious of memory allocations where it counts, and optimize as needed.

In fact, now that generics make it possible, the Go team has discussed using iterators (https://github.com/golang/go/discussions/54245), which would benefit strings.Split even further in addition to all the other slice-returning functions.

So generally you have three options for those slice-returning functions:

- Custom inline loop for some of them. More verbose, will probably be naive and not benefit from stdlib optimizations. - Return a slice and iterate over it with a for loop. Creates allocations that could probably be avoided. - Create a customized iterator for that type. Unfortunately, you can’t really use an ordinary for loop, and extra custom iterators for each type. - Use generic iterators to benefit from the optimized functions and also avoid allocation overhead.

So part of the motivation is that now with generics there’s a variety of further optimizations available even to old functions like strings.Split and regexp.FindAll, in addition to opening up common patterns and optimizations for maps/slices/etc. to be included in the stdlib.

Re:Go 1.20 Released by valyala on Friday February 03, 2023 @08:56PM (#34650555)
Agreed with most arguments.

A few remarks:

> Like strings.Index is an easy loop to write, but it comes up so often

Actually, strings.Index() is very non-trivial function partially written in assembly in order to achieve high performance [1]. This function is used in Go projects *much more frequently* than functions from the golang.org/x/exp/maps package.

> strings.Cut is basically just an if-statement

No, strings.Cut() has non-trivial code when comparing to a trivial loop for map copy or for map delete [2].

> It’s also true that maps.Keys and maps.Values allocate slices, and that you could avoid this with a loop, but strings.Split, bytes.Split, regexp.FindAll, os.ReadDir return slices and are still worthwhile as opposed to specialized iterators for each one.

The *key* difference between maps.{Key,Value} and the mentioned functions from the standard library is that it is trivial to write the `for k, v := range m` instead of maps.{Key,Value} and avoid memory allocations, while it isn't trivial to write the corresponding code without memory allocations, which substitutes strings.Split() or other mentioned functions from the standard library.

[1] https://github.com/golang/go/blob/86c4b0a6ec70b07ab49d3813a5...

[2] https://github.com/golang/go/blob/86c4b0a6ec70b07ab49d3813a5...

Re:Go 1.20 Released by bboreham on Thursday February 02, 2023 @04:41PM (#34633541)
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @01:53AM (#34637973)
That's a good example of using generics-based sorting! I think it would be more beneficial to work on compiler optimizations, which could optimize the standard interface-based sort.Slice and sort.Sort to the same level. This shouldn't be too hard to do for the most widespread case when the compiler knows the actual type hidden behind the sort.Interface, so it could inline methods of this interface.

This optimization then could speed up other similar interface-based algorithms.

Re:Go 1.20 Released by 0x62c1b43e on Thursday February 02, 2023 @10:02AM (#34627408)
Yeah, and I don’t tend to keep this around quantitatively, but I’ve certainly run into bugs in Go programs that would’ve been categorically prevented with generics.

Of course I want sync.Map to use generics instead of interface{}. How could I not? And it’s less complex-looking than type-asserting everywhere.

Re:Go 1.20 Released by valyala on Friday February 03, 2023 @03:17AM (#34638610)
The sync.Map is a good example , which could benefit from switching to generics. The problem is that this is the only useful case for generics. This case could be implemented in the way similar to built-in map[k]v generic type, which is available in Go since the first public release. And this could have prevent from opening the Pandora box with the generics.
Re:Go 1.20 Released by 0x62c1b43e on Friday February 03, 2023 @01:56PM (#34646126)
It’s not the only one. Some other packages that used workarounds like interface{} or other things to work around the lack of generics were container/{heap,list,ring}, sort, golang.org/x/sync/singleflight, /x/exp/{maps,slices}, etc. And people will want to write their own patterns at other times of course too. It wouldn’t be reasonable for these all to become builtin types like map. These standard library packages that already exist will also become more efficient and potentially reduce allocations (when using primitives) as well.
Re:Go 1.20 Released by valyala on Friday February 03, 2023 @04:05PM (#34647694)
The container/list and container/ring is one of the least useful packages included in the standard Go library, since they aren't used widely in Go programs. It is better from performance and readability PoV to use an ordinary slices instead of these packages in most cases.

The container/heap is more useful, but it could benefit more from adding an optimization for inlining interface method calls when Go compiler knows the underlying implementation behind the interface.

The golang.org/x/exp/maps is useless and may be harmful [1].

The golang.org/x/exp/slices is mostly useless, except of Sort*() functions. But it would be better to apply the optimization mentioned above to standard sort.* functions instead of forcing users to switch to different Sort*() implementations in other packages.

[1] https://news.ycombinator.com/item?id=34622393

Re:Go 1.20 Released by jen20 on Friday February 03, 2023 @08:11PM (#34650195)
> since they aren't used widely in Go programs

They aren't widely used because the ergonomics suck, because they aren't generic yet.

Re:Go 1.20 Released by 0x62c1b43e on Friday February 03, 2023 @08:18PM (#34650260)
> The container/heap is more useful, but it could benefit more from adding an optimization for inlining interface method calls when Go compiler knows the underlying implementation behind the interface.

This is exactly what generics do. With e.g. a heap.Heap[uint32] the compiler knows the implementation and there’s no interface method call overhead.

In order for the compiler to do this optimization, it has to know that you don’t e.g. pass a heap.Heap[uint32] to a function expecting heap.Heap[uint64], so the type system is what allows it to optimize.

And on top of that, now the user also gets assurance at compile time that heap.Heap[uint32].Pop returns a uint32, preventing bugs from type confusion and also so you don’t have to add type assertions everywhere you use the heap.

So now heap, sort, etc. can benefit from this improved performance; users don’t have to write wrapper types and interface implementations just so their type can be sorted; and bugs are prevented at compile time.

For [1] I posted a reply. It’s true that there are overheads with some slice-returning routines but I explained how in the reply how I viewed the tradeoffs.

Re:Go 1.20 Released by valyala on Friday February 03, 2023 @09:21PM (#34650709)
In theory the compiler can inline interface method calls without the need to introduce generics. For example, it can detect that the customStruct is passed to the sort.Sort() in the code below, and then instantiate the sort.Sort() code for the given inlined Less(), Swap() and Len() interface calls:

    type customStruct struct { ... }
    func (cs *customStruct) Less(i, j int) bool { ... }
    func (cs *customStruct) Swap(i, j int) { ... }
    func (cs *customStruct) Len() int { ... }

    func sortMyCustomStruct(cs *customStruct) {
      sort.Sort(cs)
    }

The tricky part here is that the compiler should be careful when instantiating such calls for different interface implementations, in order to avoid generated code bloat. For example, if sort.Sort() is used for a thousand different sort.Interface implementations, then it may be not a great decision to create a thousand of distinct sort.Sort() instances for every sort.Interface implementation. But this should work OK for a dozen of distinct implementations.
Re:Go 1.20 Released by smasher164 on Wednesday February 01, 2023 @08:44PM (#34620948)
I use generics all the time in my Go code, in particular with the exp/slices library and lo. I do not find it less readable. I think readability is subjective based on people's programming experience and familiarity with type systems.
Re:Go 1.20 Released by 12345hn6789 on Wednesday February 01, 2023 @08:49PM (#34620979)
worse program readability is not a true con. Any codebase can have positive or negative code quality, generics do not make this worse.

In fact, it can improve readability and maintainability in some cases instead of having multiple structs copy pasted everywhere.

Re:Go 1.20 Released by philosopher1234 on Wednesday February 01, 2023 @10:00PM (#34621493)
>worse program readability is not a true con. Any codebase can have positive or negative code quality, generics do not make this worse.

While true that generics are not necessarily going to make programs harder to read, it's also not very interesting to talk about theory.

The question which is answerable is, "on average, were go programs easier to read before the introduction of generics". The interesting point is what actually happens, not what could.

Re:Go 1.20 Released by 12345hn6789 on Wednesday February 01, 2023 @10:50PM (#34621803)
You are correct that we must observe this in practice. But, the original poster of this thread purports that generics are making go worse in multiple ways. 1: Slower compile times (without evidence) and 2: have created worse code (without evidence)
Re:Go 1.20 Released by philosopher1234 on Wednesday February 01, 2023 @11:51PM (#34622223)
Sure, they haven't proven their claim. This is all the realm of speculation.
Re:Go 1.20 Released by kune on Thursday February 02, 2023 @02:04AM (#34623165)
At first I was on the fence too. I'm not use it all the time, but when I need it, it works as expected and it is much less a hassle than I remember writing C++ templates.

I have not seen a lot of comments that complained about the slower compile times. In my own experience it didn't really had an impact. But I agree the compiler should not become slower over time, so I appreciate the effort of the Go team to bring the compiler speed back.

I don't think that code readability is so much impacted. The square brackets work well. I find the angle brackets from C++ harder to read and there is the problem that >> is a token and cannot be used for two closing template angle brackets.

The increased complexity of the compiler is an issue, but cannot be avoided if you want to support Generics. But they took the time to make it right and as I stated it works for me.

I don't think that there is low adaption. Using type parameters visibly in a public API, breaks the API, which is the reason there are not a lot of uses in the standard library and with popular packages now. But this will change when maps and slices will be integrated in the standard library, which provide completely new APIs. Yesterday I found a library writing and reading parquet files, which used it quite extensively. But since I simply checked what libraries existed to assess how well the file format is supported, I cannot say much whether the use of type parameters by the library is useful.

Re:Go 1.20 Released by umanwizard on Thursday February 02, 2023 @03:05AM (#34623614)
> there is the problem that >> is a token and cannot be used for two closing template angle brackets.

This was fixed years ago in C++11.

Re:Go 1.20 Released by Conscat on Thursday February 02, 2023 @11:54AM (#34629328)
They still have other issues, though. You ever had to put `template` before a templated member function called from an object of a `typename` type? Not fun, yet I have to do it all the time in my C++ code. MSVC and Comeau make this problem optional, but GCC and Clang don't (as per the standard).

The chevrons also confuse all my editors, because they can't figure out whether `<` is an opening bracket pair, or if its just a less-than operator. I'm a bit miffed that Cpp2 doesn't try to replace the chevrons with something else, like D did. I'm also miffed that Rust uses the chevrons too.