4 ms·
I only occasional do language design / compiler writing projects, or work with compiler internals. Most people are really bad at estimating the implementation
by klodolph 5y ago
I only occasional do language design / compiler writing projects, or work with compiler internals.
Most people are really bad at estimating the implementation complexity and tradeoffs inherent in various language features. I'd say that C++ serves as a warning to others... think before you add features to your language, or you'll end up a total mess, like C++. Java and C# gave us some interesting and subtle lessons about what does and does not work about language features like generics. C++'s templates are just a total mess, all around. Java's generics are kind of a funny compile-time feature and have a ton of limitations. C# generics have some downright nasty interactions with other parts of the type system, like operator overloading.
IIRC the designers of C# have some regrets about how generics and other features were implemented. This is from an in-person talk, I don't have anything to cite.
You should take almost nobody at face value when they talk about language features like generics, because there is almost nobody with direct experience both designing and implementing those features. You should be pretty skeptical about what I'm saying too, IMO. But do believe that the design tradeoffs for generics are a complicated enough to justify the wait.
The Golang approach seems to strike a balance between extreme approaches. The C++ approach is "pay for what you use" which, in practice, is actually an extremist language design philosophy. In C++ / Rust, you are supposed to pay for templates only in code size and not in runtime. Everything is fully instantiated. The Haskell approach is "one abstraction fits all, everything is a pointer, use an implementation dictionary, monomorphization is an optimization". Again, something of an extremist approach (similar to Java's, but the comparison with Go / Haskell is better because Go / Haskell both use implementation dictionaries).
A middle approach is actually somewhat novel, believe it or not.
- shadowgovt 5y agoC++ still has the dubious honor of being the only language where I encountered code that I could not compile because my machine lacked enough memory. I'm sure that's possible in other languages, but the program I was trying to compile wasn't that complicated... It had just been written by someone who believed every concrete class needed an abstract interface it was implementing.
- klodolph 5y agoI've done that in lots of languages, but it usually means I was trying to crash the compiler :-) I remember there was some simple way to crash a Haskell compiler with an out of memory error by defining a series of types, where each successive type required twice as much memory as the previous type to represent.
- gspr 5y ago> I've done that in lots of languages, but it usually means I was trying to crash the compiler :-) It's a real problem. Anecdotally: I maintain a Debian package with a large-ish (but far from huge), template-heavy C++ codebase. I had to give up on compiling on 32 bit machines long ago, simply because not enough addressable memory was available to the compiler. I know other maintainers have to heavily tune the compiler to work around the problem, too. I was once asked by the Ubuntu folks to disable parallel builds altogether, due to even their 64 bit builders running out of memory altogether. And this package is just large-ish – it's nowhere near truly large (like a browser or an office suite).
- nosefrog 5y agoI wasn't able to run the Clojure compiler in 2012 on a $150 dollar chromebook because it would OOM... but I blame myself for that one :P
- kllrnohj 5y agoI see you haven't worked with the joy of gradle & modern Java development. By the time you stack up gradle, javac itself, proguard or for Android R8 which are basically required to fix the terrible bytecode javac produces, some annotation processors because WHY NOT, custom build plugins, etc... it gets big
- shadowgovt 5y agoComputers seem to have caught up. The Java stack is the slowest one I regularly use (though it does support a certain amount of hot-recompile that other toolchains I use don't or can't), but it's never just crashed because it can't find room to store all those bytecode files.
- jayd16 5y ago>C# generics have some downright nasty interactions with other parts of the type system, like operator overloading. Operators are static methods so why is that surprising or nasty?
- klodolph 5y agoIt affects method overloading too, I should have said “method overloading”. Just take a look at the rules for method overloading in C#, or take a look at one of the various C# compilers to see how methods are resolved.