Boost logo

Boost :

Subject: Re: [boost] [phoenix] how do i achieve this type of extension of phoenix
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2013-12-28 08:34:14


On Wednesday, December 25, 2013 16:21:45 Hui Li wrote:
> I want to extend the phoenix library with my own expressions in a specific
> way. Would appreciate any help!! Thanks!
>
> The code below is what i want to achieve, with the intended behavior
> specified in the comments. The goal is to first build an expression (the
> expr0), and later bind some value to certain nodes and turn them into
> different types of nodes with internal states (expr1) but preserve the
> structure of the expression tree, and also be able to modify the internal
> states of those nodes.
>
> My question is, how to define myplus, mymult, myinit, and myreset to make it
> work?

I've played around with it a little bit, this can be done without defining
additional functors and functions like myplus_f, mymult_f etc.
Here it is: https://gist.github.com/sithhell/8159502

Some notes: I use lambda and locals to model the different scopes. As such, the
first operand on line 20 needs to be captured in a lambda as well (don't like
it that much either). Additionally, i didn't like the reset too much, it's a
bit contradictory to the whole functional programming idea. as such my
suggested solution is just to call init again. Is there any special
constrained why you need to "reset" rather than an additional init?

Cheers,

Thomas

>
> using boost::phoenix::arg_names::arg1;
> using boost::phoenix::arg_names::arg2;
> using boost::phoenix::arg_names::arg3;
>
> // how should i define myplus, mymult and myinit, so that
> // expr1 is arg1 + myplus_f<double>(3.0)(1,arg2) +
> mymult_f<double>(3.0)(2,arg3) auto expr0 = arg1 + myplus(1,arg2) +
> mymult(2,arg3);
> auto expr1 = myinit( expr0, 3.0 );
>
> // evaluate expr1 with actual arguments
> double r = expr1(1,2,3);
>
> // modify the internally held values of myplus_f<double>(3.0) and
> mymult_f<double>(3.0) // so that expr1 becomes equivalent to arg1 +
> myplus_f<double>(5.0)(1,arg2) + mymult_f<double>(5.0)(2,arg3)
> myreset(expr1, 5.0);
>
> // evaluate with new value members of myplus_f and mymult_f
> double r2 = expr1(1,2,3);
>
>
> myplus_f and mymult_f are defined as follows:
>
> template < typename T >
> struct myplus_f
> {
> T value;
> explicit myplus_f(const T& v):value(v){}
>
> void reset(const T& new_value) { value = new_value; }
>
> template < typename Lhs, typename Rhs >
> auto operator()(const Lhs& lhs, const Rhs& rhs) const ->
> decltype(value+lhs+rhs) {
> return value + lhs + rhs;
> }
> };
>
> template < typename T >
> struct mymult_f
> {
> T value;
> explicit mymult_f(const T& v):value(v){}
>
> void reset(const T& new_value) { value = new_value; }
>
> template < typename Lhs, typename Rhs >
> auto operator()(const Lhs& lhs, const Rhs& rhs) const ->
> decltype(value*lhs*rhs) {
> return value * lhs * rhs;
> }
> };
>
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk