extra/boost/boost_1_77_0/doc/html/yap.html
| | Home | Libraries | People | FAQ | More |
Copyright © 2018 T. Zachary Laine
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
"I like to start documentation with a quote. A nice, pithy one."
— Eric Niebler (paraphrased)
Expression templates are rad. They are used in lots of libraries; here are just three of the most impressive:
However, this can come at a high cost. Expression templates are costly to implement and maintain. Each of Eigen and Boost.Ublas has a large volume of complex expression template code that cannot be reused elsewhere.
With the language facilities available in the C++14 and C++17 standards, an expression template library is now straightforward to write and use, and has very reasonable compile times.
As a quick example, let's say we are doing a bit of matrix math, and we write this statement:
D=A\*B+C;
in which all the variables are matrices. It turns out that making a temporary for A * B and then another temporary for the resulting product plus C is very inefficient. Most matrix math libraries will have a single function that does it in one go:
mul\_add\_assign(D,A,B,C);
If you use a matrix library that offers both kinds of syntax, you have to notice when some bit of operator-using code should be replaced with some more efficient function; this is tedious and error-prone. If the library does not provide the operator syntax at all, only providing the more-efficient function calls, code using the library is a lot less writable and readable.
Using Boost.YAP, you can write some library code that enables expressions like D = A * B + C to be automatically transformed into expressions like mul_add_assign(D, A, B, C).
Consider another example. Many of us have used Unix command line tools to remove duplicate lines in a file:
sortfile\_with\_duplicates|uniq\>file\_without\_duplicates
We can do something very similar with the standard algorithms, of course:
std::vector\<int\>v1={0,2,2,7,1,3,8};std::sort(v1.begin(),v1.end());autoit=std::unique(v1.begin(),v1.end());std::vector\<int\>constv2(v1.begin(),it);assert(v2==std::vector\<int\>({0,1,2,3,7,8}));
However, it would be much better if our code did exactly that, but with a more concise syntax:
std::vector\<int\>v1={0,2,2,7,1,3,8};std::vector\<int\>constv2=sort(v1)|unique;assert(v2==std::vector\<int\>({0,1,2,3,7,8}));
This looks much more similar to the Unix command line above. (Let's pretend that Range-v3 doesn't already do almost exactly this.)
Boost.YAP can be used to do both of these things, in a pretty small amount of code. In fact, you can jump right into the Pipable Algorithms example if you want to see how the second one can be implemented.
evaluate(transform(expr)) idiom is expected to be one of the most common ways of using Yap to manipulate and evaluate expressions.|
Last revised: August 05, 2021 at 09:53:06 GMT
|
|