[phobos] D std.bind

Jason Spencer spencer8 at sbcglobal.net
Thu Jun 17 12:09:56 PDT 2010


Andrei Alexandrescu <andrei at ...> 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));
}




More information about the phobos mailing list