creating lambda expressions incrementally
Hi, I´m writing a simple expression parser in boost::spirit that can parse a string like "_1 + _2" or "log(_1)" and return a function object that does just that. I used boost::lamda for that and return it as boost::function object. Now I want to parse compositions like "sqrt(_1*_1 + _2*_2)" or "(_1 + _2)*_2" etc. It is easy to parse this of course but I have to create the corresponding function incrementally (in a loop or recursively) and that means I have to keep incremental lambdas until the whole expression has been created. I can not store them as boost::function since they do not work with lambda operator overloading (apart from the fact that it would be too costly). I need a lambda type for these intermediate lambda objects. I guess the auto type specifier would solve this but when will that be available I wonder? The typeof seems to provide a solution though. I was just trying it and it seems to work! Am I on the right track or am I overlooking something? If anyone knows a better solution please tell me! cheers Arnaldur Gylfason
"Arnaldur Gylfason"
IŽm writing a simple expression parser in boost::spirit that can parse a string like "_1 + _2" or "log(_1)" and return a function object that does just that. I used boost::lamda for that and return it as boost::function object. Now I want to parse compositions like "sqrt(_1*_1 + _2*_2)" or "(_1 + _2)*_2" etc. It is easy to parse this of course but I have to create the corresponding function incrementally (in a loop or recursively) and that means I have to keep incremental lambdas until the whole expression has been created. I can not store them as boost::function since they do not work with lambda operator overloading (apart from the fact that it would be too costly). I need a lambda type for these intermediate lambda objects. I guess the auto type specifier would solve this but when will that be available I wonder?
The upcoming version of Boost, 1.34, will contain the Boost.Typeof library that will provide the BOOST_TYPEOF and BOOST_AUTO macros to emulate this facilities. The current snapshot of 1.34 can be obtained from Boost CVS.
The typeof seems to provide a solution though. I was just trying it and it seems to work!
For the Boost.Typeof library to handle lambda expressions, on the platforms where typeof is not natively supported, Boost.Lambda templates need to be registered. The Boost.Typeof documentation describes this using Boost.Lambda as an example. Generally it's up to maintainers of Lambda library to decide if to provide the typeof support, and, to the best of my knowledge, it won't happen in 1.34 :( This registration of the lambda templates can be also done externally (again, see the typeof docs on how to do this), but this has to be kept in-sync with the Lambda templates. The two Boost libraries to support typeof in 1.34 will be spirit and xpressive. Regards, Arkadiy
The upcoming version of Boost, 1.34, will contain the Boost.Typeof library that will provide the BOOST_TYPEOF and BOOST_AUTO macros to emulate this facilities. The current snapshot of 1.34 can be obtained from Boost CVS.
Thanks for the info! Look forward to look at this.
The following works on g++ 4.0.2:
typedef typeof(lambda::_1 + lambda::_2) T1;
T1 f = lambda::_1 + lambda::_2;
typedef typeof(f*lambda::_1) T2;
T2 g = f*lambda::_1;
Let's say I have to parse "(_1 + _2)*_1" and "(_1/_2)*_1". I only get
these command strings at runtime so I don't know the expressions at
compile time.
I have to parse the strings and gradually build the lambda expression.
First the expression within parenthesis has to be created and then the
result combined with *_1
to create the final expression. The type of the first expression is not
the same in the 2 cases so how do I store/refer to the first expression?
All possible templates must be evaluated at compile ime so I somehow must
limit the possibilities at compile time. Furthermore how can I select a
type based on a runtime parameter?
I must admit I have overstretched myself here so I am not sure if I'm
overlooking something or if this is impossible.
I had thought about expression templates but I wouldn't want to duplicate
what the lambda library is already doing. Anyway it seems to me I would
have the same problem as above about
type deduction from a runtime parameter.
All helpful remarks greatly appreciated.
cheers
Arnaldur
"Arkadiy Vertleyb"
I´m writing a simple expression parser in boost::spirit that can parse a string like "_1 + _2" or "log(_1)" and return a function object that does just that. I used boost::lamda for that and return it as boost::function object. Now I want to parse compositions like "sqrt(_1*_1 + _2*_2)" or "(_1 + _2)*_2" etc. It is easy to parse this of course but I have to create the corresponding function incrementally (in a loop or recursively) and that means I have to keep incremental lambdas until the whole expression has been created. I can not store them as boost::function since they do not work with lambda operator overloading (apart from the fact that it would be too costly). I need a lambda type for these intermediate lambda objects. I guess the auto type specifier would solve this but when will that be available I wonder?
The upcoming version of Boost, 1.34, will contain the Boost.Typeof library that will provide the BOOST_TYPEOF and BOOST_AUTO macros to emulate this facilities. The current snapshot of 1.34 can be obtained from Boost CVS.
The typeof seems to provide a solution though. I was just trying it and it seems to work!
For the Boost.Typeof library to handle lambda expressions, on the platforms where typeof is not natively supported, Boost.Lambda templates need to be registered. The Boost.Typeof documentation describes this using Boost.Lambda as an example. Generally it's up to maintainers of Lambda library to decide if to provide the typeof support, and, to the best of my knowledge, it won't happen in 1.34 :( This registration of the lambda templates can be also done externally (again, see the typeof docs on how to do this), but this has to be kept in-sync with the Lambda templates. The two Boost libraries to support typeof in 1.34 will be spirit and xpressive. Regards, Arkadiy _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
"Arnaldur Gylfason"
Let's say I have to parse "(_1 + _2)*_1" and "(_1/_2)*_1". I only get these command strings at runtime so I don't know the expressions at compile time. I have to parse the strings and gradually build the lambda expression.
I think you are trying to achieve an impossible thing. Compiler is the one to create the types. You can control the compiler, so that it creates the types based on a non-trivial algorithm, but all of this should be done at compile time, and based on compile-time input: types and constants hardcoded into your program. By the runtime it's over -- you can't create the types based on the runtime string value. The typeof solves the problem because it works at compile time. Regards, Arkadiy
I think you are trying to achieve an impossible thing. Compiler is the one to create the types. You can control the compiler, so that it creates the types based on a non-trivial algorithm, but all of this should be done at compile time, and based on compile-time input: types and constants hardcoded into your program. By the runtime it's over -- you can't create the types based on the runtime string value. The typeof solves the problem because it works at compile time.
Yes I have come to the same conclusion. Thanks for your response. Some kind of eval would come in handy. Dynamic typing as in Python would also be a blessing here. Of course it would be possible to solve this by calling Python but it would be an expensive function call! cheers Arnaldur
On 10/20/06, Arnaldur Gylfason
I think you are trying to achieve an impossible thing. Compiler is the one to create the types. You can control the compiler, so that it creates the types based on a non-trivial algorithm, but all of this should be done at compile time, and based on compile-time input: types and constants hardcoded into your program. By the runtime it's over -- you can't create the types based on the runtime string value. The typeof solves the problem because it works at compile time.
Yes I have come to the same conclusion. Thanks for your response. Some kind of eval would come in handy. Dynamic typing as in Python would also be a blessing here. Of course it would be possible to solve this by calling Python but it would be an expensive function call!
If C++ had dynamic typing and eval, etc, it would probably be an expensive call as well. It doesn't come for free. cheers
Arnaldur
Tony
If C++ had dynamic typing and eval, etc, it would probably be an expensive call as well. It doesn't come for free.
Well, sometimes ease of programming is more important than speed. You just need to know/find out where it is too expensive (the bottlenecks). Anyway, I'm not expecting dynamic typing to be available in C++. cheers Arnaldur
On 10/17/06, Arnaldur Gylfason
Hi,
I´m writing a simple expression parser in boost::spirit that can parse a string like "_1 + _2" or "log(_1)" and return a function object that does just that. I used boost::lamda for that and return it as boost::function object. Now I want to parse compositions like "sqrt(_1*_1 + _2*_2)" or "(_1 + _2)*_2" etc. It is easy to parse this of course but I have to create the corresponding function incrementally (in a loop or recursively) and that means I have to keep incremental lambdas until the whole expression has been created. I can not store them as boost::function since they do not work with lambda operator overloading (apart from the fact that it would be too costly). I need a lambda type for these intermediate lambda objects. I guess the auto type specifier would solve this but when will that be available I wonder? The typeof seems to provide a solution though. I was just trying it and it seems to work! Am I on the right track or am I overlooking something? If anyone knows a better solution please tell me!
You could do it using expression templates. It should be quite easy to do and very efficient if you aren't going to need to do type-erasure.
cheers
Arnaldur Gylfason
-- Felipe Magno de Almeida
You could do it using expression templates. It should be quite easy to do and very efficient if you aren't going to need to do type-erasure.
Thanks for the response. I thought about it but I'm not so sure this would
solve it.
I have to generate the expression in steps and the corresponding types are
based on runtime parameters so they are not known at compile time.
Anyway boost::lambda is based on expression templates so I would like to
use that instead of duplicating it.
cheers
Arnaldur
"Felipe Magno de Almeida"
Hi,
I´m writing a simple expression parser in boost::spirit that can parse a string like "_1 + _2" or "log(_1)" and return a function object that
does
just that. I used boost::lamda for that and return it as boost::function object. Now I want to parse compositions like "sqrt(_1*_1 + _2*_2)" or "(_1 + _2)*_2" etc. It is easy to parse this of course but I have to create the corresponding function incrementally (in a loop or recursively) and that means I have to keep incremental lambdas until the whole expression has been created. I can not store them as boost::function since they do not work with lambda operator overloading (apart from the fact that it would be too costly). I need a lambda type for these intermediate lambda objects. I guess the auto type specifier would solve this but when will that be available I wonder? The typeof seems to provide a solution though. I was just trying it and it seems to work! Am I on the right track or am I overlooking something? If anyone knows a better solution please tell me!
You could do it using expression templates. It should be quite easy to do and very efficient if you aren't going to need to do type-erasure.
cheers
Arnaldur Gylfason
-- Felipe Magno de Almeida _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (4)
-
Arkadiy Vertleyb
-
Arnaldur Gylfason
-
Felipe Magno de Almeida
-
Gottlob Frege