I think you're close to the optimal. I'd probably drop function and write:
auto g1 = int(int b, int c, int d) { return g(2,b,c,d); };
All things considered, I'm not sure that that's worse than the arcana:
auto g1 = bind(&g, _1);
which only goes downhill when:
- g is overloaded
- the usage pattern is more complicated (e.g. you want g(2, -b, c, d)
- there are more than 10 arguments
- and by the way there's a bug above because I used _1 not _0 :o)
All in all, std.bind looks like a direct derivative of Boost's design,
which is built to deal with C++'s issues, and does not avail itself of
D's advantages.
Andrei
Jason Spencer wrote:
Andrei Alexandrescu <and...@...> writes:
Jason Spencer wrote:
- Currying an arbitrary length parameter list
- storing a delegate to the curried function
- composing curries (could be replaced by previous 2 if done in a certain
way)
- binding at arbitrary parameter indexes
All of these are much easier done with delegate literals.
As I said, I'm new, so hopefully you'll tell me if I'm missing something
obvious. But it sounds like you're suggesting that the code below represents an
easier way to these things than some templated bind or related idea. I can't
say that feels easier. I also wonder what happens when I change the return type
of g to short--can I make that change correctly in one pass (i.e. isn't manual
maintenance of this sort of construct very error-prone)?
I could well accept that there might be an easier template formulation for these
constructs that can use the full power of delegate literals and closures built
in now. Maybe bind goes away and std.functional picks up some of this
capability with a fuller curry (like the sample Curry on the template page,
even.) But I think to not provide SOME facility would add a lot of boiler plate
code, be maintenance error-prone, and hinder the use of a fairly powerful
feature.
Again, I'm quite possibly missing the "easy" way.
Jason
Sample code:
-----
import std.stdio;
int g (int a, int b, int c, int d)
{
return a + b + c + d;
}
void main()
{
// bind a single argument
auto g1 = function int(int b, int c, int d) { return g(2,b,c,d); };
// compose bindings of one argument
auto g2 = delegate int(int c, int d) { return g1(3, c, d); };
// delegate that takes two arguments and returns a delegate of one argument
auto curryG2x = delegate int delegate (int) (int b, int c)
{
return delegate int (int d)
{
return g(2, b, c, d);
};
};
// full currying
auto fullCurryG =
delegate int delegate (int) delegate (int) delegate (int) (int a)
{
return delegate int delegate (int) delegate (int) (int b)
{
return delegate int delegate (int) (int c)
{
return delegate int (int d)
{
return g(a, b, c, d);
};
};
};
};
writefln("g2(4,5) = %d, type = %s", g2(4,5), typeid(g2));
writefln("curryG2x(3)(4,5) = %d, type = %s", curryG2x(3,4)(5),
typeid(curryG2x));
writefln("fullCurryG(2)(3)(4)(5) = %d, type = %s", fullCurryG(2)(3)(4)(5),
typeid(fullCurryG));
writefln("fullCurryG(2)(3) = %s, type = %s", fullCurryG(2)(3),
typeid(fullCurryG));
}
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos