On Jan 15, 2022, at 2:34 PM, Daveed Vandevoorde via SG7 <sg7@lists.isocpp.org> wrote:



On Jan 15, 2022, at 1:39 PM, Peter Dimov via SG7 <sg7@lists.isocpp.org> wrote:

Daveed Vandevoorde wrote:
Hello reflecting friends,

(And Happy New Year!)

I’ve uploaded on the 2022 Teleconferences wiki for SG-7 an updated version
of P1240 (which has also been submitted for the next mailing).

Changes include:
— The syntax agreements that SG-7 voted through P2320 (e.g., prefix ^
instead of reflexpr(…) to create reflections)
— The proposed metafunctions now use span and string_view instead
of vector and string
— Various corrections and clarifications based on reader feedback and
implementation experience

I think that it might be worth discussing Matus's alternative representation
of reflections. Roughly, while P1240 has something equivalent to

struct info {  uintptr_t id; };

Matus instead suggests (if I understand correctly)

template<uintptr_t id> struct info {};

This implies that one does

   constexpr info x = ^T;

under P1240 and

   constexpr auto x = ^T;

under the hypothetical alternative.

The arguments against this are (again IIUC) performance - the latter
causes much more template instantiations because functions are like

   consteval some_func( auto refl );

instead of

   consteval some_func( info refl );

However, there's a difference in usability, too. In the first case, one can
always splice [:refl:] inside some_func (because it's an instantiation context),
whereas in the second case, one cannot.


That’s a massive price to pay, though (_every_ reflection value costs a type instance).  And if you’re willing to pay it, you can with P1240.  You can write:

template<info R> struct Refl { ... };

and now you have that same capability.

The reverse is not true.

(You could also write:

template<info refl> consteval some_func();

which is  slightly cheaper in terms of compilation resources and different notation.)

Daveed


There is also the matter of a) iteration, and b) a more serious performance reason I have not seen mentioned elsewhere.  

Iteration: special iteration mechanisms are required, unless you want to require a functional style as Matus’s implementation uses: see Andrew/Wyatt/Lock3’s `template for(auto …)` or `for(constexpr auto …)`, which instantiates each iteration.  Non-range-based iteration (while statements, non-range for statements etc.) are almost certainly not feasible.

(Aside: for those interested in trying the `template for` with Matus’s implementation or other template-instantiation based implementations, I extracted it into a clean branch here: 
https://github.com/drec357/llvm-project/tree/dwr-feature-template-for
And a merge of this with Matus’s implem and my string injection implem for code generation is her:
https://github.com/drec357/llvm-project/tree/meta-all
though it is a bit behind Matus’s.)

More serious performance reason:

First, suppose the reflection library included a queries for for fetching other declarations in the TU: say, it's sibling declarations and parent/children.

```
std::meta::get_next_decl(auto r)
std::meta::get_prev_decl(auto r)
std::meta::get_parent_decl(auto r)
std::meta::get_first_child_decl(auto r)
```

Now suppose a user decides they want to interface with reflection in an object-oriented style:
```
template<auto R>
struct DeclWrapper {
  auto nextDecl() { return DeclWrapper <decltype(std::meta::get_next_decl(R))>{}; }
  auto prevDecl() {…}
  auto getParent() { … }
  …
};

#include … // lots of stuff, big translation unit

int foo;
constexpr auto foorefl = DeclWrapper <decltype(^foo)>()>();
```

What happens when `foorefl` is instantiated?  

First each member of DeclWrapper<decltype(^foo)> must be instantiated, which means we have to instantiate each return type, each of which is a DeclWrapper, which itself has to be instantiated, …

The chain reaction results in instantiations of DeclWrappers for *every single declaration in the translation unit*.

It is probably easier to just figure out narrow solutions resolving the precise deficiencies of value-based implementation than dealing with these issues.



--
SG7 mailing list
SG7@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/sg7