[HN Gopher] Overview: What are Cpp2 and cppfront? How do I get a...
       ___________________________________________________________________
        
       Overview: What are Cpp2 and cppfront? How do I get and build
       cppfront?
        
       Author : cyber1
       Score  : 183 points
       Date   : 2024-03-31 21:26 UTC (1 days ago)
        
 (HTM) web link (hsutter.github.io)
 (TXT) w3m dump (hsutter.github.io)
        
       | darknavi wrote:
       | I know some of the arguments around C++/cpp2 are flawed, but I do
       | love C++ and a project to move it forward with a step-change is
       | exciting to me.
       | 
       | A few of my friends and I did Advent of Code in cpp2 this year
       | and it was a (very buggy) blast.
        
         | Galanwe wrote:
         | > A few of my friends and I did Advent of Code in cpp2 this
         | year and it was a (very buggy) blast.
         | 
         | You mean buggy ironically because you were discovering cpp2, or
         | because cpp2 itself was buggy?
        
       | JNRowe wrote:
       | Sutter's 2022 cppcon talk1 is a _great_ introduction to the
       | topic, both the problems it attempts to solve and solutions it
       | was /is settling on. One of those few talks that left me
       | genuinely enthused about the topic.
       | 
       | [It is probably worth watching for the Compiler Explorer
       | interjection toward the end alone -- Matt Godbolt Appreciation
       | Society]
       | 
       | 1 https://www.youtube.com/watch?v=ELeZAKCN4tY
        
       | cies wrote:
       | Like Kotlin to Java
       | 
       | Or ReScript to OCaml
       | 
       | Or Gleam to Erlang
        
         | treyd wrote:
         | Kotlin is a distinct language with new features that (I'm
         | fairly sure) make it non-isomorphic to Java code though. But I
         | can't speak on the others.
        
           | simon_void wrote:
           | not sure what "(non)-isomorphic" but Kotlin code is
           | interoperable with Java code in both directions. You can
           | easily call Java-code from Kotlin (but I guess that's the
           | easy direction) but you can also call Kotlin code from Java.
           | There exist specific annotations to control how Kotlin code
           | will be converted to bytecode and therefore be invoked from
           | Java, e.g. a function in a Kotlin companion object would
           | normally concerted into a function of a Singleton property
           | called INSTANCE on the base class, but if you annotate it
           | with @JvmStatic it will become a static method of that class
           | in bytecode instead. This means you can write a Kotlin lib
           | that feels very normal to call from Java. here's the relevant
           | part of the documentation: https://kotlinlang.org/docs/java-
           | to-kotlin-interop.html So yes, Kotlin is considered to be a
           | successor language, not just another language (also)
           | compiling to the JVM.
        
             | treyd wrote:
             | An isomorphism is a structure preserving 1:1 map between
             | two sets or some other pair of structures. While Java and
             | Kotlin are interoperable (because they both target the
             | JVM), they are not isomorphic for precisely the reasons you
             | described. If it was, then you could do round trip machine
             | translation on the syntax in either direction and have a
             | result that's identical to the original. You can't do that
             | because Kotlin extends Java in nontrivial semantic ways
             | (for a concrete example, see Nothing in the article you
             | linked).
             | 
             | Cpp2 isn't trying to be a successor language to C++, the
             | article states that it's trying to present an identical
             | feature set in a new skin where the best practices of
             | modern C++ are more ergonomic without introducing any new
             | functionality.
        
               | tialaramex wrote:
               | > Cpp2 isn't trying to be a successor language to C++
               | 
               | Herb is trying to _sell_ it as not a successor because
               | for now that suits him better.
               | 
               | Because C++ is a general purpose language Herb can
               | deliver a "not a new feature" that is so elaborate in
               | practice you would never write the equivalent C++ by
               | hand, but Herb can insist that since technically it can
               | still be transpiled to C++ it's not a different
               | language... right up until that ceases to suit his
               | agenda.
               | 
               | Under this model WUFFS (a higher performance yet entirely
               | safe language for writing stuff like codecs and
               | compression algorithms) doesn't "introduce any new
               | functionality" compared to C, since the present WUFFS-
               | the-language is transpiled into C. But I think C
               | programmers would be astonished to hear that _C_ is now
               | apparently higher performance than C and is able to
               | guarantee it 's entirely safe...
        
               | treyd wrote:
               | The linked article explicitly states
               | 
               | > What it isn't. Cpp2 is not a successor or alternate
               | language [...]
        
               | tialaramex wrote:
               | That's correct, Herb Sutter does indeed claim that his
               | C++ Successor Language isn't a C++ Successor Language, as
               | I stated.
        
         | Cerium wrote:
         | Or, Cfront to C? :)
        
         | jokoon wrote:
         | or more famously, typescript to javascript, which is the
         | example Herb uses.
        
         | Zambyte wrote:
         | Surprised to see Gleam instead of Elixir, I haven't heard of
         | the former before.
        
         | zem wrote:
         | all of those compile to the respective languages' bytecodes,
         | not to source code
        
       | superamadeus wrote:
       | Is there any discussion or in-depth explanation of the syntax
       | choices? I understand that a goal was context free unambiguous
       | parsing. But there are some things that surprise me.
       | 
       | For example, string interpolation:                   "Hello,
       | (msg)$!\n"
       | 
       | Why "(msg)$" and not "$(msg)"? Surely the latter is easier to
       | parse?
        
         | jiripospisil wrote:
         | https://github.com/hsutter/cppfront/wiki/Design-note:-Captur...
        
           | loeg wrote:
           | Raises more questions honestly. This looks more different
           | from today's C++ than Rust.
        
             | epage wrote:
             | I feel like consistency goes too for losing the visual
             | parsing benefits of special syntax. Otherwise, we might as
             | well adopt lisp's syntax.
        
           | breatheoften wrote:
           | What does "for later use" mean?
           | 
           | One thing I've noticed recently is that pretty much no
           | language has a good way to simultaneously define a nested
           | structure and assign that structure a name "for later reuse".
           | 
           | For example -- suppose I'm dealing with some serialized data
           | structure that come from some external system. Very likely
           | the data model behind this value involves "nested values"
           | which have themselves have some type of which might be reused
           | in multiple places by that external system.
           | 
           | When the goal is to just solve problems -- the approach i
           | like to take is to focus on the values i want to consume and
           | produce -- which might themselves contain lots of nested
           | types each with some amount of reuse ...
           | 
           | I'd really like a language feature that supports
           | simultaneously defining a type where it's relevant within
           | some other data structure _and also allows_ giving that
           | embedded thing a name for independent reuse ...
           | 
           | I wonder if this postfix $ syntax is related to that use case
           | at all ...
           | 
           | (... this comment a speculation based on names of things only
           | without even reading the whole article ...)
        
           | superamadeus wrote:
           | Oh, fantastic. Thank you!
        
           | ralferoo wrote:
           | I think $() makes much more sense than ()$ in terms of
           | parsing, when you see $ you're looking for a single word
           | token, and $( you're parsing up to the matching )
           | 
           | Maybe it's not much extra workload, but ()$ requires you to
           | pattern-match all bracketed content in a string as a possible
           | capture, and the parser can't determine whether it's a
           | capture or not until the $ or a matching close bracket.
           | Consider parsing "((x)$)" would require parsing the entire
           | string to determine the first bracket wasn't a capture, then
           | we can treat just the first character as a literal, then we
           | have to re-parse the rest of the string again, and can't be
           | sure it's a capture until the $, and then we can evaluate it
           | as a real expression and then continue with the final $.
           | 
           | Other interesting cases would be "(x+(x)$)" or even
           | "((x+(x)$)$)". I'm not sure I could easily predict the
           | parsing of latter, but prefix and permitted unbracketed
           | single word variable names "(x+$x)" is clearer and the second
           | would either be "(x+$(x)$)" or "($(x+$(x)))" both of which
           | are explicit using the prefix form and could simplify to
           | "(x+$x$)" and "($(x+$x))" where the intent seems clearer.
           | 
           | There's the precedent that many languages already use the
           | prefix form which would help newcomers with familiarity, and
           | in fact many of these languages wouldn't even need the
           | brackets and $var would be sufficient, and I can't really see
           | why the spec requires the brackets in the ()$ syntax in
           | string literals but not for expressions in code.
        
             | OskarS wrote:
             | > Maybe it's not much extra workload, but ()$ requires you
             | to pattern-match all bracketed content in a string as a
             | possible capture, and the parser can't determine whether
             | it's a capture or not until the $ or a matching close
             | bracket.
             | 
             | You don't have to: you can also just parse the string
             | backwards.
        
           | lifthrasiir wrote:
           | That raises more questions though... Like, why does the
           | capture syntax have to be attached to the captured element?
           | 
           | Rust for example has a single `move` syntax for all-capture
           | vs. no-capture toggle, e.g. `|x| x + foo` (`foo` is stored as
           | a reference) vs. `move |x| x + foo` (`foo` is moved into the
           | closure). While I do want an additional mode for uniformly
           | applying specific methods (typically `.clone()`) for captured
           | elements, that is almost enough for typical closures.
           | 
           | Also, if my reading of the documentation is correct, `$` has
           | to be attached to _each_ occurrence of captured elements.
           | Like, `:(i) = i + foo$ * (foo$ + 1)`. Doesn 't that look
           | strange? It is even possible to mix two variants of captures
           | like `:(i) = i + foo$ * (foo&$* + 1)`, and it's not entirely
           | obvious to me what will happen to `foo$` when `foo&$*` is
           | updated. Treating these "upvalues" as a sort of an implicit
           | structure (e.g. `$.foo`) is much more consistent, and a
           | prefix form `$foo` can be regarded as its shorthand.
        
           | dataflow wrote:
           | I feel like there are more options than just the ones he
           | listed. Like "Hello ${name}" or "Hello `name`" or "Hello
           | {`name`}"...
        
           | zarzavat wrote:
           | Something about foolish consistencies...
           | 
           | The priorities of a programming language syntax are to be
           | readable first, consistent second.
           | 
           | When it comes to syntax that is used more frequently then the
           | importance of readability increases, and the importance of
           | consistency drops, because people will become familiar with
           | the syntax through frequency of use, so there is no need for
           | them to be guided by consistency. Yet they will be reading
           | the code more often.
           | 
           | When it comes to syntax that is used infrequently then
           | consistency is of more importance because you want users to
           | be able to intuit the syntax. Since it will be infrequently
           | used, the readability is of lesser impact.
        
       | colonwqbang wrote:
       | Most of my personal issues aren't with C++ syntax as such
       | (although it also has many problems). My main gripes are:
       | 
       | 1. Very slow compilation.
       | 
       | 2. Poor encapsulation, adding private functions requires
       | recompiling all dependents, see (1).
       | 
       | 3. Comically huge symbols make debugging much harder than it
       | needs to be -- today gdb OOM'd my 16GB laptop when trying to form
       | a backtrace of a typical QT application coredump.
       | 
       | Unfortunately it doesn't seem like cppfront can fix these issues.
       | It may still be a worthwhile effort in other respects, of course.
        
         | ThouYS wrote:
         | under what circumstances does (2) hold? for vanilla methods
         | it's no problem
        
           | loeg wrote:
           | If you touch a header, even private only, includers will
           | rebuild. Modules might fix this.
        
           | phkahler wrote:
           | >>> 2. Poor encapsulation, adding private functions requires
           | recompiling all dependents
           | 
           | >> under what circumstances does (2) hold?
           | 
           | To add a private member variable or function, you need to put
           | it in the class definition in the header file. Then anything
           | that includes the header needs to be recompiled.
        
             | ThouYS wrote:
             | they don't need to be. dependents will continue
             | functioning, because ABI hasn't changed
        
               | jstimpfle wrote:
               | Now explain that to my build system.
               | 
               | But even if you managed to do that, first compilation is
               | still much slower than it should be, because anlot of
               | headers have to be included (transitively) to allow even
               | declaring these fields and methods.
        
             | hkwerf wrote:
             | Admittedly, adding a private member _variable_ changes the
             | object size and thus the ABI and thus requires
             | recompilation of dependencies.
             | 
             | Thinking about that, is there any case in which private
             | functions can end up in a vtable? In that case, it'd break
             | ABI too.
        
               | NekkoDroid wrote:
               | > is there any case in which private functions can end up
               | in a vtable?
               | 
               | Yes, but it generally isn't something that is done.
               | 
               | https://godbolt.org/z/5oPovKzoT
        
           | colonwqbang wrote:
           | C++ build systems are typically based on file timestamps.
           | Modifying a header file triggers recompilation of all
           | translation units including that header.
           | 
           | There are workarounds like pimpl (aka. C style
           | encapsulation). But this requires extra boilerplate and
           | indirection. C++ modules might fix it at some point, but
           | after 35 years of not having them in C++ most real life
           | codebases aren't set up that way and may never be.
        
             | gumby wrote:
             | I don't think of pimpl as a tool for speeding up
             | compilation, but for black box encapsulation.
             | 
             | If the compile time (when adding a method) is really an
             | issue you can chop up and reconfigure your include files. A
             | pain, but perhaps saves you time in the long run.
             | 
             | Of course ( _waves hands_ ) modules will magically improve
             | things...someday.
        
               | colonwqbang wrote:
               | I think it can be both things.
               | 
               | Haven't you ever seen someone do                   struct
               | Thing;         struct OtherThing;
               | 
               | in lieu of just including "thing.h"? I see it frequently
               | in real life code bases and I can't see a reason for it
               | other than compilation time optimisation.
        
               | gumby wrote:
               | Sure, I do that all the time too. But you can't call a
               | method (or look inside Thing, or pass it as an argument,
               | only a pointer to it) without including the definition.
               | 
               | Hmm, there might be some interesting linker hacks to
               | patch things up post compilation. But then you'd want
               | some way to do the forward declaration for cases where
               | Thing could have been passed in registers...
        
               | DerekL wrote:
               | This is sometimes required to break dependency cycles.
               | Also, you can use this to rearrange declarations in the
               | same file.
        
               | germandiago wrote:
               | Pimpl is both. I use it as black box also, but it does
               | both things.
        
           | jstimpfle wrote:
           | Adding private functions or fields requires changing the
           | class declarations, which requires rebuilding any code that
           | includes that class deckaration. It shouldn't be like that,
           | especially for methods which shouldnt change anything about
           | the class ABI.
           | 
           | Even worse, this dependency is transitive. Dependencies to
           | allow defining these private methods an fields are exposed
           | too, forcing inclusion of headers to all members of the
           | class, even if it's only implementation details.
        
         | MindSpunk wrote:
         | Adding methods changes the vtable layout so there's no way to
         | not recompile all the dependents. There's no solution to this
         | unless private functions are guaranteed to not be virtual.
        
           | AnimalMuppet wrote:
           | Um... isn't that guaranteed? What would it mean for a private
           | function to be virtual? It can't be overridden by a different
           | implementation in a child class...
        
             | zetafunction wrote:
             | `final` prevents a child class from overriding a method.
             | `private` does not.
        
             | Findecanor wrote:
             | Yes, you can have a private virtual member function, and it
             | can be overridden in a child class (unless declared final),
             | apparently.
             | 
             | I too thought that sounded insane, so I just looked it up.
             | I've been programming C++ for twenty five years and the
             | thought of wanting to do this have never ever occurred to
             | me...
        
               | AnimalMuppet wrote:
               | TIL.
        
               | usefulcat wrote:
               | It could make sense if you have a method that you want
               | derived classes to be able to override but not to be able
               | to call directly.
               | 
               | This is, admittedly, a pretty niche case but certainly
               | not inconceivable.
        
               | zetafunction wrote:
               | Except the derived class can simply change the visibility
               | of the override, so...
        
             | bregma wrote:
             | Child classes can override private member functions in
             | their parent class.
             | 
             | Making all virtual functions private is the better way to
             | implement inheritance: it separates implementation from
             | interface, allows for common functionality to be moved to
             | the base class without requiring gymnastics in each and
             | every derived class, and even lets you simplify the public
             | interface to reduce compile times.
             | 
             | Try it, you'll like it. You may never go back to writing
             | Java in C++.
        
           | PoignardAzur wrote:
           | Wait, what? Virtual methods in C++ are opt-in. You only need
           | the 'final' keyword when you're overriding a method in a
           | child class.
        
           | josephg wrote:
           | There isn't _that_ much work the compiler should need to do.
           | Ideally, a clever compiler could just update the vtables in
           | some intermediate representation of the program and re-emit
           | the binary. The C++ compiler today is so insanely wasteful -
           | edit one header file and the compiler re-parses all the
           | header files N^2 times. It should be possible to make a
           | compiler thats way faster than any C++ compiler today.
           | 
           | Of course, the elephant in the room is the C++ preprocessor.
           | I haven't looked too closely into cppfront, but if I had the
           | chance, I'd give the C macro system a bullet.
           | 
           | My favorite "macro" system by far is zig's comptime, which is
           | beautiful and elegant. Zig code can simply elect to be
           | executed in the compiler instead of at runtime. For example,
           | here's how the print() function compiles in zig. Its a thing
           | of beauty:
           | 
           | https://ziglang.org/documentation/master/#Case-Study-
           | print-i...
        
             | edflsafoiewq wrote:
             | The problem is reflection, including SFINAE. Code can
             | branch on if a method exists.
        
               | josephg wrote:
               | So? It shouldn't take seconds to make one change to the
               | reflection database. Or update derived code.
               | 
               | Incremental compilation is fundamentally the same problem
               | that web frameworks solve. There's plenty of efficient
               | ways to do it.
        
             | vitus wrote:
             | > The C++ compiler today is so insanely wasteful - edit one
             | header file and the compiler re-parses all the header files
             | N^2 times. It should be possible to make a compiler thats
             | way faster than any C++ compiler today.
             | 
             | Well, yeah, that's the problem that modules are supposed to
             | solve. (AFAIK the only fully C++20-standard-compliant
             | implementation of modules is in MSVC, although even Clang
             | modules are adequate for drastically reducing compile
             | times.)
             | 
             | You are still going to have to recompile all your dependent
             | compilation units if the vtable layout changes, as
             | mentioned elsewhere, since all of your callsites have to
             | reflect any changes to vtable lookups.
             | 
             | > My favorite "macro" system by far is zig's comptime,
             | which is beautiful and elegant. Zig code can simply elect
             | to be executed in the compiler instead of at runtime. For
             | example, here's how the print() function compiles in zig.
             | Its a thing of beauty:
             | 
             | How is this different from constexpr / consteval in C++?
             | 
             | std::format (introduced in C++20) is implemented in a
             | similar fashion in that the format string is checked at
             | compile-time (number of args, types, etc), so there's no
             | good reason why C++ couldn't have a print function that
             | behaves the same way and is validated at compile-time [0].
             | Libraries such Abseil and folly certainly provide this.
             | 
             | [0] It seems that C++23's std::print is not that function,
             | oddly enough.
        
           | inkyoto wrote:
           | Yes, there are solutions, and the simplest one is replace the
           | direct vtable lookup with an indirect one where the methods
           | are referenced not by their numeric offsets in the vtable but
           | via their symbolic names and the offset resolution is
           | performed via a separate lookup table - not that dissimilar
           | from how it is done in ELF shared libraries.
           | 
           | All of them will result in incurring a performance penalty,
           | either at the runtime, or at the start-up time, or in the
           | compiler/linker, and memory blowouts. But it will solve the
           | recompilation problem.
        
           | Too wrote:
           | In typical c++ manner, we can't have nice things because
           | {obscure internal technicality that don't impact the user in
           | any way whatsoever}$. As a user I don't care what a vtable
           | is. Just make it work. Other languages don't have this
           | problem.
           | 
           | During release builds sure, optimize away with LTO and
           | whatever is needed to make it vroom. During development,
           | waiting several minutes for a minor private function update
           | is just absurd.
        
             | germandiago wrote:
             | C++ is designed for good performance. Solving ABI problems
             | permanently usually means an extra layer of indirection,
             | which hurts performance.
             | 
             | There are also concerns about what you can link against or
             | not once you modify the ABI of widely used types. This is
             | of real concern at least for closed-source software or
             | software that just cannot be recompiled.
             | 
             | I am not saying it should be the right choice, some of that
             | software is legacy. I just say this is a real concern.
             | 
             | As for the private function. You can use a pimpl and use a
             | private (on the cop file instead of header) and use that,
             | for example, in many cases. This keeps compile time down.
        
         | jokoon wrote:
         | I laughed at (3)
         | 
         | Although QT is not a tiny framework, and I don't really know if
         | modern C++ tools are really good enough for this sort of
         | problem, since C++11 to 20 probably caused those tools to
         | explode in memory consumption
         | 
         | But I am not surprised at all. I remember around 2013, I would
         | use bullet physics and the Ogre3D engine, and I had to tell
         | visual C++ to increase its memory capacity because the compiler
         | would refuse to continue.
        
           | a_t48 wrote:
           | 3) is forcing me to incorporate a symbol strip/upload to
           | sentry piping at $WORK because Eigen debug symbols cause our
           | build sizes to explode.
        
         | jmac01 wrote:
         | How is dependency management not in this list hahaha holy crap
         | c++ is so fucking shit to work with in this regard compared to
         | another "modern" language.
        
       | pciexpgpu wrote:
       | I wonder how this compares with Carbon -> C++ [0].
       | 
       | Carbon is (was?) a fantastic proposal, but not sure if it has
       | lost steam since it was introduced or how well it is being
       | adopted (be it inside Google or outside)?
       | 
       | Being able to incrementally/interchangeably use/call existing C++
       | code (and vice versa) seems like a great design choice (in
       | Carbon) without having to introspect the actual generated code.
       | 
       | Not sure how easy it is to get the cppfront-generated C++ to
       | bridge with existing C++ code (and vice versa)?
       | 
       | [0] https://github.com/carbon-language/carbon-lang
        
         | mort96 wrote:
         | Carbon isn't "being adopted", it's still being developed.
         | Making a programming language takes time. Let them at least get
         | to a point where they release some form of public beta (i.e a
         | few more years, at least) before talking about adoption.
        
         | nindalf wrote:
         | The roadmap for Carbon [0] mentions wanting to have basic, non-
         | trivial programs written in Carbon by the end of 2024. They're
         | aiming for a v0.1 release in 2025. If it gains traction,
         | they're aiming for a v1.0 beyond 2027.
         | 
         | I don't think anyone outside Google will seriously adopt this
         | before it reaches v1.0. Even within Google, they may choose
         | other options.
         | 
         | [0] - https://github.com/carbon-language/carbon-
         | lang/blob/trunk/do...
        
           | bluGill wrote:
           | Googles habit of dropping support for useful things make me
           | not willing to trust them. I plan for my current code to be
           | in use for at least 20 more years (i plan to retire before
           | then), I don't want to explain to my boss either why we are
           | maintaining a compiler or why we must rewrite working code.
        
             | fractalb wrote:
             | I suspect you don't touch Go code.
        
         | jokoon wrote:
         | Herb Sutter briefly talked about why carbon was not a good
         | contender, and I think remembering it was because of backward
         | compatibility with C++.
         | 
         | At some point, keeping C++ semantics matters, since having
         | different semantics would obviously prevent using previous C++
         | codebases, or make it more difficult to make those work
         | together, and that may be why Carbon may not be a good choice.
        
       | suby wrote:
       | I spent the other day writing an archetype entity component
       | system which made heavy use of template metaprogramming. I try to
       | avoid this if possible, but it was an exercise in seeing how
       | performant I could make it, and so I wanted to offload as much
       | work as I could manage to compile time and avoid things like
       | virtual dispatch. API similar to the basic parts of entt.
       | 
       | My take away from the exercise is that this is not a language for
       | human beings. I was successful in writing it, but it was
       | extremely difficult and frustrating. Part of the frustration is
       | because conceptually what I wanted to accomplish was not
       | difficult, but figuring out how to express it was a nightmare. I
       | am not new to the language, I've been writing C++ since 2009, it
       | was the first language I learned and I've spent nearly every day
       | of my life since then writing at least some C++ code. Even so, I
       | can't say that I truly understand this shit.
       | 
       | I'm hoping cpp2 brings us someplace closer to a language that
       | mere mortals can understand. I don't want the next generation
       | writing C++.
        
         | Kwpolska wrote:
         | There are lots of languages for mere mortals. They are not
         | compatible with C++, but that's a feature. The next generation
         | is largely not writing C++.
        
         | logicchains wrote:
         | >I spent the other day writing an archetype entity component
         | system which made heavy use of template metaprogramming. >I'm
         | hoping cpp2 brings us someplace closer to a language that mere
         | mortals can understand.
         | 
         | Are you sure the problem is the language itself, and not the
         | inherent complexity of that kind of metaprogramming? As far as
         | I'm aware, Lisp is the language with the cleanest support for
         | such metaprogramming, yet metaprogramming-heavy Lisp code is
         | still quite hard to read. I'm not aware of a programming
         | language in which a compile-time ECS would be easy to
         | write/read.
        
       | crazypython wrote:
       | What are the tradeoffs between cpp2 and Carbon?
        
       | Aardwolf wrote:
       | 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)
        
         | kreco wrote:
         | Note that the "<<" operator for std::cout is not related to the
         | language itself but related to the standard library.
        
           | Sharlin wrote:
           | 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
        
             | tialaramex wrote:
             | 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.
        
         | userbinator wrote:
         | I've always thought that using "<<" in that manner was more of
         | a way to show off the operator overloading feature than
         | anything else.
        
           | OskarS wrote:
           | 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.
        
             | tialaramex wrote:
             | It would have been possible to, as a special case, type
             | check the formatting, C compilers began doing that in the
             | 1990s IIRC.
        
               | throwway120385 wrote:
               | 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.
        
               | layer8 wrote:
               | It wouldn't have added support for custom types to
               | printf(), which was an important motivation.
        
               | tialaramex wrote:
               | 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.
        
               | layer8 wrote:
               | 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.
        
         | mort96 wrote:
         | 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.
        
           | Kranar wrote:
           | 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.
        
             | mort96 wrote:
             | 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.
        
         | dale_glass wrote:
         | 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.
        
           | diath wrote:
           | 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);
        
             | petters wrote:
             | 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.
        
               | hermitdev wrote:
               | 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.
        
           | blacklion wrote:
           | 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.
        
       | kreco wrote:
       | > Because ++ and -- always have in-place update semantics, we
       | never need to remember "use prefix ++/-- unless you need a copy
       | of the old value." If you do need a copy of the old value, just
       | take the copy before calling ++/--
       | 
       | I actually wish ++ and -- operators were removed. This would
       | simplify everything, nothing to remember whether it's prefix or
       | postfix operator, whether it copies something or not, you would
       | just do "value += 1" and be done with it.
       | 
       | - Less mental overhead.
       | 
       | - Remove an extra way of doing the same thing.
        
         | conradev wrote:
         | That is the direction that Swift went:
         | https://github.com/apple/swift-evolution/blob/main/proposals...
        
           | josephg wrote:
           | Rust and Go made the same choice. In Go, I think i++ is valid
           | - but only as a statement, not an expression.
           | 
           | https://go.dev/doc/faq#inc_dec
        
         | AnimalMuppet wrote:
         | But you would break the name! C++ would be a syntax error!
         | 
         | I mean, there are people that already think that...
        
           | kevindamm wrote:
           | We could allow overloading operator++ while not defining it
           | on anything built-in....
        
           | layer8 wrote:
           | But it's C++2, and that would become valid! (C + +2)
        
         | nathanrf wrote:
         | Unfortunately, C++ uses ++ and -- for iterators, many of which
         | cannot reasonably implement += or -=. This distinction is baked
         | into the type system to tell whether or not an iterator
         | supports efficient "multiple advance" (e.g. a linked list
         | iterator doesn't have += but a pointer into a contiguous vector
         | does).
         | 
         | There's no way to fix this in a reverse-compatible way for
         | existing code (which is one of the constraints of cpp2- it must
         | work with all existing C++ so that it is possible for existing
         | projects to migrate regardless of size).
        
           | Rexxar wrote:
           | Making ++ or -- a statement that increment the target without
           | returning a value should probably be enough for forward
           | iterators.
        
           | layer8 wrote:
           | A noncopying ++ _could_ be spelled `+= 1` though. So some
           | iterators would support `+= 1`, but not `+= 2`. This would be
           | vaguely similar to how the null pointer constant was defined
           | as an integer constant expression that evaluates to zero:
           | Define `+=  < _integer constant expression that evaluates to
           | one_ >` as the increment operator.
        
       | fancyfredbot wrote:
       | It was when debugging a memory leak which occurred because I
       | forgot to declare the base class destructor as virtual that I
       | started to think C++ was a rather unfriendly language and not
       | really designed to be easy to use.
       | 
       | Then a few years later I read the spec for std::launder that I
       | realised C++ was not really designed to be understood.
       | 
       | It's a shame because it's actually a rather nice language in some
       | ways. Here's hoping that this project or something similar takes
       | off and separates the good bits from the bad.
        
         | josephg wrote:
         | Yeah... its shocking to me how difficult it is to read the C++
         | standard library. Surely, the standard library is written by
         | the authors of the language. It should be a positive example of
         | how they hope their language is used, right?
         | 
         | Here's the source of C++'s vector class:
         | 
         | https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a0111...
         | 
         | In comparison, vec in rust. (Note you need to scroll down a few
         | pages to start seeing non-trivial functions. There's a lot of
         | block comments.):
         | 
         | https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#398
         | 
         | Or list in Go:
         | 
         | https://cs.opensource.google/go/go/+/master:src/container/li...
         | 
         | To my eye, that C++ code is by far the hardest code to read.
        
           | lanza wrote:
           | I work on clang and don't know go yet still find the go
           | version easier to read.
        
           | jcelerier wrote:
           | > It should be a positive example of how they hope their
           | language is used, right?
           | 
           | should it though? there's a million ways to learn C++.
           | Reading the std code definitely isn't one - technically the
           | std could be entirely compiler builtins. If you want to read
           | positive examples take A Tour of C++ 3rd edition
           | (https://www.amazon.ca/Tour-C-Bjarne-
           | Stroustrup/dp/0136816487)
        
             | tialaramex wrote:
             | "Do as I say, not as I do" is known to be poor pedagogy.
             | 
             | If you find that expert practitioners don't do the things
             | you think students should be doing, it suggests that
             | something is wrong and needs fixing. In the standard
             | library implementations it's _very obvious_ that something
             | is badly wrong, and yet for _decades_ C++ has resisted the
             | hard work of fixing it.
        
               | jcelerier wrote:
               | Yet thousands of people learned C++ well enough to use it
               | in a professional setting, so surely << "Do as I say, not
               | as I do" is known to be poor pedagogy. >> does not hold
               | in the general case.
               | 
               | > If you find that expert practitioners don't do the
               | things you think students should be doing, it suggests
               | that something is wrong and needs fixing
               | 
               | It does not and is a very naive world view. In any trade
               | expert practitioners' way of working is wildly different
               | from what you would learn in a classroom (and generally
               | makes said student's hair raise on their head when they
               | see. This is not too relevant with C++ though as the std
               | implementation "ugliness" is mainly driven by material
               | constraints.
               | 
               | Besides in general in programming this is not even
               | _possible_. Like, from your argument one wouldn 't be
               | able to learn how to use the Win32 API or Cocoa API since
               | the operating systems using them are closed-source and
               | you cannot see how they are implemented & used by the
               | teams who develop these APIs.
        
               | tialaramex wrote:
               | No, I reject the claim that "my argument" (not in fact
               | mine) says you can't learn an API _unless_ you can see
               | how it 's implemented. I don't think that's a remotely
               | plausible reading of what was written. Instead I agree
               | with the claim they actually wrote that since software is
               | intended first and foremost to be read, it makes sense
               | that the standard library, software you'll be using as a
               | programmer should be a _positive example_ and not a
               | horrible distorted mess.
        
           | formerly_proven wrote:
           | Part of the distinct "C++ std" style is due to naming rules
           | and textual includes. Every name that's not part of the
           | standardized interface starts with __ because __foo and _Foo
           | are blanket reserved names, so a user can't complain that
           | std:: explodes when he does "#define _Base 0".
        
           | tialaramex wrote:
           | Notice that there are in practice _three_ distinct
           | implementations of the C++ standard library. They 're all
           | awful to read though, here's Microsoft's std::vector
           | https://github.com/microsoft/STL/blob/main/stl/inc/vector
           | 
           | However you're being slightly unfair because Rust's Vec is
           | just defined (opaquely) as a RawVec plus a length value, so
           | let's link RawVec, https://doc.rust-
           | lang.org/src/alloc/raw_vec.rs.html -- RawVec is the part
           | responsible for the messy problem of how to actually
           | implement the growable array type.
           | 
           | Still, the existence of _three_ C++ libraries with slightly
           | different (or sometimes hugely different) quality of
           | implementation means good C++ code can 't depend on much
           | beyond what the ISO document promises, and yet it must guard
           | against the nonsense inflicted by all three and by lacks of
           | the larger language. In particular everything must use the
           | reserved prefix so that it's not smashed inadvertently by a
           | macro, and lots of weird C++ idioms that preserve performance
           | by sacrificing clarity of implementation are needed, even
           | where you'd ordinarily sacrifice to get the development
           | throughput win of everybody know what's going on. For example
           | you'll see a lot of "pair" types bought into existence which
           | are there to squirrel away a ZST that in C++ can't exist,
           | using the Empty Base Optimisation. In Rust the language has
           | ZSTs so they can just write what they meant.
        
           | clnhlzmn wrote:
           | I think the c++ version could be more understandable but it's
           | as if the authors intentionally made it as obtuse as
           | possible.
        
             | bregma wrote:
             | The authors are required to make it obtuse. They're
             | required to use warts on all of the names because most of
             | the code is in the head files and is generative code
             | compiled by users of the library rather than the vendor. In
             | order to avoid naming conflicts they can only use obscured
             | names in their implementation of any but the defined API
             | (eg. naming any internal functions, macros, or variables
             | with leading underscores).
             | 
             | So, the authors did intentionally make it as obtuse as
             | possible for your benefit. It's written to be used, not
             | studied, by all kinds of developers in all kinds of
             | circumstances.
        
               | gosub100 wrote:
               | They could supply a "pretty" version for people who want
               | to review it. Every time I have to step through code (and
               | accidentally step into STL code) it looks sloppy and
               | gross, like a swamp. No comments or organization. I would
               | expect something neatly formatted, and comments saying
               | "This is overload-4 of std::copy()..." etc.
        
         | corysama wrote:
         | The evolution of C++ has been a multi-decade history of dealing
         | with difficult reality.
         | 
         | I have great hope that Herb can create with his cppfront
         | project "The Very Best of C++" to carry that tremendous legacy
         | forward.
         | 
         | If I was to throw my hat into a "C++ successor", it would be
         | https://www.hylo-lang.org/ with its "all the safeties" and
         | "tell you when you're doing it sub-optimal" approach.
        
           | tialaramex wrote:
           | Hylo is interesting in principle for exploring this
           | particular notion (mutable value semantics) as a way to
           | potentially write software without the lifetime annotations
           | Rust needs.
           | 
           | But I don't find it promising that after apologising in 2023
           | for missing their self-imposed 2022 deadline to ship
           | something that works and other people can use, in Q2 2024 it
           | doesn't look like their new 2023 roadmap got done either.
           | Maybe they're going to eventually deliver this amazing thing.
           | Maybe they're just going to learn some lessons (probably for
           | the Swift community) and never ship Hylo per se. Certainly
           | 2025 "Take over the world" looks... ambitious with nine
           | months left to do all the stuff left from 2023 and all the
           | work described for 2024 on top.
        
             | germandiago wrote:
             | For me Hylo is the most elegant object model I have seen so
             | far in the sense that it achieves dafety without all the
             | anniyations and borrow checks that Rust performs. It just
             | fits well the model for thinking yet it enables lots of
             | optimizations. Of particular mention is that copies are
             | lazy and can be passed freely and will only be done
             | transparently on demand. That is what keeps the model
             | simple.
        
       | dang wrote:
       | Related:
       | 
       |  _Cppfront, Herb Sutter 's proposal for a new C++ syntax_ -
       | https://news.ycombinator.com/item?id=32877814 - Sept 2022 (545
       | comments)
       | 
       | and also _Cppfront: Autumn Update_ -
       | https://news.ycombinator.com/item?id=37719729 - Sept 2023 (8
       | comments)
        
       | jokoon wrote:
       | Someone on reddit said that the cpp2 repo was a bit old, and that
       | is true, although he may have started this as an experiment
       | influenced by typescript and left it on the side at some times.
       | 
       | Anyway I have no idea if cpp2 would get support from microsoft or
       | other devs, but cpp2 seems like the most humble and "least risky"
       | solution for the future of C++, and I really want it to be.
       | 
       | What I remember the most that Herb Sutter said in his cpp2 talk,
       | is that it aims to avoid 95% of bad coding practices that C++
       | allows today.
       | 
       | It's safe to say that beyond the valid criticism of C++, that it
       | quite a good goal and it would improve C++, without using a new
       | language, and that's good, because a new language causes
       | problems: new toolchains, new semantics, new specifics, no
       | experience on a new language.
       | 
       | Cpp2 is not a new language, it is the same semantics of C++,
       | except it has a new syntax and enforces good practices.
       | 
       | One very interesting point: in the future, cpp2 allows a
       | cpp2-only compiler to be born, and it would still live next to
       | C++ binaries without problem. That cpp2 compiler might probably
       | be much faster since the cpp2 is a smaller stricter subset.
        
         | gumby wrote:
         | > Anyway I have no idea if cpp2 would get support from
         | microsoft or other devs...
         | 
         | Doesn't he work for Microsoft?
        
           | dgellow wrote:
           | Yes but it's his own personal project
        
         | petre wrote:
         | > Anyway I have no idea if cpp2 would get support from
         | microsoft or other devs, but cpp2 seems like the most humble
         | and "least risky" solution for the future of C++, and I really
         | want it to be.
         | 
         | That ship has sailed. They already have C#.
        
           | qalmakka wrote:
           | To be fair C# is vastly different in terms of semantics
           | compared to C++. There's a lot of areas where it's not viable
           | to use C#, and IMHO it also has its own share of legacy and
           | bad decisions from its "Java clone" days that make it
           | impossible to prefer it to C++ sometimes.
           | 
           | Btw Microsoft is definitely interested into adopting new
           | languages, just look all the effort they've been pouring into
           | Rust lately.
        
             | pjmlp wrote:
             | Rust is now the official system programming language for
             | Azure infrastructure, alongside managed languages, and it
             | appears there is a soft spot to use Go instead of C#, when
             | looking at what Azure opens up.
             | 
             | WinDev, Office and XBox is another matter, they are deep
             | into C++ and COM culture.
        
           | flohofwoe wrote:
           | C# is so old by now, if it would be a good replacement for
           | C++ at MS, it would already have replaced it.
        
             | barrenko wrote:
             | Java and C# are in their "let's get functional" phase.
        
               | neonsunset wrote:
               | :(
               | 
               | C# has been at that for more than a decade and a half
               | already. Java's arrival to the party is extremely late
               | and still lacking in many areas.
        
               | pjmlp wrote:
               | C# could have been like D back in 2001, yet it had to
               | wait to go open source, away from the wings from WinDev
               | politics, having to provide a replacement to C++/CLI
               | capabilities in a cross-platform way, to finally expose
               | the full CLR to C#, without us having to routinely
               | manually generate MSIL or reach out to C++/CLI.
               | 
               | Singularity and Midori were hardly taken seriously in any
               | form by WinDev.
        
             | pjmlp wrote:
             | Don't mix technology with the internal politics at
             | Microsoft, where some business units won't use anything
             | else besides COM and C++, no matter what.
             | 
             | They are so strong that they were responsible pushing the
             | whole company into the whole Windows 8 debacle with WinRT,
             | where COM was supposed to finally replace .NET.
             | 
             | https://arstechnica.com/features/2012/10/windows-8-and-
             | winrt...
        
         | maxloh wrote:
         | How about Google's Carbon language?
         | 
         | https://github.com/carbon-language/carbon-lang
        
           | joshkel wrote:
           | Carbon and Cpp2 are both "C++ successors," broadly speaking.
           | However, they take different approaches in their design:
           | 
           | Carbon is a brand-new language that's designed to have
           | seamless interoperability to C++.
           | 
           | Cpp2 _is_ C++, just with a different syntax. (The goal is to
           | even be able to mix Cpp2 and C++ syntax in the same source
           | file. The initial implementation transpiles Cpp2 to C++
           | source code, similar to how the original C++ implementation
           | transpiled C++ to C, rather than implementing a full
           | compiler.)
           | 
           | Their overall goals appear to be different, too: The Carbon
           | README states, "Existing modern languages already provide an
           | excellent developer experience: Go, Swift, Kotlin, Rust, and
           | many more. Developers that can use one of these existing
           | languages should." With that mindset, it sounds like more of
           | a stopgap for projects already invested in C++. In contrast,
           | I believe that Sutter would argue that C++ still has the
           | potential to be a viable choice for many tasks, and Cpp2 is a
           | way to realize that.
        
       | kreco wrote:
       | > // 'BufferSize' is an object defined as a synonym for the value
       | 1'000'000
       | 
       | > BufferSize: i32 == 1'000'000;
       | 
       | So "value : i32 = 10" is variable, but "value : i32 == 10" is a
       | constant.
       | 
       | The difference is so subtle I'm not sure I like it.
       | 
       | Later in the documentation you can find "equals: (a, b) a == b;"
       | which is a function but it feels like I need to decipher it
       | because "==" is not for alias in this case.
       | 
       | Retaking the example of "equals: (a, b) a == b;" it feels also
       | odd to omit the braces because they are even enforced for if/else
       | branches.
       | 
       | I have to admit that everything was interesting until the
       | "Summary of function defaults" part.
        
       | FpUser wrote:
       | Unless I can step through original source code in debugger, watch
       | variables etc. etc. I could not accept any source to source
       | translator in my practice.
        
         | nathanrf wrote:
         | It is a good thing that cppfront lets you do that, then!
         | 
         | Cppfront generates #line pragmas which tell the generated .cpp
         | file which source lines to "blame" for each piece of generated
         | code. This isn't something new and fancy for cppfront, it's a
         | bog-standard pragma that your debugger already understands. So
         | it will work the exact same as your current debugging workflow
         | even if you mix cpp and cpp2 source files.
        
           | wheybags wrote:
           | I'm working on a hobby project language that generates plain
           | C as output, and debugger integration has been one of my big
           | worries. If that works, then this is awesome, thank you!
        
       | typ wrote:
       | Looks neat and convincing. But I think the goal (and effort) to
       | make it into the C++ standard would hinder the momentum of
       | adoption. I suspect it would have to go through a lot of politics
       | and bikesheding before making any real-world impact. Imagine that
       | if Typescript had insisted to get accepted into the Emca standard
       | before widespread adoption and promotion by Microsoft; it would
       | probably still stay in the 'experimental' stage.
        
       | howtofly wrote:
       | Any good CMake integration besides https://github.com/modern-
       | cmake/cppfront?
        
         | cassepipe wrote:
         | xmake handles cppfront :
         | https://xmake.io/#/guide/project_examples?id=cppfront-progra...
        
       | grumpy_coder wrote:
       | It's a nice idea, but not clear that it can truly interoperate
       | with vanilla C++ libs which I think is required. Seems to be
       | waiting for modules to be finalized, but whether cpp2 can call
       | cpp, and cpp can call cpp2 without implementing half of a C++
       | compiler isn't obvious.
       | https://github.com/hsutter/cppfront/issues/594
        
         | iamaredpanda wrote:
         | It's a just a transpiler to valid C++ code, so calling C++ code
         | from cpp2 should be fine, but calling cpp2 code from C++ is an
         | issue. There is no implementing half of a C++ compiler because
         | it just uses clang or something after it is done transpiling.
        
       | carlsborg wrote:
       | At this point the focus should be on making interop with python a
       | first class feature.
        
       | teo_zero wrote:
       | I like the idea, although many choices are arguable. For example,
       | having to introduce mandatory/prohibited white space around
       | binary/postfix operators (like "&") completely spoils the goal of
       | having a more rational syntax.
        
       | dfgdfg34545456 wrote:
       | Great new idea in cpp. Automated bounds checking in the hello
       | world example sold me straight away. Try and do that as tersely
       | Haskellers. I hope this project gets momentum.
        
       | skywal_l wrote:
       | In this kind of thread I always mentionned Circle[0] from Sean
       | Baxter. It's worth a look.
       | 
       | [0] https://www.circle-lang.org/
        
       | mgaunard wrote:
       | I don't want bounds-checking, so lost interest immediately.
       | 
       | This is a step in the wrong direction.
        
         | dale_glass wrote:
         | There's barely a point in making a better C++ if you're not
         | going to address one of the most obvious footguns.
        
           | mgaunard wrote:
           | The main iteration this cycle for the next C++ is contracts.
           | 
           | Contracts are all about introducing undefined behaviour if
           | you don't satisfy a precondition.
           | 
           | In practice this improves software quality on many levels by
           | clearly defining requirements on interface boundaries that
           | would otherwise be implicit or just documented.
           | 
           | Of course you can have special debug modes where you actually
           | check that contracts are being satisfied.
        
             | tialaramex wrote:
             | > The main iteration this cycle for the next C++ is
             | contracts.
             | 
             | As ever the C++ train leaves on schedule with or without
             | anything you suppose is "promised" for that standard
             | revision. This has been the practice since 2011 and I don't
             | expect it to stop unless ISO tells them "Enough" or the
             | whole thing comes apart.
             | 
             | > Contracts are all about introducing undefined behaviour
             | if you don't satisfy a precondition.
             | 
             | Nope. That's _explicitly_ not what the proposal sets out to
             | do. It is likely that, as usual, WG21 will manage to take
             | facilities intended to be safe, file them to a sharp edge
             | and then slit their own throats, but P2900 in its current
             | form doesn 't do so. Here's an item from the proposal's
             | list of things they're explicitly _not_ proposing:
             | 
             | "The ability to assume that an unchecked contract predicate
             | would evaluate to true, and allow the compiler to optimize
             | based on that assumption, i.e. the assume semantic"
             | 
             | One of the three significant implementers, Microsoft,
             | actually _strongly_ objects to any idea of introducing yet
             | more Undefined Behaviour into a language that is distinctly
             | underwater when it comes to provable correctness. Microsoft
             | shut down previous proposals in this area, and while they
             | might (wrongly IMO) be sold the compromise position that 's
             | advocated by some WG21 members today (some UB in some
             | contract checks), you're asking for a lot more.
        
               | pjmlp wrote:
               | With Azure now only considering C++ for existing
               | projects, and new projects require explicit reasoning why
               | C or C++ instead of Rust, I expect some internal pressure
               | at MS to do the right thing.
        
               | mgaunard wrote:
               | I've been involved with the C++ standards committee for
               | 12+ years and my experience is that it is largely
               | political; championing a proposal is more of a demagogic
               | endeavor than anything else. Influential players have
               | been priming contracts (that have been in the works
               | forever) as a core objective this cycle and giving it a
               | lot of momentum for it to happen this time. Of course if
               | people still can't be convinced it's good enough before
               | the deadline, it won't make the cut, but it's on track.
               | 
               | Now regarding undefined behaviour, it's always been the
               | reason why the proposal isn't moving forward. Some people
               | believe religiously undefined behaviour is evil and will
               | oppose anything tied to it. The kind of clause you
               | mentioned is just to appease them and attain a
               | compromise.
               | 
               | But ultimately, contracts and undefined behaviour
               | (depending on the definition you go for) are intimately
               | linked.
               | 
               | Consider lower_bound. The behaviour is undefined if the
               | input is not sorted. That's just the way it is.
               | 
               | You can't magically make a program well-formed if you
               | breach preconditions even if you say optimizers are not
               | allowed to make additional assumptions.
        
       | ibobev wrote:
       | I do not understand why there is a push to change the C++ syntax.
       | There are plenty of new natively compiled languages like D, Go,
       | Rust, Zig, Nim, Odin, Crystal, and so on. If you do not like C++
       | you always can use some of them instead. The problems that make
       | C++ unsafe are semantic and not syntactic ones.
        
       | pjmlp wrote:
       | The whole story about what cpp2 tries to be, distancing itself
       | from other C++ wannabe replacements is only due to be coming from
       | WG21 chair, which naturally can't talk about a C++ replacement as
       | per conflict of interests.
       | 
       | Cpp2 isn't an alternative syntax to C++, as much as C++ and
       | Objective-C aren't alternative syntaxes for C, even though they
       | support a subset of it, and were born exactly the same way, code
       | translators into C.
       | 
       | C didn't evolve into them, they became their own ecosystem,
       | tainted by the underlying C compatibility.
       | 
       | The only alternative that is really a Typescript for C++, is
       | Circle.
        
       ___________________________________________________________________
       (page generated 2024-04-01 23:02 UTC)