Herb Sutter CppCon 2022 Cpp2

https://www.youtube.com/watch?v=ELeZAKCN4tY

I have been watching this video, Herb seems to have a genius idea IMO.

The video is long but is worth watching the whole thing to see what his motivation and vision is for his experiment.

Maybe this could be a game changer, near the end is a whole page of things he won't need to teach anymore, and these things will improve the stability and quality of C++ programs.

And although the syntax is different, the output is normal C++ code as we know it today, just like what Bjarne did with the beginning of C++.
It's c++ but not as we know it...

https://github.com/hsutter/cppfront
I'm doubtful about C++'s future and, by extension, this project, ultimately because the past five years' major language features have not improved my code.
- Modules aren't supported and aren't supposed to address any problem that I struggle with;
- Coroutines could be great but they lack support so nobody is using them;
- The ranges library is more verbose, complicated, and (often) slower than the library it re-implements for no reason, and
- Concepts are so frequently abused that they often end up worsening productivity.

These features are complicated and have little or no impact on my products. Simultaneously they make the language harder to learn, teach, and use; they're sometimes annoying and rarely helpful.

I encountered something like this recently:
auto square(arithmetic auto const& x) { return x * x; }
This over-constrained function blew up inside a third-party library when I tried to compute an inner product (of vectors). It's really representative of my recent experience with C++; a piece of code that does nothing, besides force me to work-around its presence.

Part of the reason I haven't moved on already is because I can basically continue to write C++14, trying to avoid overbuilt libraries and half-baked features. Another is that I'm emotionally invested in C++'s success after studying how to use it for years and years (I expect many of us feel the same). My question is whether myself, Herb, and users of cppfront might be victims of the sunk cost fallacy. If it is time to move to another tool, why move to one that is still connected to C++? What advantages might cppfront have over greenfield alternatives?

That being said, I'm willing to try the tool. Maybe I can write a small project using it this weekend. If I get around to it, I'll report back.
Last edited on
mbozzi wrote:
I'm doubtful about C++'s future and, by extension, this project, ultimately because the past five years' major language features have not improved my code.


I am not sure if that means you have watched the video? Herb did some detailed analysis of what causes problems in C++, and found that 23% of the bugs were due to initialisation and parameter passing. Cppfront addresses these problems. Also, it is only an experiment so far, I wonder what other problems Cppfront may be able to fix in the future? I mentioned in my earlier post that: in the video, near the end there is a whole list of things that Herb would not need to teach anymore. He is trying to make C++ simpler and much safer by generalising, which relates to a comment that Bjarne made. In general I think Cppfront is heading off in a bold new direction to improve things, as opposed to just adding stuff to C++.

mbozzi wrote:
- Modules aren't supported and aren't supposed to address any problem that I struggle with;


I did a post about that. They are supported with clang++ 23, and still a bit fiddly with g++, but you are right it's not universal nor complete support yet. In Cppfront import std; is implicit. I guess modules would be helpful to those folks who have really long build times, I have heard stories about build times of 12 hours or more. I wonder how much build times would go down for g++ and clang++ themselves* if they used modules throughout? * I find myself building g++ or clang++ from scratch about once per year when I want to try something in the very latest version.

mbozzi wrote:

What advantages might cppfront have over greenfield alternatives?


Herb did mention that he wasn't trying to create a new language. And that his philosophy was similar to Bjarne's: Bjarne's cfront emitted C code for the first 10 years of C++; Cppfront emits C++ code. And there are about 7 million C++ users globally. The other idea was that all of the existing C++ stuff can be used, rather than start from scratch with a brand new language. It also seems to me the big difference it the syntax of Cppfront comes from the Universal Function Call Syntax (UFCS)

Attempts have been made to "fix" C++, notably D lang. But I gather that hasn't had as much uptake as it could of had because of the competing libraries and lack of tool support.

mbozzi wrote:
That being said, I'm willing to try the tool. Maybe I can write a small project using it this weekend. If I get around to it, I'll report back.


Great I hope it goes well :+)

My question is: I wonder what other members of the C++ committee think of it?
I am not sure if that means you have watched the video?

Yeah, I watched it yesterday before I posted.

I'm very confident cppfront can offer improvements. But my intuition is that these improvements could be more dramatic if C++ was abandoned as a foundation language.

cfront emitted C code for the first 10 years of C++; cppfront emits C++ code.

