Boost logo

Boost :

Subject: Re: [boost] [reflect] Introducing Boost.Reflect
From: Matus Chochlik (chochlik_at_[hidden])
Date: 2011-08-07 05:38:51


Sorry for the late response. I've been busy with other
things recently.

On Mon, Aug 1, 2011 at 4:55 PM, Daniel Larimer <dlarimer_at_[hidden]> wrote:
> On Sun, Jul 31, 2011 at 4:11 AM, Matus Chochlik <chochlik_at_[hidden]> wrote:
>
[...]
>> > 1) Does the name describe what it does?
>>
>> Basically yes, but from a quick glance at the docs
>> I'm missing a few things (see below).
>> Generally from my own experience I can say
>> that a reflection library should not start as
>> the support tool for a particular task (RPC,
>> serialization in this case). It should aim to be
>> as general as possible, as there are other situations
>> where reflection can be useful.
>>
>
> I can only agree with you in part.  If the requirement to be as 'general as
> possible' makes the resulting solution less optimal for the most common use
> cases (RPC, Serialization, etc) then your API will be much more difficult
> for 99% of the use cases so that you can support the 1% special cases.
>  This, I believe, is the primary difference in our design philosophy.

This is true if the "generality" of the solution really makes
it visibly less efficient in the distinct use cases, which I believe
is not the problem of Mirror. It is very possible that your solution
compiles faster but in run time the differences *should* be
negligible and also the difference in compilation times is
probably not an order of magnitude or something like that
I say "should", this of course needs to be measured :-).

The advantage of a general solution is that you don't
need to register your classes multiple times if you
want to use them with multiple libraries which somehow
use meta-data describing those classes. You register
it once and those libraries can (transform and) reuse
the meta-data provided by Mirror.
I've tried this with the SOCI database library where
you can automate the implementation of its TypeConversion<>
template or with Boost.Serialization.

>
>
[...]
>
>
> Perhaps if Boost.Mirror provided a "quick and dirty" macro that does what
> BOOST_REFLECT(type, (base)(base2),(member)(member2)...) does then I could
> leverage it.  That said, Boost.Mirror currently depends upon C++0x features
> not available in Visual Studio.  Also, even with a simplified macro,
> Boost.Mirror's greater complexity/flexibility mean significantly longer
> compile times.  Ideally, the reflection should be light-weight enough that
> users automatically add it to everything so they can benefit from automatic
> serialization, json, debug output, and many other tools that can leverage
> reflection.  If adding reflection doubled my compile times then that may be
> a show stopper for many people.

There are the quick registering macros which greatly simplify
the registering see for example here:
http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/puddle/html/da/dc4/puddle_2example_2introspect_person_8cpp-example.html

When the registering and reflection of functions is finished
I'll add such quick-reg macros also for them.

+ there will be automatic registering.

[...]
>
>
>> .
>>
>> > 3) Other reflection attempts have not been accepted for one reason or
>> another.
>> >        - Boost.Reflect vs Boost.Mirror
>>
>> Here should be probably said that Mirror (and AFAIK)
>> Boost.Reflection were not submitted for review (yet)
>> and this is the only reason for them not being accepted.
>> I don't know about Jeremy but I'm planning to do that
>> once it is ready.
>>
>> The compile-time reflection is basically finished (with
>> a few things that need polishing and a few features
>> that can be added later).
>>
>> The two biggest problems I see are that it heavily
>> depends on C++11 and some quick start guide and
>> step-by-step tutorials are missing from the docs.
>>
>
> There is also a significant amount of 'reflection' provided by
> BOOST_FUSION_ADAPT_STRUCT macro.  In fact, I suspect that with the addition
> of a 'name_of<tag>' that it would provide all of the runtime/compile time
> reflection necessary for doing serialization.  Unfortunately, boost::fusion,
> and I suspect Boost.Mirror would introduce substantially more compile time
> overhead than Boost.Reflect when you consider the number of types / meta
> functions created/evaluated.   The benefit of BOOST_FUSION_ADAPT_STRUCT is
> that your types are ready for use with Boost.Spirit.  Also,
> BOOST_FUSION_ADAPT_STRUCT cannot be used to reflect methods.

This is true, as already said above the advantage of
a general solution is that you can reuse the reflected
meta-data in situations which you might not have
anticipated in the beginning.
I didn't try this, but off the top of my head I don't
see anything preventing you to do the same thing
that the BOOST_FUSION_ADAPT_STRUCT does
by transforming the meta-data provided by Mirror
and use the them in code which uses Boost.Fusion
without registering it again.

[...]
>> I couldn't find things like namespace member traversals,
>> support for compile-time metaprogramming, reflection
>> of specifiers (access type, linkage/storage class, etc.)
>> examining/setting members with getter/setter functions
>> (with side effects), just to name some, but maybe I just
>> missed them in the docs.
>>
>> Most of those things are not there because they were not in the design
> spec.
>
> Based upon these comments and the fact that Boost.Mirror is far more robust
> than my code, I think the question becomes which is better:
>
> 1) Move Boost.Reflect into Boost.RPC
> 2) Provide a simpler macro interface to Boost.Mirror
> 3) Two different reflection libraries
> 4) Move BOOST_REFLECT_ANY() into a Boost.Erasure library, simplify
> Boost.Mirror macros.
> 5) Added a small bit of reflection to BOOST_FUSION_ADAPT_STRUCT

I would agree. I admit that Mirror is just "not there yet". And in the future
if you are interested we could add support for optionally getting the meta-data
from Mirror if they're available.

>
> The last thing I want as an end-user is to specify  BOOST_REFLECT...,
> BOOST_MIRROR..., and BOOST_FUSION... for all of their types.

This is exactly what I'm trying to avoid :) There are many libraries
which use some sort of "reflective" programming and their main
problem usually is that they force you to register the same
(very often overlapping) things multiple times if you want
to use them all in one application.

>
> I suspect there is a place for all 3 solutions as they all make different
> tradeoffs in performance, flexibility, and compile times.
>
>
[...]
Regards,

Matus


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk