Hacker News new | ask | show | jobs
by Aardwolf 814 days ago
Unfortunately the first example already re-uses one of the less good parts of C++, the "<<" operator for std::cout, which always was a bit of a hack (including strange order of operations since << normally is left shift)
4 comments

I've always thought that using "<<" in that manner was more of a way to show off the operator overloading feature than anything else.
I think the original point was to make a typesafe printf that's still reasonably efficient without creating a bunch of small temporary strings. Like, if you printf like this:

    printf("Number %d, String %s", n, s);
but the types of n and s aren't int and char*, all hell breaks loose and you have the origin of a million CVEs. But how do you make that function signature typesafe, without the tools of modern templates? You sort of can't. One thing you can do is do string append stuff, but the syntax then is annoying:

    print("Number " + to_string(n) + ", String " + s);
This also creates a bunch of temporary strings, which is not ideal (and still relies on operator overloading, btw). In this world, using operators for this does make some sense:

    std::cout << "Number: " << n << ", String " << s;
Like, seen from this perspective, it's not the worst idea in the world, it does work nicely. The syntax really isn't too bad, IMHO (the statefulness part, though, really sucks). It also allows you to add formatting for your own types: just overload operator<<!

Clearly, properly type-safe std::format is vastly superior, but the C++ of the 90s simply didn't have the template machinery to make that part of the standard library.

It would have been possible to, as a special case, type check the formatting, C compilers began doing that in the 1990s IIRC.
And there are ways of signaling to a compiler that your function accepts a format string and a series of typed arguments in case you're wrapping a C-style printf function.
It wouldn’t have added support for custom types to printf(), which was an important motivation.
That's true, however neither the mechanism to do this in I/O streams, nor the weighty mechanism for std::format come close to what Rust's derive macro offers for Debug, and in my experience asking for so much means you often won't get anything because programmers are lazy.

That is, for a custom type in Rust having rudimentary Debug output is one word added to the list of derive macros, the word "Debug". Almost everybody will write that, it's barely effort.

To get that in C++ I/O Streams you need to write an operator overload function and must be careful to write it correctly. Trivial types usually don't bother, but many C++ programmers are comfortable writing this for an important type.

For std::format you need to write a template which is already pretty scary, and then it needs to implement custom parse and format steps, this is because std::format allows your custom type to define its own custom formatting rules. This is extremely powerful, but everybody must pay for this power. I have not seen most people bother doing all this at all.

You can write operator<< as a free (non-member) function yourself for classes that don’t implement it. Furthermore, it’s not necessarily the same output that you want for debugging.
Don't you think it just serves to highlight that Cpp2 is just C++? That it's explicitly not some new language with C++ FFI like Carbon.
Not sure what is meant by this statement. Both cpp2 and Carbon are different languages, neither of them claim to be just C++.

Both languages will have bidirectional compatibility with C++ so that code written in C++ can be directly accessed from Carbon and code written in Carbon can be directly accessed from C++. Neither of them use an FFI for compatibility.

It's my understanding that Carbon will create wrapper Carbon classes around C++ classes and convert data back and forth between C++ types and Carbon types at the interface boundary when necessary.
Yep, that's the plan.
Not really, Herb Sutter tries to sell cpp2 as "Typescript for C++", or "Kotlin for C++", while ignoring that Typescript doesn't add anything to JavaScript besides types, they did some mistakes on the early days not following up on this, but backtracked and now Typescript is basically a linter/transpiler.

Whereas while Kotlin used the Java ecosystem to bootstrap itself, it is clear that by now JetBrains rather wants to build their own Kotlin ecosystem, just like C++ and Objective-C took their own path after being plain translators into C.

Objective-C++ does exist, so their paths didn't diverge so much that they didn't remain in each others' ecosystems on a permanent basis (on Apple, which is the only place both regularly intersected)
I kinda like it, it's comfortable and pragmatic. I don't have to look at the docs to figure out what's the format specifier for something like a size_t, and you can easily add support for whatever might be needed, so you can comfortably do:

   std::cout << "Player is at" << _player_pos;
And get the x/y/z breakdown automatically.
But you can do that with fmtlib/std::format as well when you provide formatting for custom types, that just becomes:

    fmt::println("Player is at {}", _player_pos);
Should be possible to implement cout more effectively since there is no string parsing. I say “should” because in practice it seems to be the other way around. I don’t know why.
Been a while since I've looked at it, but pretty sure std::format validates and parses most (all?) format strings at compile time. There should be no runtime penalty.
There are some fundamental reasons why cout is slower than stdio/{fmt}: https://stackoverflow.com/a/65325727/471164.
And now try to do task which should be as trivial as add 1 format character: output number in hexadecimal and leave stream in same state that was before your code.

It becomes cumbersome very fast.

Note that the "<<" operator for std::cout is not related to the language itself but related to the standard library.
But in a "C++ 2" helloworld one would really expect to see std::println used instead [1].

[1] https://en.cppreference.com/w/cpp/io/println

Cpp2 is part of the trend for would be "C++ Successor languages" from 2022. The std::println function was standardised in C++ 23, and implementations still don't all provide it in full today.

So in effect Cpp2 pre-dates std::println. Herb will have been aware that it exists and is likely for C++ 23, but it doesn't make sense to ship software which requires features you suspect won't be widely available for several years. A "Hello, world" program should not be relying on bleeding edge features.