C++'s relationship to C is double-edged. cfront's nature as a preprocessor was surely one of the major reasons why C++ became a popular success. Unfortunately carrying C's legacy also created huge technical challenges.

I'm unconvinced that cppfront's relationship to C++ could be much different.
Last edited on
This over-constrained function


Yeah - the coder hadn't considered that the function could be called for an object that provided a * operator. Unless other overloads are provided for performance reasons, without the constraint the code would still fail to compile if the * operator couldn't be resolved. So I don't really see the advantage of even trying a constraint here - especially as it's part of a library. Black mark for them!

Just because you can, doesn't mean you should...
Last edited on
Maybe it's just me, but I don't think template error messages are a problem that needed addressing. Nearly 100% of the time you can find the source of an error by locating the deepest point in the error stack that points to your own code, without even reading the message. And it feels like concept-like features are always the worst part of any language that has them. Traits in Rust are a gigantic pain (and their errors are IMO even more incomprehensible than template errors); where clauses in C# are so annoying that every time I need them in generic methods I remember how nice templates are to write because they're duck-typed, and sometimes I just give up and write the method non-generically.

Rather than concepts, how about a networking header for the standard library? Hey, committee, networks are no less relevant today than they were in 1998, and I don't think they're going to become less relevant if you wait another 25 years.

- Coroutines could be great but they lack support so nobody is using them;
I just use Boost's implementation

C++'s relationship to C is double-edged. cfront's nature as a preprocessor was surely one of the major reasons why C++ became a popular success. Unfortunately carrying C's legacy also created huge technical challenges.
Although this is true, it's unrelated to C++ originally compiling to C. Plenty of modern languages use C as an IR primarily to avoid having to implement a full compiler backend. That a compiler emits another high-level language rather than machine language tells you nothing about how interoperable the source language and the output language will be.

All I want from a hypothetical C++ successor is:
* It must have just as good a tool ecosystem. I'm tired of languages with no debuggers and IDEs that crap out parsing sources. GFYS, rust-analyze.
* It must have a stable compiler/runtime. If it compiles with no errors or warnings today, it should also do so 20 years from now; compiler flags are a reasonable compromise to support this. Pulling a Python 3 is unacceptable. If it needs a runtime, I should not have to tie the project to this month's version, that's going to be deprecated next month. I'm looking at you, C#.
Nice to haves:
* Easier and faster to parse. Nice just in general, but also when you're working on source processors.
* Less undefined behavior, or the ability to require defined behavior in specific regions with the understanding that it may lead to worse optimizations. Both C and C++ have far too many landmines that are too easy to step on.
* Bounds checking turned on by default, with individual checks being omittable by the compiler. Even nicer: pointer arithmetic forbidden; all accesses must be through pointers of defined sizes. Corollary: address-of operator doesn't exist.
1
2
3
4
5
6
7
int int_vector.get(int index){
    auto p = (int[this.size] *)this.data;
    //Now the compiler knows how to generate the bounds check.
    //The programmer must still take care not to do anything
    //that could cause the size of this.data to change.
    return p[index];
}
I don't think template error messages are a problem that needed addressing.

The main purpose of concepts was never to improve error messages, even though that garnered lots of attention for some reason.

Concepts specify the requirements imposed on types put into templates. Without concepts, a library might informally require (in the docs) that some function template needs a random access iterator. If you pass a different kind of iterator in, your code might work fine (thanks to duck typing) until the template's implementation changes - at which point it might fail to compile, blow up at runtime, or its asymptotic complexity might change for the worse. Concepts are a tool to avoid this kind of issue, by forcing you to pass in a type with the properties the interface expects.

I reserve the use of concepts for API boundaries because
1. duck typing is enough for most one-shot/narrowly-used/internal code, and
2. concepts aren't much help to the author of the template's definition.
I'd love it if concepts helped the compiler detect under-constrained definitions. For example
1
2
3
template <typename T> 
    requires requires(T t) { t + t; } // did I get the syntax right this time?
  void f(T t) { t / t; }

The problem is that f assumes that t / t compiles, even though we only checked for t + t.
A type that has t + t but not t / t will cause this template to blow up at point of use. But ideally the template just would be rejected immediately. I believe Rust gets this right.
This feature would make concepts essential for all generic programming because of how ludicrously easy it is to make this kind of mistake, particularly in C++.

See also the "Good Concepts" paper by Stroustrup and "Elements of Programming" by Stepanov & McJones:
https://www.stroustrup.com/good_concepts.pdf
http://elementsofprogramming.com/

