intro.qbk 4.0 KB

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