A bit of curry?

I'm talking about Currying, "the technique of transforming a function that takes multiple arguments into a function that takes a single argument..."

With two recent additions to Prexonite (Script), it has become very easy to implement higher-order functions, including "curry" and "uncurry".

With "additions" I'm referring to Closures as a virtual machine feature and Lambda Expressions as a Prexonite Script expansion. Something of the form (a1, a2, a3, ... , an) => expr is an expression that is compiled into a separate function. Instead of a value, such a construct returns a closure, an enhanced reference to that anonymous function, that acts like a normal function reference. It get's even better: As this so called lambda expression is defined inside another function, you can use local variables as if they were part of the expression. That's also the reason why this closure-thingy is returned instead of a normal function reference: It carries information about additional local variables available to the lambda expression.

But now, let's get back to Currying:

Prexonite Script:
  1. unction curry(ref f) = a => b => f(a,b);
  2.  
  3. function uncurry(ref f) = (a, b) =>
  4. {
  5.     ref bc = f(a);
  6.     return bc(b);
  7. };
  8.  
  9. function map(ref f, lst)
  10. {
  11.     var nlst = new List;
  12.     foreach(var x in lst)
  13.         nlst.Add( f(x) );
  14.     return nlst;
  15. }

I admit, that these functions are limited to a total number of two arguments. It's more a proof-of-concept, as it's very rare that you actually need something like this in an imperative language like PXS. One of my unit tests uses currying to partially apply an addition to a list of integers:
Prexonite Script:
  1. map( curry( (x,y) => x + y ) , ~List.Create( 2, 3, 5 ))


In this case, curry returns a function that takes the one argument ( x ) and itself returns a function that takes the other argument ( y ) and returns x + y. So the result of this expression can be written as:
Prexonite Script:
  1. var additions = ~List.Create( y => 2+y, y => 3+y, y => 5+y );


To finally get a list of integers again, you'll have to supply the missing y, either using a for(each) loop or by treating the list itself as a reference and passing one argument:
Prexonite Script:
  1. var results = additions(5);


The result is again a list.

And no, this is not a case study. It's reality. (I'm sorry, I'm just a bit like "Closures! In my own programming language! Working!")

Discussion Area - Leave a Comment