5 ms·
I'm glad for this article. C++ has been my main language for a very long time, but I've been a grumpy skeptic of C++ since around C++14 due to the language spe
by CoastalCoder 3y ago
I'm glad for this article.
C++ has been my main language for a very long time, but I've been a grumpy skeptic of C++ since around C++14 due to the language spec's total complexity. So I've mostly stuck with C++11.
But now that C++ has modules, concepts, etc., I'm starting to wonder if C++23 is worthwhile for new projects. I.e., the language-spec complexity is still there, but the new features might tip the balance.
I'd been thinking to walk away from C++ in favor of Rust for new projects. But now I might give C++23 a chance to prove itself.
- ajross 3y agoReally the cognitive load of modern Rust is no less than C++$RECENT in my experience. Both require a ton of prima-facie concepts before you can productively read code from other developers. Of en vogue languages, Zig is the only one that seems to view keeping the "metaphor flood" under control as a design goal, we'll see how things evolve. But really, and I say this from the perspective of someone in the embedded world who still does most of his serious work in C and cares about code generation and linkage: I think the whole concept of these Extremely Heavy Systems Programming Languages is not long for this world. In modern systems, managed runtimes a-la Go/Swift/JVM/.NET and glue via crufty type-light environments like Python and Javascript are absolutely where the world has ended up. And I increasingly get the feeling that those of us left arguing over which monstrosity to use in our shrinking domain are... kinda becoming the joke.
- pjmlp 3y agoActually if you look back to 8 and 16 bit home computers, with C, C++, Object Pascal, BASIC, Modula-2, full of inline Assembly, in many cases that being the biggest code surface, it is quite similar. Nowadays C and C++ took the role of that inline Assembly, with higher level systems languages taking over the role of the former.
- ajross 3y agoSure. The point was more that Big System Engineering (in any particular domain, frankly including things like OS kernels), going forward, just won't be happening much in Rust or C++. And languages that large make for very poor "inline assembly", where C obviously does quite well and Zig seems to have a reasonable shot. I mean, literally yesterday I had to stop and write a "device driver" (an MMIO firmware loader for an on board microcontroller) in Python by mapping /dev/mem. That's the kind of interface and development metaphor we'll be seeing in the longer term: kernel driver and interface responsibilities will shrink (they are already) in favor of component design done in pedestrian languages like Go or whatever that mere mortals will understand. There's no market for a big C++ or Rust kernel framework.
- jamil7 3y agoI don't write embedded software, but I see Rust breaking into many domains outside of systems and winning developer mind share everywhere. Seemingly fulfilling its promise of being able to target low-level and higher-level software domains (something Chris Lattner wanted for Swift, but it hasn't yet materialised on the low-level side, we'll see).
- synergy20 3y agoI'm in doubt of this statement, Rust is here for 17 years, its market share is less than 1% still(per google). It does have a lot of developers saying good words for it whenever there is a chance in recent few years, but the reality is that, it's hard for most developers to learn, because of that it might remain to be a niche language for system programming. c++ is not standing still, I feel since c++20 it becomes a really interesting modern language, and I hope its memory safety concern will be addressed over time at a faster pace, in fact if you use rule-of-zero, RAII, smart pointers etc correctly your code can be very much memory-safe already.
- gonzus 3y agoAccording to Wikipedia, Rust appeared for the first time on May 15, 2015; 8 years ago.
- CoreyFieldens 3y agoThat was the release date of Rust 1.0. Not the first appearance.
- the_duke 3y agoRust was a very different language pre 1.0 (GC, builtin green threading, etc). I think it's fair to start counting at 1.0.
- dureuill 3y ago> It does have a lot of developers saying good words for it whenever there is a chance in recent few years, but the reality is that, it's hard for most developers to learn, because of that it might remain to be a niche language for system programming. On what basis is this "reality" based? Recent survey of 1000 developers by Google denotes "[the] ramp-up numbers are in line with the time we’ve seen for developers to adopt other languages"[1] > in fact if you use rule-of-zero, RAII, smart pointers etc correctly your code can be very much memory-safe already. That's not what memory safe means. Memory safe means that even if you make a mistake, you cannot get a memory error, something that is true of Rust minus the `unsafe` superset. Even with what you describe, you can trivially get UB on C++ if you: keep a reference to an object, use a smart pointer after move (something that the compiler will not warn against), call .front on an empty vector, dereference an iterator that got invalidated by pushing in your vector, use a non thread-safe object in a multithreaded context. Rust will statically prevent a memory error from occurring in any of these situations. If you're cautious, you may not get memory errors in a C++, but that's not "memory safe". Also, as a C++ developer turned Rust developer, C++20 does nothing to capture my interest back. The module system is atrocious (orthogonality between modules and namespace, way too complex for what it wants to achieve, module partitions seriously?, poor tool support 3 years after the standard was published), there are no ergonomic sum types and pattern matching, no standard package manager (and the legacy compilation model based on textual inclusion makes build system more complex than they could be), no improvements on thread safety in sight (to be fair, you pretty much need your language to feature a borrow checker and be built around thread safety, it cannot be bolted on). I have little hope C++ is in capacity of addressing these issues in the next 6 years. [1]: https://opensource.googleblog.com/2023/06/rust-fact-vs-fiction-5-insights-from-googles-rust-journey-2022.html https://opensource.googleblog.com/2023/06/rust-fact-vs-ficti...
- spoiler 3y ago> Really the cognitive load of modern Rust is no less than C++$RECENT in my experience. Both require a ton of prima-facie concepts before you can productively read code from other developers. Eh. I don't know if I agree. I've worked on a few large C++ codebases, and the cognitive load between Rust and C++ is incomparable. The ownership/borrowing stuff is complexity you deal with implicitly in other systems languages, here's it's just more explicit and semi-automated most of the time by the compiler. In C++ the terse thing is never the correct thing. If I'm using metaphors: a Rust sentence, in C++ usually has to be expressed through one or more paragraphs. The type system is so loose you have to do "mental" expansions half the time (or run the build and pray for no errors, or at the very least that the error is somewhat comprehensible[1]). There's some low-level stuff that can be ugly (for various definitions of ugly), but that's every language. The low level bits of async are a bit wired, but once the concepts "click" it becomes fairly intuitive. At least the ugly parts are cordoned behind library code for the most part, and rarely leak out. I guess it could just boil down to familiarity, but it took me much less time to familiarise myself with Rust than it took me to familiarise myself with C++. We're talking months vs years to consider myself comfortable/adept at it. Although, maybe just some C++ or general programming wisdom transferred over? [1]: This happens in Rust too, I must admit. But it's usually an odd situation that I've encountered once or twice with some very exotic types. In C++ it's the norm, and usually also reported with bizarre provenance
- deleted 3y ago[deleted]
- tazjin 3y agoC++ errors are so bizarre that most of the time I use the compilation result as a simple binary value. Some part of one's mental neural network learns how to locate many errors simply through a "it doesn't work" signal.
- aseipp 3y agoIMO the cognitive load of Rust is different in practice just from basic nuts and bolts things like having a ecosystem of libraries that culturally emphasizes things like portability and heavy testing, and a standard package manager and an existent module system (C++26 fingers crossed). I dislike Cargo but it's incredibly effective in the sense any Rust programmer can pick up another project and almost all of of the tools instantly work with no change. I mean, Rust is frankly most popular in the same space Go/Swift et cetera are, services and application layer programming, where those conveniences aren't taken for granted. I see it used way more for web services and desktop/application services/command line/middleware libraries than I do for, like, device drivers or embedded kernels. Those are limited enough in number anyway. Really, the ergonomics of both the language features and standard tooling meant it always meant it was going to appeal to people and go places C++ would not, even if they in theory are both "systems languages" with large surface areas, and they overlap at this extreme end (kernels/embedded/firmware/etc) of the spectrum that little else fits into.
- nunuvit 3y agoI think the future of these languages is largely as a target for code generation and transformation. Their legacy tooling-unfriendly designs is what's slowing this transition.
- jb1991 3y agoMost serious C++ developers will tell you that C++14 was basically a bug fix for some oversight in the C++11 spec. You should probably use it if you can if that’s the standard you’re happy with.
- poly_morphis 3y agoC++ 17 is the sweet spot for me. It has most of C++ 11/14, with many new features I use a ton: constexpr, <charconv>, <string_view>, [[maybe_unused]], new SFINAE feature (if constexpr), and more. (And this was considered a small release!?) I guess I’m just right at home and therefore a bit reluctant to jump into C++20. That and the constantly changing “””correct way of doing things.”””
- jeffbee 3y agoIf you use SFINAE that alone is reason to move to C++20, to get concepts instead.
- pjmlp 3y agoI get the same feeling regarding many features on C#, F#, Java, Python, Typescript, Scala, Kotlin, Swift. Don't forget it isn't only the language, the various implementations, standard library, breaking changes, and major 3rd party libraries. So I embrace complexity, as the alternative is being stuck with something like Go.
- corysama 3y agoC++ deserves its rep for complexity. But, it comes from a promise to avoid a version upgrade debacle in the style of Python 3. C++ promises that you will forever be able to interleave new-style code right into the middle of ancient, battle-tested old-style code. To do that, it can only add features and never take them away. Instead, it adds features that deprecate the practice of PITA patterns that were common, necessary and difficult. Like, SFINAE was necessary all over the place to make libraries "just work" the way users would expect. But, it is a PITA to write and and PITA to read. Now, constexpr if and auto return types can usually collapse all that scattered, implicit, templated pattern matching down to a few if statements. Adding those features technically made the standard more complicated. But, it made new code moving forward much simpler to understand. Similarly: Before variadic templates, parameter packs and fold expressions, you had the hell of recursive templates. Auto lambdas make a lot of 1-off templates blend right into the middle of regular code. Deduction guides set up library writers to set you up to write std::array names{"Alice", "Bob", "Charlie}; instead of std::array<const char*, 2> names{"Alice", "Bob", "Charlie};
- munificent 3y ago> But, it comes from a promise to avoid a version upgrade debacle in the style of Python 3. There is a very wide middle ground between C++'s "Your horrific unsafe code from the 80s still compiles" and Python's "We changed the integer values common operations on strings return at runtime with absolutely no way to statically tell how to migrate the code". In Dart, we moved to a sound static type system in 2.0, moved to non-nullable types in 2.13 (sound and defaulting to non-nullable!), and removed support for the pre-null safety type system in 3.0. We brought almost the entire ecosystem with us. Granted, our userbase is much smaller than C++'s and the average age of a given Dart codebase is much younger. But you can deprecate and remove old features without causing a decade of misery like Python did. You just need good language support for knowing which version of the language a given file is targeting, good static typing support, and good automated migration tooling. None of those is rocket science.
- plonk 3y ago> But you can deprecate and remove old features without causing a decade of misery like Python did. You just need good language support for knowing which version of the language a given file is targeting, good static typing support, and good automated migration tooling. None of those is rocket science. That's way easier to do in a naturally statically-typed language though.
- deleted 3y ago[deleted]
- constantcrying 3y ago>I'd been thinking to walk away from C++ in favor of Rust for new projects. But now I might give C++23 a chance to prove itself. Modules were a great step forward for C++, but one of the features I enjoy the most about Rust is that adding a library just works. Especially for single person projects, which are on the smaller side, it feels absolutely great having to do near zero build management.
- Koshkin 3y agoIt's either the complex language or the complex code.