59 lines
2.1 KiB
Plaintext
59 lines
2.1 KiB
Plaintext
[section The YAP Way]
|
|
|
|
There are certain idioms that _yap_ is written to support. Before getting
|
|
into the nuts and bolts of how _yap_ operates, let's define these idioms.
|
|
|
|
[heading _eval_xform_]
|
|
|
|
This is the main idiom you'll see reinforced in the examples. The idea is
|
|
that you capture an expression:
|
|
|
|
auto expr_0 = /* ... */ ;
|
|
|
|
then transform it one or more times:
|
|
|
|
auto expr_1 = boost::yap::transform(expr_0, my_transform_1);
|
|
auto expr_2 = boost::yap::transform(expr_1, my_transform_2);
|
|
// ...
|
|
auto expr_n = boost::yap::transform(expr_n_minus_1, my_transform_n);
|
|
|
|
and then finally you evaluate it:
|
|
|
|
auto const result = boost::yap::evaluate(expr_n);
|
|
|
|
Each call to _xform_ here produces a new _Expr_ that can subsequently be
|
|
transformed. This is conceptually similar to what happens inside many
|
|
compilers. Capturing the expression is analogous to the compiler's parse; the
|
|
transformations are analogous to optimization passes; and the evaluation is
|
|
analogous to code generation.
|
|
|
|
This keeps the meaning of your code quite clear and easy to follow. For this
|
|
reason, I think you should try to use _yap_ in this way when you can.
|
|
|
|
[heading _xform_as_eval_]
|
|
|
|
This is a variant of _eval_xform_, where the _eval_ call at the end is
|
|
unnecessary, because the final (or perhaps only) transform does all the
|
|
evaluation we need.
|
|
|
|
For instance, here is the `get_arity` transform object used in the _calc3_
|
|
example (don't worry too much about the implementation _emdash_ we'll return
|
|
to this later in the docs in much greater detail):
|
|
|
|
[calc3_get_arity_xform]
|
|
|
|
Here is how this might be used:
|
|
|
|
auto expr = 1_p * 2_p;
|
|
auto const arity = boost::yap::transform(expr, get_arity{});
|
|
static_assert(arity.value == 2, "Called with wrong number of args.");
|
|
|
|
In this case, _xform_ produces a non-_Expr_ value, all by itself. We got our
|
|
result without ever needing to call _eval_.
|
|
|
|
[note Whether _xform_ returns an _Expr_ or non-_Expr_ is entirely up to the
|
|
caller. The transform object passed as the second argument to _xform_ defines
|
|
what _xform_'s return type will be.]
|
|
|
|
[endsect]
|