Boost logo

Proto :

Subject: Re: [proto] : Proto transform with state
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2010-11-18 07:15:55


Thomas Heller <thom.heller_at_...> writes:
> Thomas Heller <thom.heller_at_...> writes:
> > Eric Niebler <eric_at_...> writes:
> <snip>
> > > Notice that the Renumber algorithm needs to be invoked twice with the
> > > same arguments. In this case, we can avoid the runtime overhead of the
> > > second invocation by just using the type information, but that's not
> > > always going to be the case. There doesn't seem to be a way around it,
> > > either.
> > >
> > > I think Proto transforms need a "let" statement for storing intermediate
> > > results. Maybe something like this:
<snip>
> > >
> > > It's fun to think about this stuff, but I wish it actually payed the
bills.
> >
> > Ok ... I implemented let!
> >
> > Here goes the renumbering example:
> > http://codepad.org/K0TZamPb
> >
> > The change is in line 296 rendering RenumberFun to:
> > struct RenumberFun
> > : proto::fold<
> > _
> > , make_pair(fusion::vector<>(), proto::_state)
> > , let<
> > _a(Renumber(_, second(proto::_state)))
> > , make_pair(
> > push_back(
> > first(proto::_state)
> > , first(_a)
> > )
> > , type_of<second(_a) >
> > )
> > >
> > >
> > {};
> >
> > The implementation of let actually was quite easy ... here is how it works:
> >
> > let<Locals, Transform> is a transform taking definitions of local variables
> and
> > the transform these locals will get applied to.
> > A local definition is in the form of: LocalName(LocalTransform)
> > If the specified transform has LocalName embedded, it will get replaced by
> > LocalTransform.
> > I also implemented the definition of more than one local ... this is done by
> > reusing proto::and_:
> >
> > let<proto::and_<LocalName0(LocalTransform0), ...
LocalNameN(LocalTransformN)>,
> > Transform>
> > The replacement is done from the end to the beginning, making it possible to
> > refer in a LocalTransformN to a LocalNameN-1, this gets replaced
> automatically!
>
> Ok, the implementation in the previous post had some bugs.
> Here is a updated one: http://codepad.org/ljjBYqHr
>
> With the relevant example, showing of reuse of locals:
> struct RenumberFun
> : proto::fold<
> _
> , make_pair(fusion::vector<>(), proto::_state)
> , let<
> proto::and_<
> _a(second(proto::_state))
> , _b(Renumber(_, _a))
> >
> , make_pair(
> push_back(
> first(proto::_state)
> , first(_b)
> )
> , type_of<second(_b) >
> )
> >
> >
> {};

Ok ... it was pointed out that you might want to give _a a meaningful name.
So here it goes:

struct RenumberFun
  : proto::fold<
        _
      , make_pair(fusion::vector<>(), proto::_state)
      , let<
            Renumber(Renumber(_, second(proto::_state)))
          , make_pair(
                push_back(
                    first(proto::_state)
                  , first(Renumber)
                )
              , type_of<second(Renumber) >
            )
>
>
{};

Which aliases Renumber to Renumber(_, second(proto::_state)) which is quite
cool. It turns out that you can have any type as the local name ;)


Proto list run by eric at boostpro.com