Why ESR Hates C++, Respects Java, and Thinks Go (But Not Rust) Will Replace C (ibiblio.org)
Open source guru Eric S. Raymond followed up his post on alternatives to C by explaining why he won't touch C++ any more, calling the story "a launch point for a disquisition on the economics of computer-language design, why some truly unfortunate choices got made and baked into our infrastructure, and how we're probably going to fix them."
My problem with [C++] is that it piles complexity on complexity upon chrome upon gingerbread in an attempt to address problems that cannot actually be solved because the foundational abstractions are leaky. It's all very well to say "well, don't do that" about things like bare pointers, and for small-scale single-developer projects (like my eqn upgrade) it is realistic to expect the discipline can be enforced. Not so on projects with larger scale or multiple devs at varying skill levels (the case I normally deal with)... C is flawed, but it does have one immensely valuable property that C++ didn't keep -- if you can mentally model the hardware it's running on, you can easily see all the way down. If C++ had actually eliminated C's flaws (that is, been type-safe and memory-safe) giving away that transparency might be a trade worth making. As it is, nope.
He calls Java a better attempt at fixing C's leaky abstractions, but believes it "left a huge hole in the options for systems programming that wouldn't be properly addressed for another 15 years, until Rust and Go." He delves into a history of programming languages, touching on Lisp, Python, and programmer-centric languages (versus machine-centric languages), identifying one of the biggest differentiators as "the presence or absence of automatic memory management." Falling machine-resource costs led to the rise of scripting languages and Node.js, but Raymond still sees Rust and Go as a response to the increasing scale of projects.
Eventually we will have garbage collection techniques with low enough latency overhead to be usable in kernels and low-level firmware, and those will ship in language implementations. Those are the languages that will truly end C's long reign. There are broad hints in the working papers from the Go development group that they're headed in this direction... Sorry, Rustaceans -- you've got a plausible future in kernels and deep firmware, but too many strikes against you to beat Go over most of C's range. No garbage collection, plus Rust is a harder transition from C because of the borrow checker, plus the standardized part of the API is still seriously incomplete (where's my select(2), again?).
The only consolation you get, if it is one, is that the C++ fans are screwed worse than you are. At least Rust has a real prospect of dramatically lowering downstream defect rates relative to C anywhere it's not crowded out by Go; C++ doesn't have that.
He calls Java a better attempt at fixing C's leaky abstractions, but believes it "left a huge hole in the options for systems programming that wouldn't be properly addressed for another 15 years, until Rust and Go." He delves into a history of programming languages, touching on Lisp, Python, and programmer-centric languages (versus machine-centric languages), identifying one of the biggest differentiators as "the presence or absence of automatic memory management." Falling machine-resource costs led to the rise of scripting languages and Node.js, but Raymond still sees Rust and Go as a response to the increasing scale of projects.
Eventually we will have garbage collection techniques with low enough latency overhead to be usable in kernels and low-level firmware, and those will ship in language implementations. Those are the languages that will truly end C's long reign. There are broad hints in the working papers from the Go development group that they're headed in this direction... Sorry, Rustaceans -- you've got a plausible future in kernels and deep firmware, but too many strikes against you to beat Go over most of C's range. No garbage collection, plus Rust is a harder transition from C because of the borrow checker, plus the standardized part of the API is still seriously incomplete (where's my select(2), again?).
The only consolation you get, if it is one, is that the C++ fans are screwed worse than you are. At least Rust has a real prospect of dramatically lowering downstream defect rates relative to C anywhere it's not crowded out by Go; C++ doesn't have that.
He seems to think he has some great insight into why C is C, why C++ is C++. But really, he is so fucking clueless I don't know where to start.
There's enough business logic programmed in C++ and Java to keep both languages around until my kids retire and they're not yet in the workforce. Rust and Go, yeah doubt there's a single company of any size running their business processes on either.
There are 4 boxes to use in the defense of liberty: soap, ballot, jury, ammo. Use in that order. Starting now.
He's a person, not a technical description.
We have enough abbreviations in tech.
Hate it when people do that.
Thank you, Bradley Manning, Edward Snowden and so many others, for courageously defending humanity, my freedom and more!
The higher the level of abstraction in your language, the higher the overhead it will create. Now, it needn't be so absolutely stupidly overengineered as .net is, but still the metric fits, the more safeguards and handrails your language comes with, the higher the overhead it incurs to have them. This is admittedly not really a huge problem in today's working environment because our computer speeds are far greater than our needs.
Still, somehow it feels silly that I need increasingly more powerful computers just to run the same kind of program, only because programmers can't be assed to learn their trade and instead rely on ridiculously overblown frameworks that is the equivalent of delivering a pack of soda with a semi because you have to bring a soda factory along with the workforce since the framework doesn't know how to deliver a single soda.
We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
and debugged
Amply demonstrated by the numerous memory exploits? ;)
Ezekiel 23:20
You mean to say, I don't know how to handle memory management and go does is all for me, without me knowing what it actually does, but it seems to work......... Oh please, Go is just Yet Another Programming Language which wasn't really necessary, but purely because some devs just didn't like other languages (or didn't know how to handle them properly).
Anything that allows us to reduce errors, increase functional complexity, reduce development time, improve readability and maintainability, and/or make it easier to code for a greater amount of people, is progress in my book. Working at a higher abstraction level achieves some or all of those goals.
And good frameworks help with that. When I build a house, I don't want a craftsman who takes time to learn how to use an adze so he can plane down lumber to the correct size for the job; I want a builder who knows he can get lumber of the correct dimensions right at the store. The skills to build instead of buy are useful in many trades (both building and programming), but they are expensive and a possible source of additional errors. Frameworks are often a good answer to that... as long as the developer understands the nature of the framework, its limitations, the licensing model, its viability, and thus can assess the consequences of using it.
If construction was anything like programming, an incorrectly fitted lock would bring down the entire building...
It's useful for large, complex programs where speed is important. That's it -- it's useful in a very small amount of software.
Not sure what your frame of reference is, but that's a LOT of software. Hell, it's basically everything that isn't trivial or severely memory constrained. Had to switch form C++ to C once for a pretty heavily memory constrained embedded application, but otherwise I've been able to get away with using C++ practically everywhere.
"Why should I want to make anything up? Life's bad enough as it is without wanting to invent any more of it."
Usually, when you try to merge the 2 ideas, you end up with something as stupidly inefficient as run-time introspection.
So, because the guiding principle of C++ is "zero-overhead abstraction", perhaps it is the case that you must explicitly choose where the computation will occur—run-time or compile-time.
Personally, I think way more problems arise of terse syntax and high symbolic abstraction that C/C++ and derived languages like so much. I mean, I'm as lazy as the next programmer and that's why I like C (and its derived languages) but even I cannot ignore that
{ (a!=1)?b=!b:b=0}
is way less readable than
begin
if a is not equal 1 then set b equal complement of b else set b equal 0
end
You'd immediately spot an error in the second because the sentence would look "wrong".
We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
Not sure what your frame of reference is, but that's a LOT of software.
No, it's not. Few programmers work on projects that are millions of lines of code and it has to be as fast as possible (real-time).
For servers, memory is cheap ($200 extra) so you can just use Java for that 2 million LOC project.
That leaves C++ only for AI, professional games and large desktop apps (Photoshop, browsers, office etc.). While these types of software are used a lot, no more than 100,000 programmers are working on this, at any given time.
For in-house desktop apps of medium complexity (upto say 500k LOC), you can use C# or VB.net.
Even for games, where low time for development is paramount, the engine is written by one company in C++. Then dozens of other companies use that engine and Lua or some other scripting language to actually write the game quickly.
The remaining 95% programmers can use a sane programming language like C, Python, Swift, Java, Rust, Nim or even Go.
Bottom line: programmer time is money for the company and C++ probably has the 2nd highest cost per line of code compared to other languages (assembly language is 1st in cost/LOC).
It's not always so clear cut. What you say is definitely true for naive compilers, but higher-level abstraction also often mean more information for the compiler and more freedom for the compiler. These can translate to better optimisations. To give a trivial example, languages like Java provide an abstraction that looks like a C struct, but don't require that the memory layout be visible to the programmer. Imagine that you create a struct-like Java object with RGB values to represent a colour and you do the same in C. Now you put them in an array and try to do some processing on them. The C version is constrained to lay out the objects as three fields with no padding (this is visible in the language with sizeof and will break ABIs if it dynamically changes). The Java version, in contrast, is allowed to put an unused padding field at the end of the struct. Why does that matter? If you want to vectorise the loop, then being able to guarantee 4-element alignment for every object in the array is a huge win. This is a legal transform for a Java compiler, but not a legal transform for a C compiler unless it can prove that no pointers to the array escape (and a few other constraints).
The big advantage of C was that a fairly simple compiler for a simple architecture could get very good performance. The disadvantage for C is that compilers quickly hit diminishing returns and the abstract machine makes a number of desirable optimisations unsound.
For example, if your language has a first-class notion of immutability, then this gives the compiler the opportunity to elide copies or add copies if they make sense for NUMA systems, and gives the compiler a lot more freedom with regard to reordering or eliding loads. Similarly, if your source language has higher-level notions of sharing then this means that you can avoid a lot of defensive memory barriers that you'd need for correct C/C++ code. If your language has stricter guarantees on aliasing, then a whole lot of optimisations suddenly become easier.
Any compiler optimisation is a mixture of two things: an analysis and a transformation. The analysis must be able to tell you if the preconditions for the transform are met. The more information you can give to the compiler, the more often the analysis can prove that the preconditions hold and enable the transform.
I am TheRaven on Soylent News
The higher the level of abstraction in your language, the higher the overhead it will create.
This is exactly why C++ remains popular among those who create large, complex, high-performance applications. C++ is well known for using zero-cost abstractions. That means you get the performance of low-level C code, but can design much safer interfaces and type safety in your code which allow the compiler, not a runtime, to validate that the code is correct and safe.
For certain types of applications, it's an effective compromise between the pragmatism of retaining backwards compatibility with decades-old ecosystems, while at the same time providing better safety and abstractions than C.
Irony: Agile development has too much intertia to be abandoned now.
No computer language is going to help a project programmed by idiots.
Irony: Agile development has too much intertia to be abandoned now.
C++ still reigns supreme due to its flexibility. While in some less pragmatic language you are very likely to hit some roadblock because language designers wanted to enforce some principle which ended up counter productive in your particular case, it won't be so with C++. This language has no other principle than practicality, and it will never block you from getting the job done. Even it being superset of C ends up being another aspect of practicality. Because C ABI still is de facto standard for language interop and system APIs and is implementation language for astronomic number of important libs.
With some extra spaces, and the whole thing changed to an expression (which is how ?: is supposed to be used) it's a lot easier to read.
b = (a != 1) ? !b : 0
The advantage of the ternary operator is that you only need the LHS part once, which helps if it's a more complex variable.
No language can compensate for having idiots in your team, but some languages, like C++, make it worse.
And remember: if you see no idiots on your team, you are the idiot.
For in-house desktop apps of medium complexity (upto say 500k LOC), you can use C# or VB.net.
Ok stop right there. No one should use any of the .net crap except if you are forced to due to some Microsoft constraints.
sudo rm -r -f --no-preserve-root /
How do I write drivers and firmware in Go? I think C is going to be around for awhile.
We'll make great pets
C++, like C, like UNIX, is an amazing achievement with lots of mistakes. Hell, Windows NT managed to replace UNIX to some extent, but nothing really managed to replace C++ and C.
Avantgarde Hebrew science fiction
If your point was to make that part more readable, I think I want you on the other team in the next debate.
If you find that unreadable, I don't want you on my team in the next software project.
Well, I do have to say that the code would not pass my code review. Not because of the use of the ternary operator, because of the meaningless variable names. I'd also ask that "0" be replaced with "false".
Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
How is this insightful? Desktop apps require GUI design and .net GUI design tools are excellent. Even the macos Xcode GUI design tools are far behind. With performance in par with Java, C# is a good choice for in-house apps with a good blend of development speed and app performance. /. mods are very biased.
That's just not true. Programming languages can enforce constraints that make common errors either difficult or impossible.
I have to admit a disenchantment with software development in general these days, largely because the consensus within the community is that fast and cheap is better than reliable and secure. We pick programming languages like PHP and C++ where we know we're going to make errors we're never going to be able to debug, and often will be completely unaware of until they strike, because meh who cares I can write in {insecure language} and I like it so sucks to be users right? Besides I'm a genius and would never make those mistakes (yes you will, asshole.)
I refuse to read another ESR article on principle, he's a jack-ass, and I seriously doubt Go is going to be taking over from C any time soon, but I generally agree with the sentiment that we made a mistake going away from Java, back to languages that are optimized towards making errors. Java is too bureaucratic, and C# is nearly as bad, and while it's overstated I do generally agree that there needs to be more control over GC for the average programmer, but there has to be a happy medium here - better than Java doesn't have to mean insane type checkers and/or going back to directly manipulating pointers.
And yeah, I know C++ has smartpointers. But it also has regular old shit pointers. And sure, you would only use the latter in the right circumstances, but, let's be honest, all those other programmers you work with, who you are soooooo much smarter than, wouldn't...
You are not alone. This is not normal. None of this is normal.
All the domains where speed isn't the biggest deal and where reliability / uptime / portability / maintainability are more important. That's why languages like Java, .NET, Python, Ruby, JS have made headway.
So where C/C++ tended to be all-encompassing, they're now relegated to performance critical areas where until recently there wasn't much choice. Kernels, embedded, systems services, games. Places where performance and/or memory footprint were critical.
But even there choice is opening up. Rust in particular produces code, that is for all intents and purposes as fast as C/C++ but which tends to be safer, more portable and reliable. If you prefer to tradeoff some speed for programming niceties then you can go for Swift and Go too.
If I were writing software from scratch these days I definitely consider other languages before C++. I might reject them for reasons but C++ and C would be the bottom of the pile.
People who do electrical engineering learn to read and understand the funky symbols they use in electricity. We don't expect them to write out everything in plain English. It's the same with programming. Your Pascal-y pseudo-code took how much more space and time to convey no extra information? Your pseudo-code actually took longer for me to parse and understand than the C version.