I have been saying this for a more than a decade, but the number one thing that killed C++ as an attractive modern language is (the lack of) modules - the ability to include C++ code and libraries from others (perhaps with transitive dependencies), would allow an actual community of devs and companies spring up around the language.
Instead we have greybeards and lone warriors, and million-line legacy codebases, half of which have their own idea on what a string or a thread is.
” killed C++ as an attractive modern language”
I’m not sure were you got this perception that it’s dead.
C++ remains the only game in town in many domains.
That said, _unless you work in those domains_ there is no good reason to use C++ IMHO.
Apart from the legacy codebases, there’s lots of C++ greenfield development.
” the ability to include C++ code and libraries from others ”
Libraries in vcpkg - a large number - are compatible enough to be used in this sense. It’s possible your specific domain is lacking contributions or you’ve been looking from the wrong places?
> I’m not sure were you got this perception that it’s dead. > C++ remains the only game in town in many domains.
Yeah but not because people like the language but because there is no alternative.
At work almost every one of us devs doesn't enjoy working with C++ but since many dependencies in the embedded space are written in C++ you don't have much of a saying which language you choose. For example, Qt supports basically only C++.
Rust is the only mature contender in that space currently.
Yeah, a ‘module’ based system of various language is so much less efficient that it seems absurd to compare them for anything that actually requires that performance.
Honestly not sure what you mean by that - in C#, for example it doesn't matter to the compiler where the code comes from, it can be JITed/inlined just the same even if its coming from a different dll.
I haven't seen any perf impact of splitting stuff between files/js modules in typescript either.
What I'm guessing is that you mean that static compilers, like that of C++, need to be able to 'see' large amounts of code to make clever inlining optimizations.
Which shouldn't be the case if the code is well designed, and/or the compiler can prove invariants necessary for optimization without having to look at the body of the code.
Modules could be better, the problem are some greybeards and lone warriors (thankfully not all), that insist using C++ as it was plain old C.
Basically, it is no different than renaming .js to .ts to take advantage of some stuff in Visual Studio Code, while keep writing plain old JavaScript.
I have seen a lot of C++ code that has a lot of "this is clearly just C" in it. None of it is because of "greybeards and lone warriors". All of it was because it started as a C codebase, and sometime in the mid to late 90s when object-oriented fever swept the world they started just adding C++ on top of the existing C codebase.
Given that the general industry approach to technical debt is "yes, more please", it is unsurprising to me that any sufficiently old C++ project still has lots and lots of plain C inside it.
There's also a ton of landmark tutorials out there which taught generations of coders how to write C++ before "modern C++", and are still the top tutorials you find when you look them up. Plus I see C libraries more commonly than C++, so you end up dealing with raw pointers despite your better efforts
I think the struggle with modules has much more to do with the complexity of the problem at hand. I think the solution looks very easy should one be willing to dispense with large parts of the ecosystem. But if your goal is to keep the ecosystem together and not break the world (ala python 2/3 or perl5/6) and solve the problem at hand (waves vaguely at modules) - then its a really hard problem.
I wish I could say modules don't work, but I have yet to understand them. Which is probably a big part of its problem.
All my hobby coding in C++ makes use of modules.
Visual C++ and clang, alongside MSBuild and CMake/ninja.
As for ecosystem fragmentation, it has been the same old story since WG14 and WG21 exist, each compiler and platform is their own snowflake of what they actually support.
> All my hobby coding in C++ makes use of modules.
Do you have an example (of yours or others) that you could link?
I've been trying to get this up and running myself, but can't seem to whisper the right CMake prayers.
Stop using python 3 as an example. It is really tiring to hear about an extreme case of gross incompetence over and over again, while over in say the Grails/Spring ecosystem I don't even bother upgrading Grails 3 or 4 Plugins to Grails 6, because they still work as intended. When you upgrade a plugin from one version to the next, you're just swapping out build.gradle, gradle wrapper and a bunch of ancillary properties files. The build system changes, but everything else stays the same with only a tiny tiny minority of plugins being affected and even then the things that broke are absolute nonissues that can be fixed relatively quickly.
It is kind of interesting how the python community hasn't learned a thing from python 2/3. The problem isn't breaking backwards compatiblity. Probably the biggest mistake you can do is act like breaking backwards compatiblity is a big deal, therefore you should pile up as many breaking changes as possible and release them all at once so as to maximize pushback and upgrade friction.
It is in fact the exact opposite. If you break 10 libraries out of a million, you as the language developer can step in and upgrade them on behalf of the original maintainer. The users increment a library version when they increment the language version and done.
Python3 is a great example. They looked at what others had done. They carefully thought about the problem. They build tools to migrate. They announced plans. They really thought they had found a better answer that would work out because they had planned for everything.
Of course we are now looking at things in hindsight and see what didn't work.
It's really important to be clear about the lessons to be learned from Python 3.
1. Forward compatibility is more important than backward compatibility. 2. Automated refactoring tools don't help with 1.
The problem wasn't that they broke a lot in Python 3. It was that you couldn't write your Python 2 in such a way as to be compatible with it until well into the transition process as the six package got popular and the devs fixed needlessly broken things in Python 2.
I would suggest languages facing the same problem learn from Perl 5's success, rather than the various failures of Python 3.
Every† minor point release of Perl 5 creates backward-incompatible changes. These can be opted into individually, or on a per-file basis by simply specifying the version of Perl used. It all works. Differently-versioned Perl code can call each other as much as it likes.
There was never any reason why Python 3 needed to be anything other than Python 2 with this at the top of the file:
use Python 3.n
For various values of `n`. Perhaps when enough time passes, that's just Python now, and you have to copy-paste this into all the legacy code: use Python 2
That's it. Any language can do this, they just have to decide not to make life hard for everyone.[†] Perhaps not literally every, but it may as well be.
There are many options with pros and cons. Python was aware of them. They made what looked like a reasonable decision to take a different paths. On hindsight we know of the problems but you could not predict them with confidence in advance. (some may have predicted it but they would admit to guessing if they are honest)
Sure, not interested in changing the past, for many reasons not least of which is that it appears to be impossible. The Python team surely did not go in to Python 3 blindly, but they botched it anyway.
What I mean to say is that Python as a negative example only goes so far, because an example of failure isn't a template for success. So "don't do what Python did" carries limited value for a language looking to make breaking changes. For a language looking to make a major point release, that's the future, and the future can be changed; this is what I'm interested in here.
"Do what Perl 5 did" (and do not do what Perl 6 did, up to the point it got renamed) is a great place to start, however, because it worked, works, is working. Languages are different enough that it isn't a completely transferable experience, but there's a lot to learn there.
Vcpkg has really improved the experience of linking 3rd party dependencies for me