1[section Introduction] 2 3"I like to start documentation with a quote. A nice, pithy one." 4 5['[*_emdash_ Eric Niebler (paraphrased)]] 6 7[heading Motivation] 8 9_Ets_ are rad. They are used in lots of libraries; here are just three of the 10most impressive: 11 12* _spirit_ allows you to write an EBNF-style grammar that gets transformed 13 into a PEG parser. 14 15* _eigen_ allows you to do linear algebra using a very natural and 16 mathematical expression syntax that _eigen_ uses to heavily optimize your 17 expressions. 18 19* _nt2_ takes slightly modified MatLab code and allows it to be parsed and run 20 as highly optimized C++ code. 21 22However, this can come at a high cost. _Ets_ are costly to implement and 23maintain. Each of _eigen_ and Boost.Ublas has a large volume of complex _et_ 24code that cannot be reused elsewhere. 25 26With the language facilities available in the C++14 and C++17 standards, an 27_et_ library is now straightforward to write and use, and has very reasonable 28compile times. 29 30As a quick example, let's say we are doing a bit of matrix math, and we write 31this statement: 32 33 D = A * B + C; 34 35in which all the variables are matrices. It turns out that making a temporary 36for `A * B` and then another temporary for the resulting product plus `C` is 37very inefficient. Most matrix math libraries will have a single function that 38does it in one go: 39 40 mul_add_assign(D, A, B, C); 41 42If you use a matrix library that offers both kinds of syntax, you have to 43notice when some bit of operator-using code should be replaced with some more 44efficient function; this is tedious and error-prone. If the library does not 45provide the operator syntax at all, only providing the more-efficient function 46calls, code using the library is a lot less writable and readable. 47 48Using _yap_, you can write some library code that enables expressions like `D 49= A * B + C` to be automatically transformed into expressions like 50`mul_add_assign(D, A, B, C)`. 51 52Consider another example. Many of us have used Unix command line tools to 53remove duplicate lines in a file: 54 55 sort file_with_duplicates | uniq > file_without_duplicates 56 57We can do something very similar with the standard algorithms, of course: 58 59[typical_sort_unique_usage] 60 61However, it would be much better if our code did exactly that, but with a more 62concise syntax: 63 64[pipable_sort_unique_usage] 65 66This looks much more similar to the Unix command line above. (Let's pretend 67that _range_v3_ doesn't already do almost exactly this.) 68 69_yap_ can be used to do both of these things, in a pretty small amount of 70code. In fact, you can jump right into the _pipable_algorithms_ example if 71you want to see how the second one can be implemented. 72 73[heading Features] 74 75* Simple _ExprTmpl_ and _Expr_ concepts easily modeled by user code. Member 76 and non-member functions on _ExprTmpls_ and _Exprs_ can be added with 77 compact macros, and a reference template that models _ExprTmpl_ exists for 78 prototyping or experimentation. 79 80* Evaluation of _yap_ expressions matches the semantics of builtin C++ 81 expressions as closely as possible. This leads to clearer understanding of 82 the semantics of expression evaluation, because the definitions are local to 83 the types involved. 84 85* Expressions may be transformed explicitly in a user-defined way. This is 86 accomplished with overloaded call operators in a transform class, which are 87 matched against subexpressions in the overall expression. While these 88 member functions may transform a subexpression into anything, a common 89 pattern is to transform only some subexpressions into either new 90 subexpressions or appropriate values and to leave other subexpressions 91 unchanged. This `evaluate(transform(expr))` idiom is expected to be one of 92 the most common ways of using Yap to manipulate and evaluate expressions. 93 94* Functions that operate on or create expressions. Functions are provided 95 (and used within _yap_) that manipulate expressions or their subexpressions. 96 These simplify the process of writing user-defined transforms, for example. 97 98[endsect] 99