C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Simplified reflection with tuples

From: <yang.franklin9_at_[hidden]>
Date: Wed, 3 Jan 2024 12:34:26 -0800
> The "splicing" syntax is for reification: the transformation of a
> reflection *value* back into the thing it represents.
You're right, but this only makes splicing more confusing. Why should it iterate (e.g. a class) if it *doesn't* return another reflection value? Transforming a reflection value should be an operation done on the value itself and itself only, like dereferencing a pointer or retrieving the value of a member variable.

> And note that I said "reflection value", not "type".
I said "reflection type" because that is exactly the language used in P1240 and P2996.

> Why would you want to store a function as a type? Again, you're
> thinking too much in terms of template metaprogramming.
I'm not saying that functions *should* be stored as types, but rather that the splicer syntax is considerably weaker for functions, which cannot use the `typename` splicer.

> Also, a `tuple` interface only makes sense for reflecting over the
> contents of an entity. Getting the properties of the entity itself
> (name, etc) wouldn't be available.
Of course. Perhaps I was short-sighted when I said that reflection always returns tuple, as this would also not work on single entities. The tuple could be instead relegated to a member of the reflection type.

> But the "existing approaches" are all painful and difficult to use.
Fold expressions and lambdas make dealing with tuples straightforward. It is really not much different from the proposed `template for` except for syntax, and not requiring another language feature.

> `reflexpr` would also be an operator.
It wouldn't. The Reflection TS defines reflexpr as a function-like specifier, more like static_cast than co_await. The syntax `reflexpr ::` is not valid, it must be `reflexpr(::)`.

Best Regards,
Franklin Yang

-----Original Message-----
From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of Jason McKesson via Std-Proposals
Sent: Wednesday, January 3, 2024 11:56 AM
To: std-proposals_at_[hidden]
Cc: Jason McKesson <jmckesson_at_[hidden]>
Subject: Re: [std-proposals] Simplified reflection with tuples

On Wed, Jan 3, 2024 at 2:05 PM Franklin Yang via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> My proposal was referring to the (much older) Reflection TS 23619. I was unaware of P1240 and P2996 which already addressed my main concern with syntax in Reflection TS. The argument for a single reflection type is sound and not something I had considered, but this does not contradict the main point of my proposal.
>
> I do still believe my point regarding tuples is still valid. P1240/2996 uses a custom scalar type as the "reflection type" and a new splicing syntax to perform operations on this type.

The "splicing" syntax is for reification: the transformation of a
reflection *value* back into the thing it represents. You can perform
plenty of operations on a reflection value that don't involve
splicing.

And note that I said "reflection value", not "type". You're thinking
too much in template metaprogramming terms, not in constexpr coding
terms. All reflection values are of the same type, which is a scalar
type distinct from other types. It's the *value* of a reflection type
that determines what entity it reflects over.

> While powerful, it comes at the expense of being a completely new language feature, and also seems to have difficulties with functions (due to not having a convenient, "lossless" way to store functions as a type, correct me if I'm wrong).

Why would you want to store a function as a type? Again, you're
thinking too much in terms of template metaprogramming.

> If constexpr tuples are used instead, no new syntax for dealing with reflection objects is necessary, and existing approaches to tuples will also work for reflection.

But the "existing approaches" are all painful and difficult to use.
`constexpr` coding is way easier to work with than the template
metaprogramming approaches you have to use when dealing with `tuple`s.

Also, a `tuple` interface only makes sense for reflecting over the
contents of an entity. Getting the properties of the entity itself
(name, etc) wouldn't be available. After all, two different structs
that have the same members are still different structs.

> Due to this library requirement, this also means ^/reflexpr will be unavailable entirely without <reflect> (and <reflect> also includes <tuple>).
>
> On the topic of ^ and reflexpr, I believe a new operator ^ for reflection is unnecessary. The authors of P1240 cite that "with months of practice with implementations that used reflexpr(...) we experienced consistent feedback that that syntax is too “heavy”," but in casual use outside deliberately using reflection, I do not believe its usage to be common enough to justify this change. Apart from not burning additional syntax, reflexpr also has the advantage of being easier to understand for the untrained, and also avoids all discussion of precedence and overloading due to not being an operator.

`reflexpr` would also be an operator. Just because it's spelled with
words doesn't mean it isn't an operator. Issues of precedence and
overloading would still be there. operator `co_await` can be
overloaded, but only because it's allowed to be; operator `...` cannot
be overloaded. So there's no reason why `^` could not be a
non-overloadable operator.
-- 
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-01-03 20:34:30