[phoenix][lambda] lambda to phoenix translation: get sig (signature) from actor
hi, what is the translation of boost.lambda
typename LambdaExp::template sig
On 5/30/2010 8:35 AM, alfC wrote:
hi, what is the translation of boost.lambda
typename LambdaExp::template sig
::type in Boost.Phoenix?
my best try was: actor<LambdaExp>::result< vector<InputType> >::type
but it doesn't compile.
I'm not sure if it's a good idea to go beyond the documented features. The more you do this, the more work you'll have to do in porting it to Phoenix-3. What is it you are trying to do? Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon
I'm not sure if it's a good idea to go beyond the documented features. The more you do this, the more work you'll have to do in porting it to Phoenix-3. What is it you are trying to do?
thank you for the advise.
What I am trying to do mixes boost.units with lambda/phoenix
expressions
I had a function that worked well with lambda and I am trying to make
it work with phoenix.
In a previous post I asked how to translate the argument, which is
done, of the following function (called qawc) and
now I am trying to translate the result type.
template
::type::value, get<0>(f_expr.args) (bind(&quantity<UnitIntegrandDomain>::from_value, _1)) ), boost::numeric::interval<double>( lower(iv).value() , upper(iv).value() ), c ); return ret_type::from_value(ret); }
On 5/30/2010 9:48 AM, alfC wrote:
I'm not sure if it's a good idea to go beyond the documented features. The more you do this, the more work you'll have to do in porting it to Phoenix-3. What is it you are trying to do?
thank you for the advise. What I am trying to do mixes boost.units with lambda/phoenix expressions I had a function that worked well with lambda and I am trying to make it work with phoenix. In a previous post I asked how to translate the argument, which is done, of the following function (called qawc) and now I am trying to translate the result type.
I am not sure if this is the best way to do it in either Lambda nor
Phoenix (I'm pretty sure that even with lambda, you are going beyond
the documentation, no?). However, I am not knowledgeable enough of the
domain you are involved with, nor do I know what qawc means.
Anyway...
In Phoenix (see Actors In Detail at: http://tinyurl.com/24wlduz),
a lambda is always an:
actor<Eval>
The return type deduction of Eval are (given varying arguments):
typename apply_actor
I am not sure if this is the best way to do it in either Lambda nor Phoenix (I'm pretty sure that even with lambda, you are going beyond the documentation, no?).
I guess that extracting subexpressions (and subexpression types) of an expression goes beyond Lambda and Phoenix documentation. and yes that is what I am trying to do.
However, I am not knowledgeable enough of the domain you are involved with, nor do I know what qawc means.
qawc is an interface to http://tinyurl.com/gslqwac now you can imagine what I a trying to do, basically extract the function information from a lambda expression.
In Phoenix (see Actors In Detail at:http://tinyurl.com/24wlduz), a lambda is always an:
actor<Eval> The documented "result" protocol for Eval is:
T::result<Env>::type
where Env is your environment (See the link I provided above). Typically, for client use, the environment is just basic_environment<...>.
well I tried this and didn't work
typename
actor<LambdaExp>::result ::type now my closest guess is
typename actor<LambdaExp>::template
result
On 5/30/10 11:26 AM, alfC wrote:
I am not sure if this is the best way to do it in either Lambda nor Phoenix (I'm pretty sure that even with lambda, you are going beyond the documentation, no?).
I guess that extracting subexpressions (and subexpression types) of an expression goes beyond Lambda and Phoenix documentation. and yes that is what I am trying to do.
However, I am not knowledgeable enough of the domain you are involved with, nor do I know what qawc means.
qawc is an interface to http://tinyurl.com/gslqwac now you can imagine what I a trying to do, basically extract the function information from a lambda expression.
In Phoenix (see Actors In Detail at:http://tinyurl.com/24wlduz), a lambda is always an:
actor<Eval> The documented "result" protocol for Eval is:
T::result<Env>::type
where Env is your environment (See the link I provided above). Typically, for client use, the environment is just basic_environment<...>.
well I tried this and didn't work typename actor<LambdaExp>::result
::type
now my closest guess is typename actor<LambdaExp>::template result
::type which is almost the type I am trying to generate but it is of 'const&' (const reference) type which is a problem for a return type because of 'returning reference to temporary'.
Perhaps just remove ref if you want the value? Anyway, I think I need to look more closely. But right now, I'm quite full. It seems you have it working anyway, no? If so, can we get back to this later so I can offer a better library solution? I'm very interested with this and how we can do better with the current Phoenix-3 rewrite. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
which is almost the type I am trying to generate but it is of 'const&' (const reference) type which is a problem for a return type because of 'returning reference to temporary'.
Perhaps just remove ref if you want the value?
yes, I did that
typename remove_reference
Anyway, I think I need to look more closely. But right now, I'm quite full. sorry if I made you waste your time, and thank you for your help so far.
It seems you have it working anyway, no?
yes and no, the argument and the return type are fully translated from
lambda to phoenix
the final result is:
typename remove_reference<
typename actor<LambdaExp>::template
result const& iv
){ Now the problem is to translate the body of the function,
the original Boost.Lambda version was
bind(
&LambdaExp::template sig ::type::value,
get<0>(f_expr.args)
(bind(&quantity<UnitIntegrandDomain>::from_value, _1))
),
which I can not translate into boost.phoenix, my best try is
boost::phoenix::bind(
&remove_reference On one hand Phoenix seems more powerful than BLL but BLL is more
intuitive to go into the internal works. If so, can we get back to this later so I can offer a better library
solution? I'm very interested with this and how we can do better
with the current Phoenix-3 rewrite. Sure, glad you are interested. Let me know if you need more details,
what I am doing now is an experimental code to
interface GSL routines from C++ that uses lambda expression.
Experimental in the sense that I want to see how far I can get with
Phoenix in terms of building a natural (mathematical) language
interface to numerical routines.
In this experimental code
I am trying to make the functions smart enough to recognize *simple*
patterns in the expression.
In this example, it recognizes the singularity (at 3.) in the integral
integral( f( _1 )/(_1 - 3.) , interval(2., 4.));
other simple expressions are
solve( f(_1) == 2.);
just to give you an idea. I am not sure if am repeating someone else's
work but when I see expression templates in C++ I see numerical and
symbolic mathematics converge into the perfect language to do
scientific computing. Of course the patterns do not need to be
necessarily *simple* in the future, once we master Phoenix we can go
beyond to write transformation rules for expression, in order to do
that I must gain complete access to the internal subexpressions and
subexpression types.
Thank you,
Alfredo
On 5/30/2010 10:50 PM, alfC wrote: <snip>
Sure, glad you are interested. Let me know if you need more details, what I am doing now is an experimental code to interface GSL routines from C++ that uses lambda expression. Experimental in the sense that I want to see how far I can get with Phoenix in terms of building a natural (mathematical) language interface to numerical routines. In this experimental code I am trying to make the functions smart enough to recognize *simple* patterns in the expression. In this example, it recognizes the singularity (at 3.) in the integral
integral( f( _1 )/(_1 - 3.) , interval(2., 4.));
other simple expressions are
solve( f(_1) == 2.);
just to give you an idea. I am not sure if am repeating someone else's work but when I see expression templates in C++ I see numerical and symbolic mathematics converge into the perfect language to do scientific computing. Of course the patterns do not need to be necessarily *simple* in the future, once we master Phoenix we can go beyond to write transformation rules for expression, in order to do that I must gain complete access to the internal subexpressions and subexpression types.
In that case, I think your best bet is to build your own DSEL using Proto. Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news. The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions. Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting. -- Eric Niebler BoostPro Computing http://www.boostpro.com
In that case, I think your best bet is to build your own DSEL using Proto.
that is the point, I don't want to build another DSEL (and wouldn't know how to do it with proto), C++ language as a DSEL is enough to experiment with the expressions right know, and that is the reason I ended up using phoenix.
Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news.
The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions.
well that would be perfect. I don't imagine how (just because I still don't understand proto) but in any case I should be able to do it for the current phoenix, ... in principle. or I'll rather wait for Phoenix3.
Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting.
sure. I am surprised that I am using phoenix in a way that was not intended for. What are expression for if not to take them appart and analyse piece by piece? Thank you, Alfredo
On 5/31/2010 11:35 AM, Eric Niebler wrote:
On 5/30/2010 10:50 PM, alfC wrote: <snip>
Sure, glad you are interested. Let me know if you need more details, what I am doing now is an experimental code to interface GSL routines from C++ that uses lambda expression. Experimental in the sense that I want to see how far I can get with Phoenix in terms of building a natural (mathematical) language interface to numerical routines. In this experimental code I am trying to make the functions smart enough to recognize *simple* patterns in the expression. In this example, it recognizes the singularity (at 3.) in the integral
integral( f( _1 )/(_1 - 3.) , interval(2., 4.));
other simple expressions are
solve( f(_1) == 2.);
just to give you an idea. I am not sure if am repeating someone else's work but when I see expression templates in C++ I see numerical and symbolic mathematics converge into the perfect language to do scientific computing. Of course the patterns do not need to be necessarily *simple* in the future, once we master Phoenix we can go beyond to write transformation rules for expression, in order to do that I must gain complete access to the internal subexpressions and subexpression types.
In that case, I think your best bet is to build your own DSEL using Proto. Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news.
The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions.
Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting.
Indeed very timely. See also: http://tinyurl.com/37mguzo "phoenix domain language (to write mathematical formulas)" (Cc'ing the author) This is not the first time Phoenix has been used this way. Yet one of the reasons why I insist on a simple extension interface. I think we're on the right track, Eric. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon
Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting.
Indeed very timely. See also:http://tinyurl.com/37mguzo "phoenix domain language (to write mathematical formulas)"
right, since C++ is "mathematical enough" (or as mathematical as it
can be with the small set of available symbols [+,-,/,*,==]) then
phoenix is mathematical enough,
creating a mathematical DSEL on proto probably won't be better than
phoenix [except for very specific mathematical area, e.g. tensor
manipulation]
this discussion is very nice, and now that you know the context maybe
I can recast the question:
I am extracting a subexpression (don't know the exact name in phoenix
jargon)
called LambdaExp, by recognizing the pattern
actor
alfC wrote:
creating a mathematical DSEL on proto probably won't be better than phoenix [except for very specific mathematical area, e.g. tensor manipulation]
I'll shamelessly point you to my workon such a topic tha I presented a Boost'Con 2010: http://www.filetolink.com/188d42d9
On 5/31/2010 4:18 PM, alfC wrote:
(this in the context of boost.units is necesary to adimensionalize an expression, apply a normal function and then restore de dimension), this is the closest I got but doesn't work:
bind( &result_type::value, actor<LambdaExp>(at_c<0>(f_expr))( // Question: what goes here? to apply the subexpr. bind( &quantity<UnitIntegrandDomain>::from_value, arg_names::arg1 ) ) // end here );
What are the args to LambdaExp? Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon
bind( &result_type::value, actor<LambdaExp>(at_c<0>(f_expr))( // Question: what goes here? to apply the subexpr. bind( &quantity<UnitIntegrandDomain>::from_value, arg_names::arg1 ) ) // end here );
What are the args to LambdaExp?
f_expr can be any phoenix expression taking one argument the
integration variable, and returning a quantity.
the object of LambdaExp type can be any phoenix subexpression of
f_expr, typically should represent another function that takes one
argument the integration variable (e.g. quantity) and returns another
quantity
to give you an example:
if f_expr was "(boost::phoenix::arg_names::_1 * 0.2 )/
(boost::phoenix::arg_names::_1-wp)" (wp is a constant)
the type of LambdaExp is
composite
On May 31, 3:07 am, Joel de Guzman
What are the args to LambdaExp?
ok, I think I simplified the code as much as possible to its bare
bones, here it is a compilable example of what I need.
as you see first there is a lambda version which is concise and works,
then follows the phoenix attempt.
I have and expression template _1 + 1. or arg1 + 1. and I am trying to
compose it with two free functions (sq and div2).
Take _1 + 1. or arg1 + 1. as black box (this is an example of what the
subexpression that the pattern matching recognizes in the full
example).
The precise question is what is the phoenix translation of the lambda
"bind(&div2, (_1+1.)(bind(&sq, _1) ) )" ?
[ _1+1. is just an example, in the real code is some argument passed
and can be any expression, in other words "(_1+1.)" must remain there,
so (bind(&div2, (bind(&sq,arg1) ) + 1. ) is not the answer I am
looking for].
the full minimal example is below:
#include
On 6/2/10 5:03 PM, alfC wrote:
On May 31, 3:07 am, Joel de Guzman
wrote: What are the args to LambdaExp?
ok, I think I simplified the code as much as possible to its bare bones, here it is a compilable example of what I need. as you see first there is a lambda version which is concise and works, then follows the phoenix attempt. I have and expression template _1 + 1. or arg1 + 1. and I am trying to compose it with two free functions (sq and div2). Take _1 + 1. or arg1 + 1. as black box (this is an example of what the subexpression that the pattern matching recognizes in the full example).
The precise question is what is the phoenix translation of the lambda "bind(&div2, (_1+1.)(bind(&sq, _1) ) )" ? [ _1+1. is just an example, in the real code is some argument passed and can be any expression, in other words "(_1+1.)" must remain there, so (bind(&div2, (bind(&sq,arg1) ) + 1. ) is not the answer I am looking for].
the full minimal example is below:
#include
#include #include #include double sq(double x){return x*x;} double div2(double x){return x/2.;} using namespace std; int main(){ {// first with lambda using namespace boost::lambda; double const dos = 2.; boost::function
f( bind(&div2, (_1+1.)(bind(&sq, _1) ) ) ); cout<< f(dos)<< endl; // returns 2.5 } {// second with phoenix using namespace boost::phoenix; using namespace boost::phoenix::arg_names; double const dos = 2.; // boost::function f( (bind(&div2, (arg1+1.) (bind(&sq,arg1) ) ) )); //doesn't work, what goes here?? // cout<< f(dos)<< endl; // should return 2.5 } return 0; }; I tried all sorts of things, I am starting to think that Phoenix is not designed for this (although it is supposed to be a generalization of BLL.)
You are right. Phoenix is not designed to compose that way.
I've taken note of this use case and it probably be incorporated
into 3.0.
However, take note that we do things differently in Phoenix.
This use case is typically done using phoenix::functions and
phoenix higher order functions called phoenix::lambda. Here's
how I would write your code in Phoenix:
First, I'll start with a phoenix function taking in a higher order
phoenix function: _1+1.
boost::function
On May 31, 3:07 am, Joel de Guzman
wrote: First, I'll start with a phoenix function taking in a higher order phoenix function: _1+1. boost::function
f = divdoub(_1, lambda[_1+1.0]);
Hi Joel DG., Eric N. and Steven W.,
thank you so much for your help after all these posts I can call my
little experiment a success,
a nice mashup between, numeric libraries (not from Boost),
Boost.Units, Boost.Interval and Boost.Phoenix (Boost.Lambda didn't
make it to the end).
It can be resumed in this actual line of code
cout << qawc( _1 / (_1 - 3.*si::hertz), interval(2.*si::hertz,
4.*si::hertz)) << endl; //outputs 2 hertz
let me explain what it does (in can be a nice case study for
Boost.Phoenix3),
1) it takes a phoenix expression [e.g. _1/(_1-3.*si::hertz)], and
singles out the denominator which has a singularity at 3.*si::hertz
this qawc function stores the numerator and the singular point, it
does that by a sort of pattern matching in the function argument:
actor
On 6/5/2010 6:21 AM, alfC wrote:
On May 31, 3:07 am, Joel de Guzman
wrote: First, I'll start with a phoenix function taking in a higher order phoenix function: _1+1. boost::function
f = divdoub(_1, lambda[_1+1.0]); Hi Joel DG., Eric N. and Steven W., thank you so much for your help after all these posts I can call my little experiment a success,
Great! <snip>
let me explain what it does (in can be a nice case study for Boost.Phoenix3), 1) it takes a phoenix expression [e.g. _1/(_1-3.*si::hertz)], and singles out the denominator which has a singularity at 3.*si::hertz this qawc function stores the numerator and the singular point, it does that by a sort of pattern matching in the function argument: <snip>
To repeat: in Phoenix 3, this will be easier. Rather that writing your own custom pattern matching meta-program, you'll be able to use Proto grammars to find patterns in Phoenix expressions, and you'll use Proto transforms to modify the expressions however you want. -- Eric Niebler BoostPro Computing http://www.boostpro.com
On 5/31/2010 3:39 AM, Joel de Guzman wrote:
On 5/31/2010 11:35 AM, Eric Niebler wrote:
On 5/30/2010 10:50 PM, alfC wrote: <snip>
Of course the patterns do not need to be necessarily *simple* in the future, once we master Phoenix we can go beyond to write transformation rules for expression, in order to do that I must gain complete access to the internal subexpressions and subexpression types.
In that case, I think your best bet is to build your own DSEL using Proto. Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news.
The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions. <snip>
Indeed very timely. See also: http://tinyurl.com/37mguzo "phoenix domain language (to write mathematical formulas)"
(Cc'ing the author)
This is not the first time Phoenix has been used this way. Yet one of the reasons why I insist on a simple extension interface. I think we're on the right track, Eric.
The "phoenix domain language" thread argues for a simple extension interface, but that this thread argues for powerful expression introspection and transformation facilities: two separate things, both of which will be nicely addressed by our current working design. Yes, we're on the right track. Finally. -- Eric Niebler BoostPro Computing http://www.boostpro.com
participants (4)
-
alfC
-
Eric Niebler
-
Joel de Guzman
-
Joel Falcou