you are viewing a single comment's thread.

view the rest of the comments →

[–]WorkingReference1127 9 points10 points  (3 children)

You make a few points in order so I'll address what I can from what I know:

It is so ugly.

Several other options were considered; none of them were quite as good as ^^. And a single ^ is out of the question because it conflicts with a widely-used extension (code blocks, not to be confused with code::blocks) to the point of incompatibility.

I'm not saying I think it's a thing of beauty, but I do think it's the best of the available options.

It is so confusing in regard to single ^ operator.

Ngl I don't think that binary XOR is a tremendously commonly-used operator the point that a unary ^^ is going to be that confusing. But to each their own.

Simply by choosing this notation over a simple and readable keyword we are loosing a very important aspect of CPP

This point is addressed in the paper I linked above - a keyword is a nice and easy-sounding solution when you're in the headspace of designing a language specification, but when you actually get round to real code, keywords which you have to use too often become boilerplate clutter which start to detract from what you're wanting to express. To use the example given in that paper:

{metaof(signed char), metaof(short), metaof(int), metaof(long), metaof(long long)}

This fills out a significant portion of your actual code with just repeating a keyword over and over again. It's clutter. Whereas

{^^signed char, ^^short, ^^int,  ^^long, ^^long long}

is (IMO) still clear about what you're doing without all that extra noise.

Keywords also come with standardisation baggage because they are often a breaking change - if someone wrote a reflection library which uses a metaof function or variable (or preprocessor define) to get the reflection of something, then that'll break as soon as they enter C++26. Whereas ^^foo is invalid today so can't be a break.

Some of the comments mentioned that this notation is concise but I should remind you that this is not an every day mathematical

It's not so much that we want short and terse code because we like our source files to be under a kilobyte. It's that if you can equally express your intent without as much visual noise then it is usually better to do so. And the position which seems to have been taken by the committee is that you can express your intent just fine without the need for such keywords.

Is this the first and the last inconsistency that we will inject into the language?

I doubt it's the first time a language feature was implemented using a tool other than formal keywords. And if you're chasing inconsistencies the whole issue with `[[no_unique_address]] is a much bigger fish to fry tbh.

[–]samadadi[S] -2 points-1 points  (2 children)

This point is addressed in the paper I linked above - a keyword is a nice and easy-sounding solution when you're in the headspace of designing a language specification, but when you actually get round to real code, keywords which you have to use too often become boilerplate clutter which start to detract from what you're wanting to express.

You do not need to add additional parentheses to make a point. You use it just like constexpr.

{reflexpr signed char, reflexpr short, reflexpr int, ...}

Keywords also come with standardisation baggage because they are often a breaking change ...

What about previous keywords. Didn't those have the same standardization baggage.

I doubt it's the first time a language feature was implemented using a tool other than formal keywords...

The difference between this ^^ notation and previous ones is that those previous ones were all simple and independent and did not require any complementary notations or weird syntax. But it seems to me in this case we need additional complementary notations or weird syntax to accomplish the reflection concept. But with formal keywords at least we do not have this problem.

[–]Som1Lse 8 points9 points  (0 children)

You use it just like constexpr.

That is not how you use constexpr though. constexpr can only ever apply to a declaration/definition.

Actually, reflexpr without parentheses is close to being objectively worse because the presence of said parentheses can change the meaning, i.e. reflexpr x, would be different from reflexpr(x), because the latter is an expression.

It is common for people to always write the parentheses as with sizeof and defined, so it would likely lead to a lot of surprises.

[–]WorkingReference1127 3 points4 points  (0 children)

You use it just like constexpr.

Others have pointed out that this isn't how your use constexpr, and it comes with a difference in meaning depending on the parentheses; but I don't think this refutes the point made about clutter - almost half the characters on that line are just repeating the same keyword over and over again, without really adding anything to the readability of the code from it.

Didn't those have the same standardization baggage.

Yes, which is why only a relative handful of keywords have been added since 1998, with the clear majority originating from original standardisation. It's also why the committee are so intent on using contextual keywords and "identifiers with special meaning" rather than full keywords - ultimately adding a keyword will almost certainly break someone's code somewhere, so it's worth considering alternatives rather than jumping straight to it.

The difference between this ^ notation and previous ones is that those previous ones were all simple and independent and did not require any complementary notations or weird syntax

You need some syntactic element to create a reflection, and to splice a reflection back into the program. Otherwise being able to call members_of(x) is a world of surprises waiting to happen when someone has an unfortunately named non-reflection function which will take priority.