RFC: Thoughts on generative C++
I'd be interested to hear what you guys think about this:
Oh, there's been some discussion about proposed changes on the Qt mailing list.
My thoughts: interesting idea, for sure. It would make it possible to resign from MOC and make the more exotic Qt futures to be built "natively", if I may abuse that term in such a way. Also, I imagine this could greatly improve the compiler errors (right now it is sometimes hard to judge what causes an error because the compiler points to moc file) to show error in user code instead of generated one.
However, it will take a long time until Qt can transform into using this approach (if at all). It is a definite binary and source compatibility break, so requires a major version change (by the time the proposal is accepted into ISO, this can easily mean Qt 7 or even Qt 8). It will require big porting effort, akin to Qt 3 => 4 transition which was painful.
So, all in all - good idea, but won't change anything in Qt world anytime soon, I think, even if ISO accepts it.
Not super sure the benefits are greater than the potential damages this might cause.
The arguments specific about Qt are 🐂💩.
property<T>, as he described it, would not remove the need to go through moc, it would be just another possible syntax for the same thing. the signal/slot return type was just too generically illustrated to comment on
@VRonin what potential damages do you have in mind ?
I'm kinda torn on this. On one hand I'm extremely excited about the possibilities, but on the other I'm worried about what it will mean for the language and its ecosystem.
The benefits I see:
- A ton of code I deal with could be greatly simplified with meta-classes. This includes not only the code generators (like moc or midl) but also a lot of boilerplate code, template and macros (if you ever implemented a macro or template based property system you know the pain). The idea of providing classes with customized default behavior is very compelling to me.
- Experimenting with new language construct ideas would be possible without hacking on the compiler or creating additional tooling. As an example - ever heard of a MS specific
__superkeyword? An extremely useful feature that is just not useful enough to standardize because there's boilerplate workaround for it. Now I could just write my own metaclass that adds it.
- I deal with large codebase that requires distributed building to be viable. Distributed builds don't always go along with code generators or require special care. This would simplify this scenario greatly removing the need for extra code generation step (there's also a downside to this, see below).
- This one is kinda vague but the idea of creating your own language constructs or modifying existing ones (because that's what it partially boils down to) sounds kinda liberating - e.g. somebody comes up with a rule of 3, or 5 or 0 or whatever comes next... now you don't have to rely on programmers to be up to date with every bell and whistle of new language version or rely on someone using the right type traits. You can just code these rules into a
and the dangers:
- It needs to be handled very very carefully. It's the kind of feature that could easily break the language and it would be very hard to glue it back together in future versions.
- Tooling. Tooling. Tooling. We already have multiple sub-dialects in C++: the preprocessor, templates and constexpr. A lot of computation is being moved over to compile time. The tools for writing and, especially, debugging that stuff always lags behind and they really really need to catch up. It's not a problem exclusive to metaclasses but it gets worse further with them. I honestly don't want to have to debug a 100 line constexpr template metaclass with #ifdef statements using paper scribbles and coffee.
- A lot of computation is being moved over to compile time. This is a big problem for compilation times in large code bases. It might not be an issue for small projects or for ones that compile on some computer super-farm, but for the middle tier this is a big pain point. 3rd party code generators like moc can be paralleled to some degree but it would be a lot harder if such generator is glued into the compiler step. To circumvent this some artificial policies would need to be introduced on site, e.g my company already has a restriction on the template complexity we can do. Not because of any correctness or readability concerns but simply because of the compile time footprint. I don't want any more great language features It's not viable to use because of that.
- There seem to be a growing number of features coming in C++ that kinda sorta overlap in functionality. Metaclasses, reflection and concepts in particular seem to me have a big overlap in the issues they aim to address. C++ is complex as it is. This will add a lot to it. Even just syntax wise it's a whole lot new things.
evaland other Lispian constructs to the like worry me. I hope this doesn't turn C++ into a completely dynamic language. That's not what I signed for choosing it :P
- It's a million years away from when it will be usable in production. By the time it gets here all the problems it tries to solve might very well be addressed in a different way so it will have to be redesigned time and time again to stay relevant. It's concepts all over again I fear.
@SGaist As Mr. HS acknowledges this is a sharp knife. If you ever came across a third-party-written template library (even a well written one as boost) you know how difficult to read and maintain for someone who isn't the author. imagine what happens when you have a company internal library in which you can exploit templates, metaclasses and template metaclasses. every repository risks to become its own language.
This one is kinda vague but the idea of creating your own language constructs or modifying existing ones (because that's what it partially boils down to) sounds kinda liberating - e.g. somebody comes up with a rule of 3, or 5 or 0 or whatever comes next... now you don't have to rely on programmers to be up to date with every bell and whistle of new language version or rely on someone using the right type traits. You can just code these rules into a copyable_class, movable_class etc.
This is already possible using a base class that contains nothing but a bunch of static asserts
@VRonin Static asserts can only force you to write something when you're subclassing. Meta-classes could "write" it for you i.e. generate the members and typedefs you need.
I can only say.
For 20 years ago, many beginners loved to
use #define and macros to alter the language
And even far worse stuff.
Luckily that became really, really bad practice and it went away.
So now they want to include even better support for it?
Not sure it will be so glorious..
But im sure it will be messy.
I would much like real generators, outputting true c++ to inspect.
Like ability to enum all members and types for easy streaming and
boilerplate code generation.
Not the ability to alter the language directly.
So now they want to include even better support for it?
No, the metaclasses do not allow you to redefine existing concepts. It allows you to create new default classes with different defaults. And both the meta and normal code remains strictly compiled and testable.
It will be possible to abuse this system, sure, and that is indeed a bit worrying. But, as I understand it, the changes permitted won't be as big as macros allow.
Ok so it sounds worse than it might become. :)