copyright 2005 eric niebler xpressive: library design on the edge or, how i learned to stop worrying...
TRANSCRIPT
![Page 1: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/1.jpg)
Copyright 2005 Eric Niebler
xpressive:Library Design on the Edge
or, How I Learned to Stop Worrying and Love Template Meta-Programming
![Page 2: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/2.jpg)
Copyright 2005 Eric Niebler
“Why program by hand in five days what you can spend five years of your life automating?”
-- Terrence Parr, author ANTLR/PCCTS
![Page 3: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/3.jpg)
Copyright 2005 Eric Niebler
Overview
Domain-Specific (Embedded) Languages xpressive and Dual-Mode DSEL Design Programming at the Compile-time / Runtime
boundary
![Page 4: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/4.jpg)
Copyright 2005 Eric Niebler
Domain-Specific Languages
Mini-languages, everywhere!– GNU Make– Backus Naur Form– Regular expressions
Syntax, constructs and abstractions for working efficiently in some narrow domain
Not general purpose!
![Page 5: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/5.jpg)
Copyright 2005 Eric Niebler
Why DSLs?
General purpose languages are low-level, procedural
DSLs are high-level and declarative Solution space shares concepts with problem
space DSL code is easier to write, read, reason
about and maintain.
![Page 6: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/6.jpg)
Copyright 2005 Eric Niebler
Embedded DSLs
A DSL in a library All the wholesome goodness of a DSL in the
host language of your choice! C++ is a good host language
– operator overloading– low abstraction penalty
![Page 7: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/7.jpg)
Copyright 2005 Eric Niebler
Expression Templates
(Ab)uses C++ operator overloading to approximate the syntax of the embedded language
Must map embedded language syntax and constructs into C++
Used by:– Blitz++ : high-performance scientific computing– Spirit : parser generator (EBNF)
![Page 8: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/8.jpg)
Copyright 2005 Eric Niebler
DSEL example: EBNF Calculator
group ::= '(' expr ')'fact ::= integer | groupterm ::= fact (('*' fact) | ('/' fact))*expr ::= term (('+' term) | ('-' term))*
rule<> group, fact, term, expr;
group = '(' >> expr >> ')';fact = integer | group;term = fact >> *(('*' >> fact) | ('/' >>
fact));expr = term >> *(('+' >> term) | ('-' >>
term));
![Page 9: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/9.jpg)
Copyright 2005 Eric Niebler
Types of DSELs: Dynamic
Example:SQLCommand c = "SELECT * from Employees";
Advantages:– Unconstrained syntax– Statements can be specified at runtime
Disadvantages:– Syntax errors discovered at runtime– Performance costs of interpretation
![Page 10: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/10.jpg)
Copyright 2005 Eric Niebler
Types of DSELs: Static
Example:double d = (matrix * vector)(3, 4);
Advantages:– Syntax errors checked at compile-time– Aggressive inlining, domain-specific codegen
Disadvantages:– Constrained by rules for legal C++ expressions– Cannot accept new statements at runtime
![Page 11: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/11.jpg)
Copyright 2005 Eric Niebler
Static DSELs...
Dynamic DSELs...
Can’t I have it both ways?
Hrrmmm ...
![Page 12: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/12.jpg)
Copyright 2005 Eric Niebler
Dual-Mode DSEL Interface
Provide both a static and dynamic interface! Sounds good but ...
– Can we really get the advantages of both?– Can we share the implementation to avoid code
duplication?
![Page 13: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/13.jpg)
Copyright 2005 Eric Niebler
"\\w""\\w+""a\\w""a|b""(\\w)\\1""[^a-z]""(?=foo)"
_w+_w'a' >> _was_xpr('a') | 'b'(s1= _w) >> s1~range('a', 'z')before("foo")
Expression TemplateRegular Expression
![Page 14: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/14.jpg)
Copyright 2005 Eric Niebler
Get a Date
// Match a date of the form 10-03-2005
"\\d\\d?-\\d\\d?-\\d\\d(?:\\d\\d)?";
regex date = _d >> !_d >> '-' // match month >> _d >> !_d >> '-' // match day >> _d >> _d >> !(_d >> _d); // match year
# Match a date of the form 10-03-2005
/\d\d?-\d\d?-\d\d(?:\d\d)?/
// Match a date of the form 10-03-2005regex date = regex::compile( "\\d\\d?-\\d\\d?-\\d\\d(?:\\d\\d)?");
![Page 15: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/15.jpg)
Copyright 2005 Eric Niebler
Regex aliases, anyone?
regex date = /* ... */;
// A line in a log file is a date followed by a// space, and everything up to the newline.regex log = date >> ' ' >> +~set['\n'];
regex date = /* ... */;
// A line in a log file is a date followed by a// space, and everything up to the newline.regex log = date >> ' ' >> +~set['\n'];
![Page 16: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/16.jpg)
Copyright 2005 Eric Niebler
Semantic Constraints
// Only match valid datesregex date = (_d >> !_d)[if_is_month()] >> '-' >> (_d >> !_d)[if_is_day()] >> '-' >> (_d >> _d >> !(_d >> _d))[if_is_year()];
// Only match valid datesregex date = (_d >> !_d)[if_is_month()] >> '-' >> (_d >> !_d)[if_is_day()] >> '-' >> (_d >> _d >> !(_d >> _d))[if_is_year()];
![Page 17: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/17.jpg)
Copyright 2005 Eric Niebler
Two great tastes ...... that taste great together
// A line in a log file is a date followed by a// space, and everything up to the newline.regex date = regex::compile(get_date_pattern());
regex log = date >> ' ' >> +~set['\n'];
![Page 18: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/18.jpg)
Copyright 2005 Eric Niebler
“Some people, when confronted with a problem, think, ‘I know, I’ll use
regular expressions.’ Now they have two problems.”
--Jamie Zawinski, in comp.lang.emacs
![Page 19: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/19.jpg)
Copyright 2005 Eric Niebler
Recursive regexen!
regex parens;parens // A balanced set of parens ... = '(' // is an opening paren ... >> // followed by ... *( // zero or more ... keep( +~(set='(',')') ) // of a bunch of things that are // not parens ... | // or ... by_ref(parens) // a balanced set of parens ) // (ooh, recursion!) ... >> // followed by ... ')' // a closing paren ;
![Page 20: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/20.jpg)
Copyright 2005 Eric Niebler
A Regex Calculator?!
regex group, fact, term, expr;
group = '(' >> by_ref(expr) >> ')';fact = +_d | group;term = fact >> *(('*' >> fact) | ('/' >>
fact));expr = term >> *(('+' >> term) | ('-' >>
term));
![Page 21: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/21.jpg)
Copyright 2005 Eric Niebler
Wife: It's a floor wax!
Husband: No, it's a dessert topping!
Announcer: Stop! You're both right. It's a floor wax and a dessert
topping!
-- Saturday Night Live
C++ library design at the edge
![Page 22: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/22.jpg)
Copyright 2005 Eric Niebler
STL, MPL and Fusion, Oh My!
// Just the data, ma’amstd::list<int> integers;
// Just the types, ma’amtypedef mpl::list<int, double, std::string>types;
// Types and data, please!fusion::tuple<int, double, std::string> data = fusion::make_tuple(1, 3.14, "hello");
![Page 23: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/23.jpg)
Copyright 2005 Eric Niebler
The Fusion Library
Heterogeneous data structures STL-influenced
– containers, iterators, algorithms
MPL-compatible by Joel de Guzman, part of Boost.Spirit
– http://spirit.sourceforge.net
![Page 24: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/24.jpg)
Copyright 2005 Eric Niebler
A Simple Fusion-esque List
struct nil = {};
template<class Car, class Cdr = nil>struct cons { Car car; Cdr cdr; cons(Car const & a, Cdr const & d = Cdr()) : car(a), cdr(d) {}};
inline cons<Car,Cdr>make_cons(Car const & a, Cdr const & d){ return cons(a, d); }
![Page 25: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/25.jpg)
Copyright 2005 Eric Niebler
Simple Fusion-esque List, cont.
cons<int,cons<double,cons<std::string> > > data =
make_cons(1, make_cons(3.14, make_cons(std::string("hello"))));
![Page 26: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/26.jpg)
Copyright 2005 Eric Niebler
Fusion-esque algorithms
template<typename F>void for_each(nil, F) {}
template<class Car, class Cdr, class F>void for_each(cons<Car, Cdr> const & l, F f){ f(l.car); for_each(l.cdr, f);}
![Page 27: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/27.jpg)
Copyright 2005 Eric Niebler
Programming challenge!!!
Write the type of a std::pair<First, Second> where Second is a pointer to the whole std::pair ...
std::pair<int, ??? *>std::pair<int, std::pair<int, ???*> *>std::pair<int, std::pair<int, std::pair<int, ???*> *> *>std::pair<int, std::pair<int, std::pair<int, std::pair<int, std::pair<int, std::pair<int,
std::pair<int, std::pair<int,
![Page 28: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/28.jpg)
Copyright 2005 Eric Niebler
Dual-Mode DSEL Design Strategy
recursive algorithms one modular core two binding policies: static and dynamic acyclic data structures
![Page 29: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/29.jpg)
Copyright 2005 Eric Niebler
xpressive Matchers
// Match any single characterstruct any_matcher{ template< class Iter, class Next > bool match(Iter i1, Iter i2, Next const &n)
const { if ( i1 == i2 ) { return false; } return n.match( ++i1, i2 ); }};
![Page 30: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/30.jpg)
Copyright 2005 Eric Niebler
xpressive static Scaffold
template< class Matcher, class Next >struct static_xpression { Matcher matcher; Next next;
template< class Iter > bool match( Iter i1, Iter i2 ) const { return matcher.match( i1, i2, next ); }};
![Page 31: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/31.jpg)
Copyright 2005 Eric Niebler
xpressive dynamic Scaffold
template< class Iter >struct matchable { virtual bool match( Iter, Iter ) const = 0;};
![Page 32: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/32.jpg)
Copyright 2005 Eric Niebler
xpr: dynamic Scaffold, cont.
template< class Matcher, class Iter >struct dynamic_xpression : matchable< Iter > { Matcher matcher; matchable< Iter > * pnext;
bool match( Iter i1, Iter i2 ) const { return matcher.match( i1, i2, *pnext ); }};
![Page 33: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/33.jpg)
Copyright 2005 Eric Niebler
Separation of Concerns
Matchers implement core functionality Scaffolds implement binding policy (static or
dynamic) Matchers are binding-neutral, reusable Best of both worlds
– perf of static binding– flexibility of dynamic dispatch
![Page 34: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/34.jpg)
Copyright 2005 Eric Niebler
References
xpressive:– http://boost-sandbox.sf.net/libs/xpressive
Spirit and Fusion– by Joel de Guzman– http://spirit.sf.net
![Page 35: Copyright 2005 Eric Niebler xpressive: Library Design on the Edge or, How I Learned to Stop Worrying and Love Template Meta- Programming](https://reader036.vdocuments.net/reader036/viewer/2022062517/56649ef35503460f94c059df/html5/thumbnails/35.jpg)
Copyright 2005 Eric Niebler
Questions?