Boost logo

Boost :

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


Peter Dimov wrote:
> Joel de Guzman:
>
>> Maybe you want:
>>
>> let(_a = 0)[ ++_a ]
>
> Maybe I do. :-)
>
>> phx::for_each(_1, lambda[std::cout << _1 << std::endl])
>>
>> Notice that like protect, there are two function invocations happening
>> here.
>
> The confusion here comes from the fact that the above would work if
> lambda[] had "unlambda" semantics, that is, if it returned a function
> object that was not a phoenix expression.

No, that is not the "unlambda" semantics. There needs to be 2 function
application there: 1) the one that substitutes the stl container for _1
(the leftmost _1) and 2) the one that substitutes the container's
element for _1 (the rightmost _1). The key point here is that phx.lambda
(and BLL protect), *returns a lambda-functor that returns a lambda-functor*.
unlambda OTOH simply returns a plain functor (non-actor). A plain functor
can only do one function application (bear in mind that this is phoenix
for_each (lazy), not std::for_each (eager)).

Here's the crucial difference (using BLL) highlighting the difference:

     {
         int x = 5;
         int r = bind(_1, _2)(unlambda(_1), x);
         BOOST_TEST(x == 5);
     }

     {
         int x = 5;
         int r = bind(_1, _2)(protect(_1)(), x);
         BOOST_TEST(x == 5);
     }

Notice that protect *requires* the additional function application:

     protect(_1)()

I'm CC'ing Jaakko for clarification. It's also plausible that I am
confused.

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