8 ms·
Towards a more powerful and simpler C++ with Herb Sutter
- 0xFFC 9y agoAre they really going to add $ to C++? Unbelievable. What was wrong with "reflexpr"? It is way more C++'ish than "$". Update: From Herb's blog : "Also, a vocal minority in the committee strongly want a syntax that does not include the $ character (not just for $class, but also for $expr reflection) because they have large code bases that use $ in source code that is not C++ code but is processed to emit C++; removing $ is an easy change at any time and we’ll just follow what the committee decides for reflection syntax (in fact, the alternative syntax I showed in the endnote above removes the need to write $). So further work is needed on those items, but fortunately none of it affects the core model." https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-generative-c/#comment-39733 https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-ge... P.S. I really hope that vocal minory would win ;) But overall the proposal is what I have been talking about for a long time.
- humanrebar 9y agoThe best way to add new language primitives without breaking anyone is to pick a syntax that currently fails to compile. `reflexpr interface {...}` could be declaring and initializing a global. `$class`, on the other hand, doesn't compile. One could also do `virtual class` or something, I guess, since `virtual class` is a combination of reserved keywords.
- ape4 9y agoIts so much simpler :)
- 0xFFC 9y agoI agree, but $ doesn't make the language way more uglier than what it is now?
- mattnewport 9y agoI don't see why, unless you have something particularly against the $ symbol? It seems to fit with existing syntax quite well, e.g. & gives the address of a thing, $ gives the reflection of a thing. Extending that to define a metaclass seems pretty natural.
- alphaalpha101 9y agoI think the negatives (ugliness) of having $ in a few places where you define metaclasses is outweighed by the positives (cleanliness) of replacing this: class foo { virtual ~foo() = 0; virtual void do_x() = 0; }; with this: interface foo { void do_x(); }; in thousands of places.
- aduitsis 9y agoNext proposal will be about the new C++ logo, which will be, yes, a camel!
- kevinnk 9y agoIt's still up in the air I think - you can see from his blog[1] that others in the the committee prefer a syntax more like meta::type interface(const meta::type source) { // … basically same code … }; [1] https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-generative-c/ https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-ge...
- 0xFFC 9y agoThank you, I didn't know that. This syntax makes much more sense. Considering C++ style programming. I am very interested in having Reflection in C++. But tbh $ makes it really awkward.
- chrisaycock 9y agoThe interview covers proposed metaprogramming features in upcoming versions of C++. In particular, it demonstrates metaclass as a way for users to define new kinds of types, instead of relying solely on class/struct/union/enum. For example, Java has an interface, in which methods are declared but not defined. The proposal for metaclass gives a demonstration of what an interface in C++ could look like: interface Shape { int area() const; void scale_by(double factor); }; Instead of changing the compiler to allow for new interface keyword, we can create a metaclass: // the dollar sign ($) prefix indicates reflection and metaprogramming $class interface { // the constexpr indicates compile-time execution constexpr { // raise an error if there are data members compiler.require($interface.variables().empty(), "interfaces may not contain data"); // loop over all functions for (auto f : $interface.functions()) { // raise an error if move/copy functions are present compiler.require(!f.is_copy() && !f.is_move(), "interfaces may not copy or move"); // function must be public if (!f.has_access()) f.make_public(); compiler.require(f.is_public(), "interface functions must be public"); // function must be virtual f.make_pure_virtual(); } } // add a destructor virtual ~interface() noexcept { } }; Thus I can create a new kind of type directly in my code. This can be part of a library for downstream users without ever changing the compiler. See the full proposal here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0707r2.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p070...
- xamuel 9y agoThat is not a step toward simpler code. Under that proposal, people looking at your code will have to look up definitions of basic things that ought to be keywords---like "interface"---in order to reason about the code.
- jcelerier 9y ago> Under that proposal, people looking at your code will have to look up definitions of basic things that ought to be keywords---like "interface"---in order to reason about the code. That's a good thing: now you can refer to 20 lines of code instead of 15 pages of standardese to understand what happens.
- CamTin 9y agoJonathan Blow (cult/indie game developer/studio owner) has a lot of ideas about evolving C++ (or rather, building a new language to replace it) specifically in a game industry context. This perspective is interesting because its kind of running at a different angle away from the "memory-safe, better guarantees" project that Rust is workin on. https://www.youtube.com/watch?v=TH9VCN6UkyQ https://www.youtube.com/watch?v=TH9VCN6UkyQ Just as the scripting languages took a big bite out of C/C++ usage starting in the 90s, I think we're seeing another couple use-case for C/C++ pull off: 1) stuff that is performance sensitive but security sensitive as well (Rust) 2) stuff that is soooo performance sensitive that Rust and C++ are actually too bloated, but which isn't really security sensitive so the guarantees that Rust/Modern C++ offer aren't worth it (Jai, Blow's language). Category 1 is clearly real, but Category 2 might be too small to sustain itself (though Blow makes an economic argument that it would be worth it). Are we just going to keep peeling back C/C++ users from the pack with more specifically-useful languages until there are none left except for those maintaining legacy code? Or are there use-cases where C++ will continue to make sense? I guess a lot of this depends on whether or not we can meaningfully "modernize" C++ through the standards process without simply bolting on a lot more features that add to the bloat. I wouldn't wager much that this trick can be pulled off.
- vvanders 9y agoAs Ex-Gamedev I don't buy that #2 is too bloated for C++, you just have to be smart about what features you pick. Really though for what he wants to do you want a flexible framework(scripting language) backed by a fast engine(native). Jai sounds pretty interesting but I don't know if Blow has the interest in building an ecosystem around it or just using it for his own projects. FWIW my ideal use case is Lua + Rust. I've done it on a few projects so far and really love the combo of flex + stability.
- raverbashing 9y agoAgreed The only case I see for "C++ is too bloated" is for embedded apps on limited hardware and even then But then of course people make something that's 10 inheritance levels deep and (ab)uses templates and then suddenly "C++ is slow". Write better code
- WoodenChair 9y agoThis sounds to me like "we will make it simpler by adding more features (that are presumably simpler to reason about)." The problem with C++ (and the reason that it is too complex) is that it has too many features. This proposal will do nothing to eliminate all of the cruft, the real source of complexity. That would require actually removing features, backwards-compatibility be damned!
- wtetzner 9y agoLooking at this post https://news.ycombinator.com/item?id=15613848 https://news.ycombinator.com/item?id=15613848, I wonder if it could help to simplify C++ by moving some of the existing features into libraries, which you would have to include for backwards compatibility, but could do without if you didn't need backwards compatibility.
- mattnewport 9y agoBackwards compatibility in C++ means "your existing code still compiles and does the same thing". Can you give an example of a situation where that could be achieved with your proposal?
- wtetzner 9y agoWell, my thought was that you'd just have different profiles, like is already used: -std=c++20-full or -std=c++20-light Perhaps c++20-light could never become the default, since it would break backwards compatibility, but you could always set the flag. I dunno. It was just a thought I had when reading about the new feature, not something I've thought through.
- mattnewport 9y agoI rarely see anyone present well thought out specifics of what should be removed from the language when making these types of claim. There are some complex areas (two phase name lookup springs to mind) that might be done differently if designed anew but I haven't seen too many good examples of things that could be "easily" removed, backwards compatibility be damned, that I have found to be actual problems in practice. The best examples are usually legacies of C.
- jstimpfle 9y agoYeah Metaclasses in Python are obviously so powerful and make programs so easy to read, so let's just go ahead and add those as well. Now we only write struct Point { int x; int y; }; to get the oh-so-needed class Point { private: int x; int y; public: Point() =default; ~Point() noexcept =default; Point(const Point&) =default; Point& operator=(const Point&) =default; Point(Point&&) =default; Point& operator=(const Point&&) =default; }; Genius! Almost like 1972 where we wrote the former and that was just fine!
- mattnewport 9y agoYou can still write the former and it's just fine.
- jstimpfle 9y agoExcept, I need to think the latter?
- mattnewport 9y agoNot for a Plain Old Data (POD) type. You need to think about the latter if you're manually managing memory or OS resources in your class (which should be rare) or you're trying to optimize performance when you have members that can be moved more cheaply than copied (usually because they manage memory) which should also usually be rare and the result of identifying a performance issue through profiling.
- makecheck 9y agoI sort of want a file-by-file language upgrade like Objective-C seems to have. For instance, if you add something like “nullable” to an Objective-C header, then the compiler will require similar directives throughout the file; otherwise, it doesn’t. C++ needs a new strict set of rules that (ideally for individual files, to start) prohibits some set of older/deprecated features from even compiling. That way, you know where the language is going and you adapt.