Subject: Re: [boost] phoenix::bind
From: Joel de Guzman (joel_at_[hidden])
Date: 2008-10-02 18:53:42
Peter Dimov wrote:
> Now that I've seen what Phoenix can do, I think that, were I to design a
> Boost.Lambda2, I'd probably go with a classic lambda of the form
> lambda( _x, _y )[ _x + _y ]
> where the inner _x + _y is not a function object, and it is the lambda
> that turns it into one. (That is, the evaluation of an inner expression
> would be done with eval(expr, args...) and not with expr(args...).)
That is actally what's happening internally already.
> Local state would look like
> lambda( _x, _a = 0 )[ _a += _x ]
> and one can also extend this to lambda( byval, ... ) and lambda( byref,
> ... ) to control the default capture behavior.
I'd spell function
> application inside a lambda as apply( f, x ) and not as bind, leaving
> the latter as an alias for lambda[ apply ].
> So \f \x f (f x) would be
> lambda( _f )[ lambda( _x ) [ apply( _f, apply( _f, _x ) ) ] ]
> Using the above example as a test for this theory:
>> lambda(_a = arg2)
>> push_back(arg1, _a)
> In lambda terms, it's something like
> \x,y for_each( x, \z push_back( z, y ) )
> so (with lazy for_each and push_back):
> lambda( _x, _y )[ for_each( _x, lambda( _z )[ push_back( _z, _y ) ] ) ]
> This implies that a lambda must be able to access an outer scope. I
> wonder how could one do that. :-) The outer lambda should be able to do
> some term rewriting, I guess.
Phoenix already does that. See let visibility:
It's one of the early requirements. I'm quite happy with it. Hah,
those were one of the sleepless coding nights. Example
from the doc:
let(_x = 1, _y = ", World")
// _x here is an int: 1
let(_x = "Hello") // hides the outer _x
cout << _x << _y // prints "Hello, World"
anything you can do with "let", you can do with "lambda".
> I should also be able to spell that as:
> lambda( _x, _y )[ for_each( _x, lambda( _x )[ push_back( _x, _y ) ] ) ]
> with the two _x being properly scoped.
Yep. Phoenix can do that. A local variable may hide an outer local
variable. Here, we just reuse the locals for arguments to the
lambda as well. So, in current terms, this:
lambda( _x, _y )[ _x + _y ]
is just this:
lambda( _x = _1, _y = _2 )[ _x + _y ]
Very cool suggestion, Peter!
-- 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