$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Mat Marcus (mmarcus_at_[hidden])
Date: 2002-02-22 12:38:24
I would really like to see us further explore GenVoca layered designs. I 
didn't think there was much chance of this after the limited response to 
<http://groups.yahoo.com/group/boost/message/23654>. This stuff is hard to 
explain, but maybe by taking it in smaller pieces we can establish a useful 
dialog. So, rather than another lengthy post on the subject, I'll try to 
stimulate discussion by diving into a couple of small specifics.
I see two main differences between C&E-style GenVoca and policy based 
design:
Policy based design (PBD)
  * PBD uses Policies in two simultaneous roles, implemetation class 
templates and as a configuration DSL.
  * PBD favors policies which don't communicate; collaboration is 
orchestrated by a "manager" class template (e.g. SmartPtr)
GenVoca
  * GenVoca uses layers (generalized policies) for the implementation class 
templates. A separate configuration generator is used to parse the 
configuration DSL
  * GenVoca offers (but does not require) the possiblity of communication 
between layers
There is an appealing simplicity in PBD: no configuration generator is 
required. However, for some domains, the flexibility and reusabiity offered 
by GenVoca probably outweighs the cost of the additional required 
machinery. Of course, if you plan on writing a configuration generator 
anyway then I see no advantage to using policies instead of layers; in this 
case policies are merely the degenerate case of a zero-layered design. 
Perhaps an example from the aformentioned post would help clarify.
Example (from the aformentioned post)
I will examine a  feature model/configuration DSL  reverse engineered from 
Andrei's SmartPtr.  Then I will indicate how the policy based design might 
map to a (degenerate) single layered GenVoca design. In this case the 
configuration generator, omitted until sufficient interest, is quite 
trivial, as the DSL and the ICCL are more or less identical. Things only 
get interesting when we try to coax out the appropriate communicating 
layers. See the above post for a little more detail.
 Front End/Feature Model/Configuration DSL
   SmartPtr                :   SmartPtr [ElementType,
                                          OwnershipPolicy,
                                          ConversionPolicy,
                                          CheckingPolicy,
                                          StoragePolicy]
    ElementType             :   T
    OwnershipPolicy         :  RefCounted | RefCountedMT
                               | ComRefCounted | RefLinked
                               | DeepCopy
                               | DestructiveCopy | NoCopy
    ConversionPolicy        :  AllowConversion
                               | DisallowConversion
    CheckingPolicy          :  AssertCheck
                               | AssertCheckStrict
                               | NoCheck
                               | RejectNullStatic
                               | RejectNull
                               | RejectNullStrict
    StoragePolicy           :  DefaultSPStorage
We can use this feature model as the configuration DSL. Orthogonality is 
natural on the front end.
Back End/Single Layered Genvoca Grammar/ICCL
    SmartPtr                : SmartPtr[Config]
Config
    ElementType             :   T
    OwnershipPolicy         :  RefCounted | RefCountedMT
                               | ComRefCounted | RefLinked
                               | DeepCopy
                               | DestructiveCopy | NoCopy
    ConversionPolicy        :  AllowConversion
                               | DisallowConversion
    CheckingPolicy          :  AssertCheck
                               | AssertCheckStrict
                               | NoCheck
                               | RejectNullStatic
                               | RejectNull
                               | RejectNullStrict
    StoragePolicy           :  DefaultSPStorage
or in C++:
struct MyRefCountedConvertibleAssertCheckFooPtrConfig // simplistic: no 
layering or communication
{
    typedef OwnershipPolicy   RefCounted;
    typedef ConversionPolicy  AllowConversion;
    typedef CheckingPolicy    AssertCheck;
    typedef StoragePolicy     DefaultSPStorage;
    typedef Foo               ElementType;
};
template <class Config>
class SmartPtr : public Config
{
 // ...
};
of course the client will not want to declare
   SmartPtr<MyRefCountedConvertibleAssertCheckFooPtrConfig>
instead GenVoca uses a configuration generator and DSL so client code will 
look like
    typename SmartPtrGenerator<T, ref_counted,
                default_storage, assert_checking,
                disallow_conversion>::type;
(Aside: typedef templates would be nice here). The implementation of such a 
SmartPtrGenerator on top of our SmartPtr ICCL is straightforward, using 
standard metaprogramming techniques and I will leave it for another article 
if there is any interest. Or see for example C&E page 587 and page 654.
These explanations and examples are intentionally incomplete. But if there 
is any interest I'd be happy to explore this stuff in more detail -- 
questions, comments or corrections are very welcome.
Mat
#####
    Beman> --- In boost_at_y..., Beman Dawes <bdawes_at_a...> wrote: Tim,
    Beman>
    Beman> You might also read Mat Marcus'
    Beman> http://groups.yahoo.com/group/boost/message/23654 if you
    Beman> haven't done so already.
    Beman>
    Beman> The techniques you, Dave, Jeremy, and Mat are exploring are
    Beman> on the research frontier of generic and generative
    Beman> programming.  Very few people understand them fully.  I
    Beman> know I don't.
    Beman>
    Beman> For these techniques to migrate into the main stream, there
    Beman> is a real need for descriptive material that is easier to
    Beman> understand.  Andrei Alexandrescu did a great job in his
    Beman> book at making policies easy enough to understand that many
    Beman> of us could start using them in everyday programming.
    Beman> Someone needs to do something similar for combining
    Beman> generative programming, named template parameters, and
    Beman> policy-based design into a unified, understandable,
    Beman> technique.
    Beman>
    Beman> --Beman
    Tim> Thanks for the insight.  I have read Mat's post, and if his
    Tim> experience was anything like mine, I found GenVoca to be
    Tim> rather cumbersome.  It wasn't clear to me how to divide the
    Tim> architectural layers.  That difficulty is partly why I've
    Tim> explored using policy- based design as a "back-end" to a
    Tim> generator, rather than something like GenVoca.  Policies are
    Tim> just easier to understand.