News for hackers. Stuff that matters.
Re:How generics are implemented in Go 1.18 by kevin_thibedeau on Tuesday March 01, 2022 @03:28PM (#30519553)
The compile time issues for C++ are entirely because of the creaky header mechanism that doesn't permit efficient parsing. Generics have worked fine in Ada since its inception. Any modern language can adopt the same process of tracking a formal abstract interface that is parsed once and expanded into concrete code as necessary.
Re:How generics are implemented in Go 1.18 by josephg on Tuesday March 01, 2022 @03:37PM (#30519664)
The process of expanding genetic code into concrete code based on the types (monomorphizing) can also be an expensive process. At least, people in the rust world point to it a lot as a reason why some crates compile slowly. Monomorphizing multiplicatively increase how much code LLVM needs to process (and optimize).

Mind you, C/C++’s ridiculous header system is probably still a much bigger issue. Especially because C++ templates usually need to go in header files.

Re:How generics are implemented in Go 1.18 by yakubin on Tuesday March 01, 2022 @04:20PM (#30520147)
Although monomorphization takes a significant chunk of a typical Rust compilation, it pales in comparison to LLVM codegen and execution of procedural macros. So although it's academically worthy of note, optimization-wise it's not where the focus should be. Personally, I'd like to see someday a Rust compiler which is not based on LLVM. Both Zig and Jai compile much faster when using their non-LLVM backends than when using LLVM, so Rust is not the odd one here either.
Re:How generics are implemented in Go 1.18 by nicoburns on Tuesday March 01, 2022 @05:34PM (#30520975)
> Although monomorphization takes a significant chunk of a typical Rust compilation, it pales in comparison to LLVM codegen

It's not the monomorphization itself that takes a long time, it's the LLVM codegen due to all the extra code being generated from duplicated function implementations. I've heard macros slow for largely the same reason, it's not the macro execution itself that's slow, it's compiling all the generated code.

Re:How generics are implemented in Go 1.18 by yakubin on Wednesday March 02, 2022 @05:47AM (#30525921)
> I've heard macros slow for largely the same reason, it's not the macro execution itself that's slow, it's compiling all the generated code.

If that were true, the same issue would apply to hygienic macros, yet it doesn't. It's distinctly a problem with proc macros.

Re:How generics are implemented in Go 1.18 by jcelerier on Tuesday March 01, 2022 @04:55PM (#30520583)
> Mind you, C/C++’s ridiculous header system is probably still a much bigger issue. Especially because C++ templates usually need to go in header files.

IDK about that. A project I'm working on is template-heavy in a major way, entirely header-only (~15kloc of this: https://github.com/celtera/avendish/blob/main/include/avnd/c... more or less) but with a barely correctly set-up dev environment with clang and PCH (a couple lines in CMake), ninja and mold, individual rebuilds are pretty much instant ; a complete rebuild which on my machine builds 49 libraries and 38 executables takes a whopping 7 seconds, CMake included.

Re:How generics are implemented in Go 1.18 by xigoi on Tuesday March 01, 2022 @04:09PM (#30520025)
Increases compared to what? If you don't use generics and write the code for each type manually, you'll end up with exactly the same thing.
Re:How generics are implemented in Go 1.18 by zwieback on Tuesday March 01, 2022 @05:43PM (#30521053)
I often wonder about that - if I was going to write by hand I might end up extracting a simple interface, do some type coercion/promotion or some other trick to reduce the number of functions I need to write.

I read about how .Net does Generics at the VM level and was very impressed, a good compromise between C++ "macro expansion" and Java "type erasure", both of which seem extreme.

At the end of the day, though, when generics are present I stop worrying and just use List<int>, List<float>, List<char>, etc. without a second thought. The compiler, VM or runtime can deal with it although I might get punished in some way.

Re:How generics are implemented in Go 1.18 by pshc on Tuesday March 01, 2022 @05:17PM (#30520807)
Increased compile time compared to doing polymorphism with an extra layer of indirection, I’m guessing
Re:How generics are implemented in Go 1.18 by kenniskrag on Tuesday March 01, 2022 @03:31PM (#30519594)
Isn't that solved with c++ modules [1]?

[1] https://en.cppreference.com/w/cpp/language/modules

Re:How generics are implemented in Go 1.18 by Kranar on Tuesday March 01, 2022 @04:13PM (#30520067)
Not really, in C++ templates still need to be instantiated in every module but modules don't have to each repeat the parsing of template definitions. The module that declares the template will do the job of parsing the template and producing some intermediate representation of it that other modules can consume. Okay that does save some amount of time but the overwhelming majority of time spent compiling templates is in instantiating them, not parsing them from literal text into an AST.

Modules don't make instantiating templates any faster, it only makes parsing them faster.

Re:How generics are implemented in Go 1.18 by pjmlp on Wednesday March 02, 2022 @04:02AM (#30525339)
They sure do, make the most common expansions avaiable as extern templates.
Re:How generics are implemented in Go 1.18 by Kranar on Wednesday March 02, 2022 @09:43AM (#30527837)
That has nothing to do with modules. You can extern a template going back to C++11.
Re:How generics are implemented in Go 1.18 by pjmlp on Wednesday March 02, 2022 @11:03AM (#30528810)
Modules make it more convinient to do so, and allow for more build speedups.
Re:How generics are implemented in Go 1.18 by pjmlp on Tuesday March 01, 2022 @03:44PM (#30519738)
Yes, with VC++ offering the best experience currently.
Re:How generics are implemented in Go 1.18 by throwaway2037 on Wednesday March 02, 2022 @08:50PM (#30536099)
I am confused. Why was this downvoted? Is GCC and Clang doing better? (Or another C++ compiler?)
Re:How generics are implemented in Go 1.18 by Kranar on Thursday March 03, 2022 @01:14PM (#30544558)
Because the answer is false, modules do not solve the problem of having common/shared template instantiations.

As for the comment about MSVC, it's mostly off topic, doesn't relate to the question that was asked (which had nothing to do with which compiler provides the best experience), and even if you accept that MSVC provides the best module experience, it's support for it is still very buggy and not suitable for anything other than experimenting and beta testing.

Re:How generics are implemented in Go 1.18 by FooBarWidget on Tuesday March 01, 2022 @03:30PM (#30519582)
Rust also has (relatively) bad compile times due to generics. Not as bad as C++, but you can notice it's significantly worse than Go.
Re:How generics are implemented in Go 1.18 by yakubin on Tuesday March 01, 2022 @04:26PM (#30520232)
Rust does compile slower than Go, but it's not due to generics. It's mostly due to LLVM codegen and procedural macros. Go has the benefit of not relying on LLVM and not having procedural macros.
Re:How generics are implemented in Go 1.18 by edflsafoiewq on Tuesday March 01, 2022 @06:41PM (#30521600)
A lot of the IR comes from expanding huge stacks of generic functions. I don't think the issue can't be neatly partitioned up like that.
Re:How generics are implemented in Go 1.18 by codeflo on Tuesday March 01, 2022 @04:48PM (#30520488)
Absolutely true. I’d add that Rust is also doing a lot more expensive optimizations in release builds.
Re:How generics are implemented in Go 1.18 by jcelerier on Tuesday March 01, 2022 @04:56PM (#30520599)
Until recently Go didn't even use registers for passing arguments, it just put everything on the stack like in a 1965 textbook (https://go.googlesource.com/proposal/+/refs/changes/78/24817...)
Re:How generics are implemented in Go 1.18 by eloff on Tuesday March 01, 2022 @05:04PM (#30520672)
If you mean for function calls, I believe you're correct, not taking into account inline functions.

However, for code generation Go obviously uses registers since way before the 1.0 days.

Re:How generics are implemented in Go 1.18 by geodel on Tuesday March 01, 2022 @08:04PM (#30522324)
You are right of course about LLVM being source of slowness.

In general discussion I see around is that all Rust's perf optimizations are to Rust's credit (nothing about LLVM optimization) while all woes around Rust's compile time lay at step of LLVM and Rust is not be blamed.

Re:How generics are implemented in Go 1.18 by pjmlp on Tuesday March 01, 2022 @03:45PM (#30519759)
D, Ada, Eiffel, Delphi go as counter example, and C++ modules are already proving a much better experience in VC++.
Re:How generics are implemented in Go 1.18 by FooBarWidget on Wednesday March 02, 2022 @06:06AM (#30526020)
Delphi didn't have generics. Not sure about more modern versions, but the power of the generics also impacts compile times. Java generics barely impact compile times at all but they're also nowhere as powerful as Rust and C++ ones.
Re:How generics are implemented in Go 1.18 by pjmlp on Wednesday March 02, 2022 @07:50AM (#30526760)
You stop using Delphi long time ago, I would say.

To pick one of my examples, D templates and compile time metaprogramming are even more powerfull than Rust and C++ ones, yet it compiles just as fast.

Re:How generics are implemented in Go 1.18 by benibela on Wednesday March 02, 2022 @01:57PM (#30531269)
Delphi added generics in 2009

So it had them roughly as long as Go existed

Re:How generics are implemented in Go 1.18 by vyskocilm on Wednesday March 02, 2022 @02:10AM (#30524626)
There is tinygo with llvm backend and the build times are abysmal.
Re:How generics are implemented in Go 1.18 by nicoburns on Tuesday March 01, 2022 @05:32PM (#30520956)
That's not true, Rust doesn't have those headers and has the same compile time issues as C++.
Re:How generics are implemented in Go 1.18 by the-smug-one on Tuesday March 01, 2022 @05:42PM (#30521043)
Rust has macros and an expensive type system though, and compilation is getting faster.