Boost logo

Boost :

Subject: Re: [boost] phoenix::bind
From: Joel de Guzman (joel_at_[hidden])
Date: 2008-10-02 11:36:46


Peter Dimov wrote:
>>> - \ \
>>> double - /\ f . /\ x. f(f x)
>>> - / \ / \
>>
>> lambda( _f = _1 )[ bind( _f, bind( _f, _1 ) ) ] ?
>
> FWIW, the above doesn't work for me. What is the proper Phoenix way to
> express this double lambda?

Here's an example:

#include <iostream>
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_scope.hpp>

using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;

struct sqr_impl
{
     template <typename Arg>
     struct result
     {
         typedef Arg type;
     };

     template <typename Arg>
     Arg operator()(Arg n) const
     {
         return n * n;
     }
};

function<sqr_impl> sqr;

struct ffx_impl
{
     template <typename ArgF, typename ArgX>
     struct result { typedef ArgX type; };

     template <typename ArgF, typename ArgX>
     ArgX operator()(ArgF f, ArgX arg2) const
     {
         ArgX x = f(arg2);
         return f(x);
     }
};

function<ffx_impl> ffx;

int
main()
{
     std::cout << "Square of " << 5.0 << " is " <<
         sqr(5)()
     << std::endl;

     std::cout << "Double Square of " << 5 << " is " <<
         ffx(lambda[sqr(_1)], 5.0)()
     << std::endl;

     std::cout << "Double Double Square of " << 5 << " is " <<
         ffx(lambda[
                 ffx(lambda[sqr(_1)], _1)
             ],
             5.0
         )()
     << std::endl;

     return 0;
}

This was first discussed in a post by Joel Young (2002!):

     http://lists.boost.org/Archives/boost/2002/03/27181.php

after my naive initial response, I got something like:

     http://lists.boost.org/Archives/boost/2002/03/27250.php

which is a template function that returns a function (doub).

Notes:

* Here, lambda[..] is getting rather unwieldy. I had an earlier
   version with implicit lambdas. With that, you write Double Double Square
   expression more succinctly as:

     ffx(ffx(sqr(_1), _1), 5.0)

* Perhaps there's a terser way similar to your suggestion without using
   phoenix function. I'll investigate on it.

Regards,

-- 
Joel de Guzman
http://www.boostpro.com
http://spirit.sf.net

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