Date: Wed, 23 Feb 2022 15:27:52 -0500
Thanks Daveed and Matus and others for your very eloquent presentations and thoughts today. Some belated thoughts:
Matus’s templated metaobject type is implicitly convertible to meta::info. As Gasper noted, that is the key feature: in Matus’ formulation, an object is returned which arguably has greater functionality than meta::info, but can also be silently converted to it.
Given this, the matter of how the two perform on the same algorithms is beside the point: if the meta::info version is faster, just call that with one of Matus’s template instantiations; the cost is merely that of the implicit conversion + the original instantiation. (And often not even that: it would probably be trivial for an implementation to check if the type of the LValue to which a reflection is being assigned is meta::info, and if so, avoid the instantiation in the first place.)
On the other hand, others contend that it is nearly as simple to go in the other direction: always return a meta::info, and simply wrap it into a template arg where needed. This seems fairly effortless and does not deviate from what has already been accepted, and anyway it is difficult to visualize the examples in which Matus’s template-only algorithms would truly be needed (which I trust exist but agree w/Wyatt do need to be spelled out more plainly for those of us without quite as much familiarity).
There is however another consideration which might argue in favor of Matus’s approach in a larger sense: leaving room for *other, future* improvements upon meta::info. A stronger type system might well be demanded as reflection comes into broad use, to e.g. help the compiler verify a particular metafunction is valid under all inputs. Also object-oriented reflection could make a comeback as consteval performance improves. There are a multitude of ways we might want to pack more information into the type of a reflection in the future.
Matus’s proposal hints at the path to taking full advantage of meta::info’s speed and simplicity at the present while leaving room for these future possibilities:
When the type of a reflection is written as `meta::info`, it must be a meta::info.
When the type of a reflection is specified as `auto`, *the specification should not make any restrictions on the actual type of the object*, only that it is implicitly convertible to meta::info. (In other words, precisely the metaobject concept Matus suggested reflections should return.)
The same should apply to reflection queries returning e.g. vector<info> or span<info>: the type of members_of must return an object at least implicitly convertible to those, but whether the user specifies the Lvalue type as `auto` or `span<info>` can be significant to the compiler.
(One tweak of the above which could be more acceptable: specify auto&& as the type when you want the maximum type info, e.g. Matus’s template instantiation, and `auto` when you want the meta::info. Similar to string literals, for which `auto&&` may be a `const char[3]` while `auto` is always a `const char *`.)
Now, of course whether that auto-typed object has the semantics of Matus's template instantiations is a question that needs to be settled; this is only to point out the more general, future-proofing *advantage* of returning auto-typed reflections and encouraging the use of auto in place of meta::info (so that e.g. if a stronger reflection typing system emerges, the compiler can take advantage of it automatically). The reflection query library can still be written as taking meta::info parameters for optimum speed.
Daveed raised the legitimate concern of type deduction. A special type deduction rule would indeed probably be necessary to ensure meta::info gets preference in templated overload situations; I’m not clear on what complexities that might introduce.
In sum Matus’s proposed extension of the reflection type system at a minimum raises questions sure to emerge again down the line.
> On Feb 23, 2022, at 12:47 PM, Matus Chochlik via SG7 <sg7_at_[hidden]> wrote:
>
> Hi SG7,
>
> As we've discussed I'm sending the links to:
> - the meeting C++ talk (the audio is messy for the first minute and half, if gets better afterwards, you can skip to 1:30 nothing of value will be lost)
> https://www.youtube.com/watch?v=BP0gsVy502w <https://www.youtube.com/watch?v=BP0gsVy502w>
>
> - The slides from that talk:
> https://matus-chochlik.github.io/mirror/latex/meeting_cpp.pdf <https://matus-chochlik.github.io/mirror/latex/meeting_cpp.pdf>
>
> -The slides from today (again):
> https://matus-chochlik.github.io/mirror/latex/value_vs_type_based.pdf <https://matus-chochlik.github.io/mirror/latex/value_vs_type_based.pdf>
>
> - The reflection "library" is implemented here:
> https://github.com/matus-chochlik/mirror/tree/develop/include/mirror <https://github.com/matus-chochlik/mirror/tree/develop/include/mirror>
>
> - Examples and use-cases:
> https://github.com/matus-chochlik/mirror/tree/develop/example/mirror <https://github.com/matus-chochlik/mirror/tree/develop/example/mirror>
>
> - Doxygen docs (W.I.P.):
> https://matus-chochlik.github.io/mirror/doxygen/ <https://matus-chochlik.github.io/mirror/doxygen/>
>
> - Compiler-explorer sandbox (the implementation is done by me (far from a compiler-guru/sensei) so it is horribly un-optimized):
> https://compiler-explorer.com/z/9931EW6xb <https://compiler-explorer.com/z/9931EW6xb>
> https://compiler-explorer.com/z/W9csaWPfq <https://compiler-explorer.com/z/W9csaWPfq>
>
> - The clang fork (the goal of which was to implement the TS) is here:
> https://github.com/matus-chochlik/llvm-project <https://github.com/matus-chochlik/llvm-project>
>
> HTH,
> Feedback on any of these things is very welcome.
>
> --Matus
>
> P.S. I've attached the slides for another talk that goes through the use-cases (I'd maybe like to torture some other conference audiences with that, so please do not share the attached PDF outside of WG21. Thank you! :) )
> <use_cases.pdf>--
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
Matus’s templated metaobject type is implicitly convertible to meta::info. As Gasper noted, that is the key feature: in Matus’ formulation, an object is returned which arguably has greater functionality than meta::info, but can also be silently converted to it.
Given this, the matter of how the two perform on the same algorithms is beside the point: if the meta::info version is faster, just call that with one of Matus’s template instantiations; the cost is merely that of the implicit conversion + the original instantiation. (And often not even that: it would probably be trivial for an implementation to check if the type of the LValue to which a reflection is being assigned is meta::info, and if so, avoid the instantiation in the first place.)
On the other hand, others contend that it is nearly as simple to go in the other direction: always return a meta::info, and simply wrap it into a template arg where needed. This seems fairly effortless and does not deviate from what has already been accepted, and anyway it is difficult to visualize the examples in which Matus’s template-only algorithms would truly be needed (which I trust exist but agree w/Wyatt do need to be spelled out more plainly for those of us without quite as much familiarity).
There is however another consideration which might argue in favor of Matus’s approach in a larger sense: leaving room for *other, future* improvements upon meta::info. A stronger type system might well be demanded as reflection comes into broad use, to e.g. help the compiler verify a particular metafunction is valid under all inputs. Also object-oriented reflection could make a comeback as consteval performance improves. There are a multitude of ways we might want to pack more information into the type of a reflection in the future.
Matus’s proposal hints at the path to taking full advantage of meta::info’s speed and simplicity at the present while leaving room for these future possibilities:
When the type of a reflection is written as `meta::info`, it must be a meta::info.
When the type of a reflection is specified as `auto`, *the specification should not make any restrictions on the actual type of the object*, only that it is implicitly convertible to meta::info. (In other words, precisely the metaobject concept Matus suggested reflections should return.)
The same should apply to reflection queries returning e.g. vector<info> or span<info>: the type of members_of must return an object at least implicitly convertible to those, but whether the user specifies the Lvalue type as `auto` or `span<info>` can be significant to the compiler.
(One tweak of the above which could be more acceptable: specify auto&& as the type when you want the maximum type info, e.g. Matus’s template instantiation, and `auto` when you want the meta::info. Similar to string literals, for which `auto&&` may be a `const char[3]` while `auto` is always a `const char *`.)
Now, of course whether that auto-typed object has the semantics of Matus's template instantiations is a question that needs to be settled; this is only to point out the more general, future-proofing *advantage* of returning auto-typed reflections and encouraging the use of auto in place of meta::info (so that e.g. if a stronger reflection typing system emerges, the compiler can take advantage of it automatically). The reflection query library can still be written as taking meta::info parameters for optimum speed.
Daveed raised the legitimate concern of type deduction. A special type deduction rule would indeed probably be necessary to ensure meta::info gets preference in templated overload situations; I’m not clear on what complexities that might introduce.
In sum Matus’s proposed extension of the reflection type system at a minimum raises questions sure to emerge again down the line.
> On Feb 23, 2022, at 12:47 PM, Matus Chochlik via SG7 <sg7_at_[hidden]> wrote:
>
> Hi SG7,
>
> As we've discussed I'm sending the links to:
> - the meeting C++ talk (the audio is messy for the first minute and half, if gets better afterwards, you can skip to 1:30 nothing of value will be lost)
> https://www.youtube.com/watch?v=BP0gsVy502w <https://www.youtube.com/watch?v=BP0gsVy502w>
>
> - The slides from that talk:
> https://matus-chochlik.github.io/mirror/latex/meeting_cpp.pdf <https://matus-chochlik.github.io/mirror/latex/meeting_cpp.pdf>
>
> -The slides from today (again):
> https://matus-chochlik.github.io/mirror/latex/value_vs_type_based.pdf <https://matus-chochlik.github.io/mirror/latex/value_vs_type_based.pdf>
>
> - The reflection "library" is implemented here:
> https://github.com/matus-chochlik/mirror/tree/develop/include/mirror <https://github.com/matus-chochlik/mirror/tree/develop/include/mirror>
>
> - Examples and use-cases:
> https://github.com/matus-chochlik/mirror/tree/develop/example/mirror <https://github.com/matus-chochlik/mirror/tree/develop/example/mirror>
>
> - Doxygen docs (W.I.P.):
> https://matus-chochlik.github.io/mirror/doxygen/ <https://matus-chochlik.github.io/mirror/doxygen/>
>
> - Compiler-explorer sandbox (the implementation is done by me (far from a compiler-guru/sensei) so it is horribly un-optimized):
> https://compiler-explorer.com/z/9931EW6xb <https://compiler-explorer.com/z/9931EW6xb>
> https://compiler-explorer.com/z/W9csaWPfq <https://compiler-explorer.com/z/W9csaWPfq>
>
> - The clang fork (the goal of which was to implement the TS) is here:
> https://github.com/matus-chochlik/llvm-project <https://github.com/matus-chochlik/llvm-project>
>
> HTH,
> Feedback on any of these things is very welcome.
>
> --Matus
>
> P.S. I've attached the slides for another talk that goes through the use-cases (I'd maybe like to torture some other conference audiences with that, so please do not share the attached PDF outside of WG21. Thank you! :) )
> <use_cases.pdf>--
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
Received on 2022-02-23 20:27:55