On Wed, Feb 21, 2018 at 5:30 PM, Steven Watanabe via Boost < boost@lists.boost.org> 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@lists.boost.org> 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