Use case for std.bind

Denis Koroskin 2korden at gmail.com
Wed Feb 25 11:36:43 PST 2009


On Wed, 25 Feb 2009 17:19:30 +0300, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> Jason House wrote:
>> Andrei Alexandrescu Wrote:
>>> int plus(int x, int y} { return x + y; } auto plus5 =
>>> curry!(plus)(5); assert(plus5(10) == 15);
>>>  typeof(plus5) will be a little struct that may be cumbersome to
>>> pass around, in which case you do want to take the toll of the
>>> indirect call by writing:
>>>  auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5)
>>> == int delegate(int)); assert(plus5(10) == 15);
>>>  This stuff belongs to std.functional. I plan to eliminate std.bind
>>> and put currying and binding in std.functional. What do people
>>> think?
>>>  Andrei
>>  I've done the whole boost::bind thing before and it sucks. When
>> boost::lambda came out, that was way better. Anonymous delegates are
>> even better. Learning a separate functional syntax will always be a
>> sub par solution to me.
>
> So let's see. If what you have is a function int fun(int, int) and you  
> want to fix its first parameter to a specific value, you can write:
>
> (int x) { return fun(42, x); }
>
> That would be a function literal. To give it a name, you can say:
>
> int gun(int x) { return fun(42, x); }
>
> If you want to pass that thing around, you take &gun (or &(literal)) and  
> transform it into a delegate. One minor issue with the above is that the  
> syntax is rather verbose and that the relationship between the function,  
> the parameter, and the outcome is not conceptualized. Yes, the  
> constructs can curry any function, but you have no *notion* of currying  
> a function. So I thought of defining such a simple notion that would  
> allow you to write:
>
> curry!(fun)(42)
>
> instead of the literals above.

I don't want to offend anyone, but this syntax sucks badly.

Just compare:

auto x = (int x) { return fun(42, x); };
auto x = makeDelegate(curry!(fun)(42));

And you say that your solution is /shorter/? You must be kidding! Delegate  
is THE way to pass closures in D, not some functional object that has  
opCall(). Besides, I want my methods to be virtual and I can't afford  
myself a template method that accepts functional objects of any type.

bind is way *way* WAY more capable that what you propose as a replacement.  
It allows parameter reordering, duplication etc with a simple, uniform  
syntax:

auto x = bind(&fun, 42, _0);
auto y = bind(&fun, _0, 42);
auto z = bind(&fun, _1, _0);

But it's not very intuitive and easy to read:

auto q = bind(&fun, _1, bind(&fun, bind(&fun, _0, 42), _1));

Besides, it is often ambiguous:

void foo(int x, int y);
void foo(float x, int y);

auto x = makeDelegate(bind(&foo, _0, 42)); // error

With built-in D delegate syntax, there is no ambiguity and mistake:
auto x = (int x) { foo(x, 42); };

That's *the best* syntax I can think of. Just keep it and let the std.bind  
go. Don't waste your precious time of fixing something that isn't broken  
(err.. std.bind IS broken, but that's not what I was talking about :p)

> In your code you are of course free to use either form as you find fit,  
> just as you can write x * x * x or cube(x) or pow(x, 3). So I'm not sure  
> where the sub par thing comes.
>
>> I'll go even further. If D had only what you've proposed for ranges
>> and std.functional but lacked opApply and anonymous delegates, I
>> never would have become a D user. Simple, clean syntax is that
>> important to me...  Please don't recreate boost and STL in D.
>> They're great libraries, but we can do way better than that!
>
> This is the Usenet equivalent of a pie in the face. Wait, what? I  
> _thought_ I'm far beyond recreating boost and STL and also that in the  
> process I am using the full power of the language (and sometimes even  
> more, as shown by the stream of bug reports and enhancement requests  
> that I had to post recently). All range, functional, and algorithms do  
> hinge on anonymous delegates (function literals in fact, which are  
> considerably better); they don't compete with them at all, so I fail to  
> see how one could be thought of in separation from the other. Anyhow, if  
> you have some ideas on how we can do way better than the current trend  
> I'm all ears. My perception, if you allow me to venture a thought, is  
> that you are a bit confused. To paraphrase SICP, you are happy with x *  
> x * x and are afraid that the option of writing cube(x) makes things  
> worse.
>
>
> Andrei




More information about the Digitalmars-d mailing list