Subject: Re: [proto] Thoughts on traversing proto expressions and reusing grammar
From: Eric Niebler (eric_at_[hidden])
Date: 2010-10-15 21:45:45
On Fri, Oct 15, 2010 at 1:35 AM, Thomas Heller
> On Wednesday 13 October 2010 07:10:15 Eric Niebler wrote:
> > I had a really hard time grokking unpack. In Proto, function-types are
> > used to represent function invocation and object construction. The type
> > "X(A,B,C)" means either call "X" with three arguments, or construct "X"
> > with three arguments. In "unpack< X(A, B, C) >" X does *not* get called
> > with three arguments. It gets called like "X( A(_0), A(_1), A(_2), ...B,
> > C )", where _0, _1 are the child nodes of the current expression. This
> > will confuse anyone familiar with Proto. I'd like to replace this with
> > something a little more transparent.
> Ok, i put to together an alternative version. This hooks onto the already
> place transform mechanism and works like this:
> Whenever the first argument to a transform is proto::vararg<Fun> it expands
> the child expressions and applies the Fun transform before the actual
> transform gets called, example:
> struct test
> : proto::when<
> proto::function<vararg<proto::_> >
> , foo(vararg<proto::_>)
> this will call foo(a0, a1 ... aN) where aX are the children of the function
> expressions. Note that you can replace proto::_ by any transform you like.
> Thus making the call look like:
> foo(Fun(a0), Fun(a1), Fun(a2) ...)
Ah, clever! I like it. I'd like to see this generalized a bit though. For
instance, if the transform were instead "foo(_state, vararg<_>)" the
intention is clear, but it doesn't sound like your implementation would
handle this. Actually, the semantics get somewhat tricky. And I fear it
would lead folks to believe that what gets unpacked by the vararg in the
transform corresponds exactly to the children that were matched by the
vararg in the grammar. That's not quite the case, is it?
How about this ... an "unpack" placeholder that works essentially how your
vararg does, but with any Fusion sequence (including Proto expressions), and
the sequence has to be explicitly specified (like the first parameter to
So, instead of foo(vararg<_>), you'd have foo(unpack(_)), where _ means "the
sequence to unpack", not "the transform to apply to each element". If you
want to apply a transform to each element first, you could specify the
transform as a second parameter: foo(unpack(_, Fun)). (That form would
probably use fusion::transform_view internally.)
The implementation of this would be very tricky, I think, because unpack
could appear in any argument position,not just the first. And you'd have to
be careful about compile times. But a fun little problem!
Additionally, you can add whatever arguments you like to the transform.
Which transform? Example?
Proto list run by eric at boostpro.com