What are the benefits of using Boost.Phoenix?

I can not understand what are the real benefits of using Boost.Phoenix.

When I use it with Boost.Spirit grammars, this is really useful:

double_[ boost::phoenix::push_back( boost::phoenix::ref( v ), _1 ) ] 

When I use it for lambda functions, it is also useful and elegant:

 boost::range::for_each( my_string, if_ ( '\\' == arg1 ) [ arg1 = '/' ] ); 

But what are the benefits of everything else in this library? The documentation says, "Functors are everywhere." I do not understand what is good in this?

+13
c ++ boost boost-phoenix
Feb 16 2018-11-11T00:
source share
5 answers

I will show you what is the critical difference between Boost.Lambda and Boost.Phoenix:

Boost.Phoenix supports (statically) polymorphic functors, while Boost.Lambda bundles are always monomorphic.

(At the same time, in many aspects, the two libraries can be combined, so they are not an exclusive choice.)

Let me illustrate (warning: code not tested.) :

Phoenix

In Phoenix, a functor can transform into a "lazy function" of the Phoenix (from http://www.boost.org/doc/libs/1_54_0/libs/phoenix/doc/html/phoenix/starter_kit/lazy_functions.html )

 struct is_odd_impl{ typedef bool result_type; // less necessary in C++11 template <typename Arg> bool operator()(Arg arg1) const{ return arg1 % 2 == 1; } }; boost::phoenix::function<is_odd_impl> is_odd; 

is_odd is really polymorphic (like the is_odd_impl functor). This is_odd(_1) can act on anything (which makes sense). For example, in is_odd(_1)(2u)==true and is_odd(_1)(2l)==true . is_odd can be combined into a more complex expression without losing its polymorphic behavior.

Lambda try

The closer we can get to this in Boost.Lambda ?, we could define two overloads:

 bool is_odd_overload(unsigned arg1){return arg1 % 2 == 1;} bool is_odd_overload(long arg1){return arg1 % 2 == 1;} 

but to create a "lazy function" lambda, we will need to choose one of two:

 using boost::lambda::bind; auto f0 = bind(&is_odd_overload, _1); // not ok, cannot resolve what of the two. auto f1 = bind(static_cast<bool(*)(unsigned)>(&is_odd_overload), _1); //ok, but choice has been made auto f2 = bind(static_cast<bool(*)(long)>(&is_odd_overload), _1); //ok, but choice has been made 

Even if we determine the version of the template

 template<class T> bool is_odd_template(T arg1){return arg1 % 2 == 1;} 

we will have to bind to a specific instance of the template function, for example

 auto f3 = bind(&is_odd_template<unsigned>, _1); // not tested 

Neither f1 , nor f2 , nor f3 are truly polymorphic, as the choice was made during the binding.

(Note 1: this may not be the best example, since everything may seem to work due to implicit conversions from unsigned to long, but that's another matter.)

To summarize, given the polymorphic function / functor, Lambda cannot bind to the polymorphic function (as far as I know), while Phoenix can. It’s true that Phoenix relies on the “Result of the Protocol” http://www.boost.org/doc/libs/1_54_0/libs/utility/utility.htm#result_of , but 1) at least it's possible, 2) It’s less problem in C ++ 11, where return types are very easy to infer, and this can be done automatically.

In fact, in C ++ 11, Phoenix lizards are still more powerful than the C ++ 11 built-in lambdas. Even in C ++ 14, where lambdas templates are implemented, Phoenix is ​​still more general because it allows a certain level of introspection. (For this, other things, Joel de Guzman (Phoenix developer) was and remains ahead of his time.)

+8
Feb 17 2018-11-11T00:
source share

Well, this is a very powerful lambda language.

I used it to create a prototype for mathematical DSL:

http://code.google.com/p/asadchev/source/browse/trunk/work/cxx/interval.hpp

and much more:

http://code.google.com/p/asadchev/source/browse/#svn%2Ftrunk%2Fprojects%2Fboost%2Fphoenix

+5
Feb 16 '11 at 7:30
source share

Do not look at Boost.Phoenix2.

The evolution of lambda expressions in boost is as follows:

Bind → Lambda, Phoenix2 (as part of the Spirit) → Phoenix3 (as a separate library under development).

The result is a single lambda library with support for polymorphic functors (others will become obsolete).

+3
Feb 28 '11 at 17:28
source share

I have never used Phoenix, but ...

From the documents of the Phoenix library :

The Phoenix library allows you to use FP methods, such as higher-order functions, lambda (unnamed functions), currying (partial function application), and lazy evaluation in C ++

From the Wikipedia article on functional programming :

... functional programming is a programming paradigm that considers computing as an estimate of mathematical functions and avoids state and mutable data. It emphasizes the use of functions, in contrast to the imperative style of programming, which emphasizes state changes

So, Phoenix is ​​a library for incorporating functional programming in C ++.

The main interest in functional programming these days seems to be related to the perceived benefits of correctness and performance due to limiting or eliminating side effects.

That's right, because without the side effects, the code you see is everything that happens in the system. Some other codes will not change your state below you. You can write code much easier without errors in such an environment.

Performance, because without the side effects, the code you write can be safely run in parallel without any resource management primitives or atomic access tricks. Multithreading can be enabled extremely easily, even automatically and works very efficiently.

+2
Feb 16 '11 at 7:21
source share

Functional programming in C ++. It is difficult to explain if you have not previously used a language with proper support for functional programming, such as SML. I tried using Phoenix and found it pleasant, but very impractical in real projects, because it significantly increases compilation time, and error messages are terrible when you do something wrong. I remember getting a few megabytes of errors from GCC when I played with Phoenix. Additionally, debugging deeply nested template instances is PITA. (In fact, these are also all arguments against using most of boost.)

0
Feb 16 '11 at 7:13
source share



All Articles