Subject: Re: [boost] De Bruijn Bind (alternate bind syntax) Interest?
From: David Sankel (camior_at_[hidden])
Date: 2010-09-03 21:29:57
On Fri, Sep 3, 2010 at 7:46 PM, Joel de Guzman <joel_at_[hidden]>wrote:
> On 9/4/2010 5:42 AM, Dave Abrahams wrote:
>> On Fri, Sep 3, 2010 at 5:22 PM, David Sankel<camior_at_[hidden]> wrote:
>>> On Fri, Sep 3, 2010 at 4:46 PM, Dave Abrahams<dave_at_[hidden]> wrote:
>>> On Fri, Sep 3, 2010 at 2:52 PM, Larry Evans<cppljevans_at_[hidden]>
>>>> wrote:> Since, as I mentioned, I had trouble understanding how apply
>>>>> worked, and the code seems pretty complicated, at least to me,
>>>>> I was hoping DeBruijn's method would offer simplifications.
>>>> > From the examples I've seen so far, this would make it easier for bind
>>>> library writers at the expense of usability. On th other hand, once
>>>> lambdas start to use protect() I'm usually giving up on them ;-)
>>> Usability is hurt from whose perspective? The bind author or the bind
>> The bind user
>> And how so?
>> 1. It means learning a totally new paradigm for writing ordinary
>> lambdas thatso farseems to require the grasp of quite a few concepts
>> that are not familiar to the average C++ programmer. bind and its
>> cousins may not be as flexible, but they're designed to be intuitively
>> graspable (to a C++ programmer), and the paradigm is now going into
>> the standard so will be lingua franca.
>> 2. Again, please correct me if I'm wrong about this, but it looks like
>> for "ordinary lambdas" (those that don't need protect), the
>> corresponding bind expressions are always shorter and simpler.
> Perhaps it would be good to have a practical use-case. In a
> lengthy discussions about scopes and higher order functions
> (with Jaakko, Dave, Doug plus some more I don't recall), we
> had this use case (this is the one you can see in the phoenix
> docs here: http://tinyurl.com/295ha83):
> write a lambda expression that accepts:
> 1. a 2-dimensional container (e.g. vector<vector<int> >)
> 2. a container element (e.g. int)
> and pushes-back the element to each of the vector<int>.
> The phoenix solution:
> lambda(_a = _2) // local _a captures the outer arg2
> push_back(_1, _a)
> We once had outer. The outer solution looked like this:
> push_back(_1, outer(_2))
> How would that look like if you extend phoenix with your syntax?
Thanks for the example Joel.
Assuming for_eachF and push_backF are normal polymorphic functions, the
core would look like:
auto f = lam<2>( app( for_eachF
, lam( app( push_backF
If we extend the language with for_each and push_back primitives,
auto for_each = appPrim( for_eachF );
auto push_back = appPrim( push_backF );
it gets a bit simpler:
auto f = lam<2>( for_each( _1_1
, lam( push_back( _1_1, _2_1 ) )
If we do Stefan's multi-arity suggestion, which I still don't like too much,
it looks like this:
auto f = for_each( _1_1
, lam( push_back( _1_1, _2_1 ) )
If we make _1 a synonym for _1_1 and so on (not saying we should), we get:
auto f = for_eachF( _1
, lam( push_back( _1, _2_1) )
> It would be good to tackle this through practical use-cases
> and using plain C++ terms. Too much formality hurts my brain.
> If this use-case is too simplistic, then perhaps you can provide
> something more elaborate, yet still practical.
I think your example is a valid use case. Unfortunately, I think it would
take longer to explain my particular use cases than the formality of this
An example of a bind weakness that really bites is the following function.
This came up when I was making a high performance stream library:
//Where g is some other function
template< typename F >
auto doThingee( F f )
-> decltype( boost::bind( g, f ) )
return boost::bind( g, f );
doThingee does what you would expect most of the time. That is, until a user
makes a call like:
doThingee( boost::bind( h, 22, _1) );
See the problem here? This is an example of the really crappy bind semantics
that hardly anyone is aware of. With something like De Bruijn bind, there
are no surprises.
-- 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