Boost logo

Proto :

Subject: Re: [proto] Thoughts on traversing proto expressions and reusing grammar
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2010-10-14 02:16:27


On Wednesday 13 October 2010 22:46:40 Eric Niebler wrote:
> On 10/13/2010 11:54 AM, Thomas Heller wrote:
> > On Wednesday 13 October 2010 20:15:55 Eric Niebler wrote:
> >> Possibly. But now, you're explicitly constructing a terminal with a
> >> reference_wrapper as a value. Proto doesn't know how to treat
> >> reference_wrapper when evaluating Phoenix expression because you
> >> haven't told it how. You'll need to fit this into your evaluation
> >> strategy somehow. It will be a good test to see how truly extensible
> >> your proposed mechanism is.
> >
> > Ok, i have to admit, it gets a little messy here. We probably would
> > like to specialize our generic evaluator based on the terminal tag.
> > Which takes care of: a) regular terminals (as in captured by value) b)
> > things like reference wrapper c) placeholders as you suggested them.
> > I don't have a good solution to that problem. Anyone else?
>
> Not sure yet. This needs thought.
>
> > The only thing i can think of right know is to introduce a special tag
> > for a reference. It would be great if we could make proto::terminals
> > with different tags, or let's not call them terminals but nullary
> > expressions.
>
> Proto already lets you define nullary expressions with custom tags.
> Might be handy here.
>
> <snip>

Ok, this looks promising. I haven't been able to construct nullary
expressions with proto::make_expr. So i assumed it was not possible :)
Reinvestigating. I think this might be a good solution to phoenix::value and
phoenix::reference.

> >> Simple. They become:
> >> typedef
> >>
> >> actor<proto::terminal<phoenix_placeholder<mpl::int_<0> > >::type>
> >>
> >> arg1_type;
> >>
> >> arg1_type const arg1 = {};
> >>
> >> And then your default evaluator changes to handle placeholders:
> >> template <typename Tag>
> >> struct generic_evaluator
> >>
> >> : proto::or_<
> >> :
> >> proto::when<
> >>
> >> proto::terminal<phoenix_placeholder<proto::_> >
> >>
> >> , fusion_at(proto::_value, proto::_state)
> >>
> >> , proto::_default<eval_grammar>
> >>
> >> {};
> >>
> >> or something. If placeholder are part of the core, there's nothing
> >> stopping you from doing this. You can also handle reference_wrappers
> >> here, but that feels like a hack to me. There should be a way for
> >> end-users to customize how Phoenix handles terminal types like
> >> reference_wrapper.
> >
> > The problem i am having with approach to tackle placeholders, is that i
> > still can't see how this would solve the grand "placeholder
> > unification" problem
>
> There are two aspects of "placeholder unification":
>
> 1) Using phoenix placeholders in other EDSLs.
> 2) Using placeholders from other EDSL in Phoenix.
>
> (1) is solved by making the phoenix domain a sub-domain of
> proto::default_domain. (2) is not yet solved, but can be trivially done
> so by changing the above evaluator to:
>
> struct Placeholder
>
> : proto::when<
>
> proto::and_<
> proto::terminal<proto::_>
> , proto::if_<boost::is_placeholder<proto::_value>()>
>
> , fusion_at(proto::_value, proto::_state)
>
> {};
>
> template<class Tag>
> struct generic_evaluator>
>
> : proto::or_<
>
> Placeholder
> , _default<eval_grammar>
>
> {};
>
> Note the use of some hook-able boost::is_placeholder trait.
>
> <snip>

Right, that makes sense!

For the rest, see the other post.
<snip> see other post.


Proto list run by eric at boostpro.com