|
Boost : |
Subject: Re: [boost] Template metaprogramming libraries
From: David Sankel (camior_at_[hidden])
Date: 2011-09-19 11:01:53
On Mon, Sep 19, 2011 at 10:23 AM, David Sankel <camior_at_[hidden]> wrote:
> On Fri, Sep 16, 2011 at 11:37 PM, Joel de Guzman <
> joel_at_[hidden]> wrote:
>
>> On 9/17/2011 2:07 AM, Giovanni Piero Deretta wrote:
>> > On Fri, Sep 16, 2011 at 6:09 PM, David Sankel <camior_at_[hidden]> wrote:
>> >> [...]
>> >> The reason I said that phoenix "somewhat" gets around the bind heritage
>> >> problems, which was obscure I admit, was because phoenix's use of
>> >> traditional bind syntax still leaves a semantic hole.
>> >>
>> >> If someone writes the following:
>> >>
>> >> template< typename F >
>> >> auto doSomething( F f ) -> decltype(...)
>> >> {
>> >> return bind( f, 15, _1)
>> >> }
>> >>
>> >> And then I call doSomething elsewhere like this,
>> >>
>> >> doSomething( bind( g, 12, _1, _2 ) )
>> >>
>> >> , then the result is something most likely unexpected for the user who
>> knows
>> >> what doSomething means (it returns a version of f that has 15 filled in
>> as
>> >> its first argument (λx. λy. x(15,y))), but hasn't read its
>> implementation.
>> >
>> > Boost.Lambda has unlambda, which is documented to prevent exactly this
>> problem:
>> >
>> >
>> http://www.boost.org/doc/libs/1_47_0/doc/html/lambda/le_in_details.html#lambda.unlambda
>> >
>> > With a quick search I couldn't find the phoenix equivalent of
>> > unlambda, but I'm sure there must be.
>>
>> Phoenix does not need it because it has explicit 'lambda'
>> (pun unintentional) which is required for passing in
>> higher-order functions (e.g. to phoenix::for_each).
>> IMO, unlambda is a hack around BLL limitations.
>>
>> This should be the answer David Sankel's concern too (above).
>> I think there's lack of understanding of Phoenix here.
>>
>
> I think you hit the nail on the head with regards to at least my own lack
> of understanding of Phoenix. Sorry to muddy the waters. I'm excited about
> getting a better understanding.
>
> It looks as if boost.lambda requires the writer of a higher order function
> to guard its arguments, using unlambda. boost.phoenix, on the other hand,
> requires the callers of higher order functions to guard its arguments using
> lambda. Is this correct?
>
> For comparison, the boost.lambda example,
>
> for_each(a.begin(), a.end(), std::cout << _1 << ' ');
>
> Would be the following in boost.phoenix?
>
> // assuming _1 is never a function type
> for_each(a.begin(), a.end(), lambda[ std::cout << _1 << ' ' ]);
>
>
> I didn't catch "explicit lambda required for higher order function calls"
> from reading the documentation. I wonder how it could fit in the
> introduction without overly confusing the reader. It seems like a critical
> thing to know IMO.
>
> At any rate, for the record: I am for supporting De Brujin style
>> in Phoenix. The infrastructure is in place. I see no reason why
>> we can't support both.
>>
>
> That would be great and would be enough to entice me to use phoenix as I
> love the simplicity of the De Bruijn sytax.
>
> Maybe something like following would get a dbb implementation on top of
> phoenix (extended with DeBruijn indices)
>
> namespace dbb
> {
> auto _1_1 = boost::phoenix::_1_1;
> //...
>
> auto app = boost::phoenix::bind;
>
> struct lam
> {
> template< typename A>
> auto operator()( A a ) -> decltype( ... )
> {
> return boost::phoenix::lambda( a );
>
oops, that should be return boost::phoenix::lambda[ a ];
}
> };
> }
>
> David
>
>
> --
> David Sankel
> Sankel Software
> www.sankelsoftware.com
> 585 617 4748 (Office)
>
-- David Sankel Sankel Software www.sankelsoftware.com 585 617 4748 (Office)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk