I also agree that the new features seem to embrace and extend the "footgun-ness" of C++, rather than attempt to fix it.
I also agree that the new features seem to embrace and extend the "footgun-ness" of C++, rather than attempt to fix it.
That's much easier to do when the tasks that the language is suitable for are bounded in some way.
There are not many common idioms that are going to be shared (beyong libstdc++) between a realtime audio processing application and a data visualization backend for the web and an embedded system control app and a payroll processing backend.
An example of a language with a smaller domain which makes its idioms obvious through its design is Ruby.
An example of a high-performance language that can be used for all those things that makes its idioms obvious through its design is Rust. Another would be, imo, C.
> There are not many common idioms that are going to be shared (beyong libstdc++) between a realtime audio processing application and a data visualization backend for the web and an embedded system control app and a payroll processing backend.
I also just generally have to disagree with it, but you seem to be using a different definition of idiom to me. From what you said here, you seem to take idiom to be synonymous with "design decision". For me, an idiom is a specific semantic construct, possibly associated with specific syntax, that achieves a specific basic programming task. For example, the idiomatic way to loop with an index in Python is to use enumerate.
It's merely the way that most people do the basic things, in a way that is actually good to do. C++ is infamous for a huge number of people using the language dangerously, to the point where there are effectively no idioms outside of specialist communities, and to find them out you need to read books. A significant amount of the basic design of the language needs to be ignored for most purposes.
While I wouldn't say no to having such idioms available in C++ as language constructs, it is important that C++ continues to provide the lowest level that it can for such tasks (e.g. pointers into arrays or other buffers), and probably the level right above that (libstdc++).
Similarly for threads (or more generally, parallel and asynchronous programming) - some other languages make available some really nice idioms for expressing these things, but again it is important for performance and control reasons that C++ continues to provide the current lowest level of access for this (basically a wrapper around pthreads). While things like promises, futures and coprocessing are really useful, they are often inappropriate for highly performant code.
One of the sources of complexity in the C++ I work with is that a lot of it is using templates to try to maximize the size of individual expressions. Consider, for example, the Eigen library (https://eigen.tuxfamily.org/index.php), which gains most of its magic in using compile-time template specialization to re-group logical operations so that the compiler can realize "Oh, this is really looping over dozens of memory cells to do the same operation... I should compile it using SSE instructions." I haven't seen yet whether / how Rust pulls off similar tricks or whether doing so in Rust requires a developer to write n-ary asm bindings, which would actually make Rust less expressive than C++ if the goal is maximizing performance with minimum code.
(Of course, the flip side of that is that there's a lot of Eigen that's unsafe behavior; hold the library slightly wrong, and you're operating on deallocated memory. Oops. ;) ).
I don't have the impression that Rust's container idioms match those of, say, Python, but I may just not know Rust well enough.
E.g. https://github.com/glium/glium
Rust would be useless if you couldn’t have safety if you had any unsafe at any point. That’s the whole point of rust: you can build safe interfaces to unsafe actions