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