# Boost :

Subject: Re: [boost] [yap] review part 3: tests + misc + summary
Date: 2018-02-23 08:24:41

On Wed, Feb 21, 2018 at 5:30 PM, Steven Watanabe via Boost <
boost_at_[hidden]> wrote:

> AMDG
>
> On 02/20/2018 11:16 PM, Zach Laine via Boost wrote:
> > On Tue, Feb 20, 2018 at 9:29 AM, Steven Watanabe via Boost <
> > boost_at_[hidden]> wrote:
> > <snip>
> >>>> - Combining transforms isn't exactly easy, because of
> >>>> the way transforms recurse. For example, if I have
> >>>> two transforms that process disjoint sets of nodes,
> >>>> I can't really turn them into a single transform.
> >>>>
> >>>
> >>> I'm not necessarily opposed to the idea, but how would combining
> >> transforms
> >>> work? Would each node be matched against multiple transform objects,
> >> using
> >>> whichever one works, or something else?
> >>>
> >>
> >> Probably the behavior is to choose the
> >> first one that matches. That would make
> >> it easy to write a transform that overrides
> >> some behavior of another transform. (Note
> >> that I really have no idea how to make
> >> something like this actually work.)
> >
> >
> > Well if *you* don't... :) I'll wait until you get back to me with more
> > details before I bite off such a feature.
> >
>
> So, here's a concrete example of the problem
> I'm trying to solve:
>
> Suppose that Alice defines let(_a=1)[_a] as
> as we talked about, along with a let_transform
> that can be used with transform_evaluate.
> Now, Bob also thinks that Yap is really cool
> and defines switch_(1_p)[case_<1>("one"), case_<2>("two")]
> with a corresponding switch_transform which,
> again, works with transform_evaluate. Finally,
> Carol comes along and wants to write:
> let(_a=5)[switch_(_a)[case_<5>("Five")]].
> How do we combine let_transform and switch_transform?
>
> It may be that the best solution is for let_transform
> and switch_transform to use CRTP (which doesn't require
> anything from Yap).
>
> The original reason I was thinking this way is that
> if transforms were somehow composable, then we wouldn't
> need transform_evaluate, as it could be implemented like:
> auto transform_evaluate(auto&& expr, auto&& t) {
> return transform(expr, combine_transforms(t, default_evaluate{}));
> }
>

It took some doing, but I really liked this idea, so I've implemented
this. These major changes have just gone in:

1) Add the ability to pass an arbitrary number of transform objects to
transform. At each expression, an attempt is made to match the
tag-transforms of the first transform object, then the
expression-transforms of the first transform object, the tag-transforms for
the second transform object, the expression-transforms of the second
transform object, etc.
2) Add a new function evaluation(), that returns a transform object that
can be used to evaluate an expression.
3) Add a new transform_strict() function that gives a hard error on any
failure to match an expression, but that is otherwise just like transform().

It's very light on testing, but it's working for all the tests and examples
that use evaluate(), which is now implemented in terms of evaluation().
And the chained transforms work at least for simple cases.

Zach