|
Boost : |
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk