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:
- unction curry(ref f) = a => b => f(a,b);
- function uncurry(ref f) = (a, b) =>
- {
- ref bc = f(a);
- return bc(b);
- };
- function map(ref f, lst)
- {
- foreach(var x in lst)
- nlst.Add( f(x) );
- return nlst;
- }
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:
- 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:
- 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:
- 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