> C++'s relationship to C is double-edged.
> cfront's nature as a preprocessor was surely
> one of the major reasons why C++ became a popular
> success. Unfortunately carrying C's legacy also
> created huge technical challenges.
Although this is true, it's unrelated to C++ originally compiling to C. Plenty of modern languages use C as an IR primarily to avoid having to implement a full compiler backend. That a compiler emits another high-level language rather than machine language tells you nothing about how interoperable the source language and the output language will be.

In general I'd agree but here cfront implemented a C dialect & cppfront implements a C++ dialect. Therefore cfront carried C's problems forward and perhaps cppfront will carry C++'s problems forward too.

I'm not sure about big an issue this might be, but there are inherent issues with C and C++ (within the definition of its object model, for example, or provenance) that I suppose any language dialect would be hard-pressed to avoid.
Last edited on
The main purpose of concepts was never to improve error messages, even though that garnered lots of attention for some reason.
The very first thing I read about concepts back when C++11 was still called C++09 was that their purpose was to provide an early check that the template argument being passed to an instantiation provided the interfaces the template needed, because otherwise the check would be performed implicitly by some code deep in the template that uses the missing facility and the compiler would spit a gigantic error message.
Now, it's possible that one might want to check that besides the argument providing the right interface, it also provides the right semantics on that interface, and that can't be checked by templates. However, that's exactly what square() above does:
 
auto square(arithmetic auto const& x) { return x * x; }
For whatever reason, the designer requires that x must have the semantics of a number and not just anything that just happens to have an operator*().

If you pass a different kind of iterator in, your code might work fine (thanks to duck typing) until the template's implementation changes - at which point it might fail to compile, blow up at runtime, or its asymptotic complexity might change for the worse.
Not a great example. Iterators can be distinguished by the operators they provide. Sequential iterators don't provide operator[]().

In general I'd agree but here cfront implemented a C dialect & cppfront implements a C++ dialect. Therefore cfront carried C's problems forward and perhaps cppfront will carry C++'s problems forward too.
Is Cpp2 intended to be a superset of C++ like C++ originally was of C? If that's the case I agree with you and I'll add that that's pretty insane, but I thought the point of making a clean break was removing undesirable features. I don't think Cpp2 can be called a "dialect" of C++ if it merely shares some design goals and otherwise their syntaxes and semantics are incompatible.
Not a great example. Iterators can be distinguished by the operators they provide. Sequential iterators don't provide operator[]().

You probably mean operator+ not operator[] but I understand the point. For example std::string::iterator is random access but it isn't necessarily a pointer and might not have operator[].

There are standard library functions whose time complexity depends on the kind of iterator passed in, partition_point for example.
https://en.cppreference.com/w/cpp/algorithm/partition_point

If some generic code depends on partition_point using logarithmic time it might be important to require that the right kind of iterators are involved.

Is Cpp2 intended to be a superset of C++ like C++ originally was of C?


Herb kept saying he wasn't trying to create a new language, but rather trying to explore what C++ could evolve to be if it wasn't constrained by syntax compatibility. There are features removed from the new syntax. For example you can't say "union" in the new syntax - but you can say "std::variant", which is obviously a union inside.

The idea is that you can't make mistakes with unions as long as you stick to the "new" syntax.
Oh... He wants to mix C++ and Cpp2 source in the same file... Well, there are ways that it can not become a compatibility monster, but given that it compiles to C++ and thus interop should be trivial, I really don't see the point. It sounds like a stupid idea to me.
After watching the talk, I gotta say, I'm pretty positive about it. I've never been too keen on name: type sort of syntaxes, but it does make it nicely consistent, and I've heard it makes parsing simpler. I really like how simple parameter passing is, although I kinda feel it could be simpler still. I'm not sure how a forward parameter works, and I feel like the responsibilities of move parameters could be absorbed by some of the other ones. In fact I left a suggestion in an issue to that effect.
All in all, I think this is a good direction for C++'s evolution. I can't wait to see how classes turn out.
Reminds me of the never-to-be-released "Jai" language by Jonathan Blow.
(At least, superficially with the name : type syntax)
Last edited on
Did Jon Blow give up on his project?
Haven't been keeping up on it much, but I would assume not. He's developing a game using the language, so I assume the game will be finished before the language :)
Topic archived. No new replies allowed.