
On 3/30/2010 2:02 PM, Manjunath Kudlur wrote:
With Phoenix or lambda-like DSELs implemented with Proto, it is easy to implement stuff when the expected actual parameters to the lambda expressions are primitive types. When I want to pass arbitrary types to the lambda expression and manipulate it in the lambda expression, things become complex. For example, consider the following function :
struct point { float x; float y; };
float sum(point p) { return p.x+p.y; }
If I want to have a lazy version of this function, I cannot simply do (arg1.x + arg1.y)(p). I have to implement functions that return Proto or Phoenix expressions and use it in the language. In the above case, it would look something like (point_get_x_(arg1) + point_get_y_(arg2))(p). So for every type I want to support in the DSEL, I have to implement lazy versions of functions to get and set the type members, or call some methods. In other words, the language has to be aware of all the data types that can be used with it. <snip>
Not necessarily. These these can be added to your DSEL post-hoc, and there are some fun games you can play with proto's operator->*. Consider the following program: #include <cassert> #include <boost/proto/proto.hpp> namespace proto = boost::proto; struct point { int x, y; }; proto::terminal<int point::*>::type x = {&point::x}; proto::terminal<int point::*>::type y = {&point::y}; struct arg_ {}; proto::terminal<arg_>::type arg = {{}}; struct micro_lambda : proto::or_< proto::when< proto::terminal<arg_> , proto::_state > , proto::otherwise< proto::_default<micro_lambda> > > {} eval; int main() { point p = {2,4}; int r = eval( arg->*x + arg->*y, p ); assert( r == p.x + p.y ); } You can't overload operator dot (.), but proto makes up for it by automatically interpreting ->* as if it were dot. Proto evaluates the LHS and RHS, and as long as the RHS is something like a data member pointer or member function pointer that can be applied to the LHS, it all Just Works. It works with mutation through the data member pointer, too: eval( arg->*x *= 21, p ); assert( p.x == 42 ); HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com