Re: Multimethods idioms and library support
On 02/22/11 11:44, itaj sherman wrote:
Is it supposed to be possible do checkout the whole svn tree?
I think so.
It keeps breaking.
Should I better take just part?
Yes, at least according to the following post:
http://article.gmane.org/gmane.comp.lib.boost.user/65939/match=using+sandbox+es
Not unless I finally do some documentation and submit it for
review and it's accepted.
For compisite_storage you mean? Or certain part?
Well, now that you mention it, I'd have to provide documentation for
mpl, at least, and maybe some other variadic template libraries used
by composite storage.
However, I'm still working on other things and still have to
figure a way to make the multiple-dispatch code faster.
A timing comparison w.r.t. boost::variant is in the boost vault
as indicated by this post:
http://article.gmane.org/gmane.comp.lib.boost.user/65480
shows it has quadratic performance w.r.t. number of variants.
What exactly is the name of
"variants"? Is it like number of virtual parameters for the
function?
I was unclear. If you have a types:
typedef variant<T11,T12,...,T1n_1> var_1;
typedef variant<T21,T22,...,T2n_2> var_2;
...
typedef variant<Tm1,Tm2,...,T1n_m> var_m;
and an overloaded function, f, taking m arguments where:
arg_1 can be one of the var_1 template args.
arg_2 can be one of the var_2 template args.
...
arg_m can be one of the var_m template args.
the the compile-time goes up proportional to
n_1*n_2*...*n_m
However, that's just extrapolating from the benchmark results where m
was only 2, but you can see from the curve fits that the time does go
up proportional to n_1*n_2.
Although boost::variant also suffers from this, it does
suffer as badly, as indicated by the timing curves shown
in the vault .zip file.
One measure is the assignment operator.
What does the binary test do?
If you mean the TestVariantBinary.cpp in the sandbox, then it is the
test driver for comparing 3 methods for doing binary visitation:
boost::variant
boost/composite_storage/pack/multiple_dispatch
A specialization similar to boost::variant but optimized
for smart pointers. This was developed by Paul Bormans.
I know nothing about boost development, what does it measure?
I don't know about boost development, but the measurement done
by the Makefile in the variants_compare.zip in the vault is that done
by the g++ compiler when passed the -ftime-report option. More
precisely it measures the TOTAL time output by that report option.
Can you point me to some reading about it?
I'd just try using the -ftime-report option to see the output. I just
picked the TOTAL time part of the output because that seemed good
enough.
So one_of_multiple_dispatch is supposed to do what I want?
Yes, when using reifier_visitor as 1st arg to reify_apply.
What exactly is the relation of it with one_of_maybe?
I should clarify:
There are two methods used:
1) reifier_visitor
2) reifier_switch
Each method uses an overloaded function:
f(c_1,c_2,...,c_m)
where:
c_1 may be from one of a set of types, T11, T21,...,T1n_1
c_2 may be from one of a set of types, T21, T22,...,T2n_2
...
c_m may be from one of a set of types, Tm1, Tm2,...,T2n_m
IOW, there are n_1*n_2*....*n_m overloads of f.
The dispatching is done with a call such as:
reify_apply<reifier_xxx>(f,a_1,a_2,...,a_m)
where:
xxx = visitor or switch
a_1,a_2,...,a_m are abstract arguments which are "reified"
(turned into conrete arguments) by reifier_xxx.
The differences between the abstract types of these two methods is
described next.
1) reifier_visitor:
With virtual functions you have an inheritance hierarchy:
base_type
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
|/ \|/ \|
derive_1 derive_2 derive_3
and base_type has virtual function taking an abstract visitor:
struct abs_visitor
{
virtual void visit(derive_1&)=0;
virtual void visit(derive_2&)=0;
virtual void visit(derive_3&)=0;
};
and each derive_i has the concrete visit functions, reflecting the
standard visitor pattern:
http://www.dofactory.com/Patterns/PatternVisitor.aspx
The correspondence between the above inheritance diagram and the code
here:
http://svn.boost.org/svn/boost/sandbox/variadic_templates
/libs/composite_storage/sandbox/pack
/one_of_multiple_dispatch.test.cpp
is:
here code
---- ----
base_type template<typename ResultType>
struct host_abstract;
derived_I template<unsigned I,typename ResultType>
struct host_concrete;
The abstract types in this method are like base_type.
The concrete types are like derived_I.
2) reifier_switch
In contrast, with reifier_switch, you have a disjoint sum
data structure implemented using a tag or discriminator
and a set of "bounded"(the name used by boost::variant docs)
types. This type is declared as:
enum tag_type
{ tag_1
, tag_2
, tag_3
};
typedef
multiple_dispatch::container
< tags::one_of_maybe
, mpl::integral_c<tag_type,tag_1>//discriminator
, derive_1 //bound type corresponding to tag_1
, derive_2 //bound type corresponding to tag_2
, derive_3 //bound type corresponding to tag_3
>
base_type;
The abstract types in this method are like base_type.
The concrete types are like derived_I.
Does the above make things clearer?
Is it only you working on it?
Yes.
Which parts?
All.
itaj