Currying

From Rosetta Code
Revision as of 14:39, 2 April 2013 by rosettacode>Dkf (→‎{{header|Tcl}}: Some more notes)
This page uses content from Wikipedia. The original article was at Currying. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)
Currying is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Create a simple demonstrative example of Currying in the specific language.

Add any historic details as to how the feature made its way into the language.

ALGOL 68

In 1968 C.H. Lindsey proposed for partial parametrisation for ALGOL 68, this is implemented as an extension in wp:ALGOL 68G. <lang algol68># Raising a function to a power #

MODE FUN = PROC (REAL) REAL; PROC pow = (FUN f, INT n, REAL x) REAL: f(x) ** n; OP ** = (FUN f, INT n) FUN: pow (f, n, );

  1. Example: sin (3 x) = 3 sin (x) - 4 sin^3 (x) (follows from DeMoivre's theorem) #

REAL x = read real; print ((new line, sin (3 * x), 3 * sin (x) - 4 * (sin ** 3) (x)))</lang>

C#

This shows how to create syntactically natural currying functions in C#. <lang csharp>public delegate int Plus(int y); public delegate Plus CurriedPlus(int x); public static CurriedPlus plus =

     delegate(int x) {return delegate(int y) {return x + y;};};

static void Main() {

   int sum = plus(3)(4); // sum = 7
   int sum2= plus(2)(plus(3)(4)) // sum2 = 9

}</lang>

C++

Currying may be achieved in C++ using the Standard Template Library function object adapters (<lang C++>binder1st</lang> and <lang C++>binder2nd</lang>), and more generically using the Boost <lang C++>bind</lang> mechanism.

Eiffel

Eiffel has direct support for lambda expressions and hence currying through "inline agents". If f is a function with two arguments, of signature (X × Y) → Z then its curried version is obtained by simply writing

   g (x: X): FUNCTION [ANY, TUPLE [Y], Z]
       do
           Result := agent (closed_x: X; y: Y): Z 
              do 
                 Result := f (closed_x, y) 
              end (x, ?)
       end

where FUNCTION [ANY, TUPLE [Y], Z] denotes the type YZ (agents taking as argument a tuple with a single argument of type Y and returning a result of type Z), which is indeed the type of the agent expression used on the next-to-last line to define the "Result" of g.

Haskell

Likewise in Haskell, function type signatures show the currying-based structure of functions (note: "<lang haskell>\ -></lang>" is Haskell's syntax for anonymous functions, in which the sign <lang haskell>\</lang> has been chosen for its resemblance to the Greek letter λ (lambda); it is followed by a list of space-separated arguments, and the arrow <lang haskell>-></lang> separates the arguments list from the function body)

   Prelude> let plus = \x y -> x + y
   Prelude> :type plus
   plus :: Integer -> Integer -> Integer
   Prelude> plus 3 5
   8

and currying functions is trivial

   Prelude> let plus5 = plus 5
   Prelude> :type plus5
   plus5 :: Integer -> Integer
   Prelude> plus5 3
   8

In fact, the Haskell definition <lang haskell>\x y -> x + y</lang> is merely syntactic sugar for <lang haskell>\x -> \y -> x + y</lang>, which has exactly the same type signature:

   Prelude> let nested_plus = \x -> \y -> x + y
   Prelude> :type nested_plus
   nested_plus :: Integer -> Integer -> Integer

Io

A general currying function written in the Io programming language: <lang io>curry := method(fn, a := call evalArgs slice(1) block( b := a clone appendSeq(call evalArgs) performWithArgList("fn", b) ) )

// example: increment := curry( method(a,b,a+b), 1 ) increment call(5) // result => 6</lang>

Java

<lang java5> public class Currier<ARG1, ARG2, RET> {

       public interface CurriableFunctor<ARG1, ARG2, RET> {
           RET evaluate(ARG1 arg1, ARG2 arg2);
       }
   
       public interface CurriedFunctor<ARG2, RET> {
           RET evaluate(ARG2 arg);
       }
   
       final CurriableFunctor<ARG1, ARG2, RET> functor;
   
       public Currier(CurriableFunctor<ARG1, ARG2, RET> fn) { functor = fn; }
       
       public CurriedFunctor<ARG2, RET> curry(final ARG1 arg1) {
           return new CurriedFunctor<ARG2, RET>() {
               public RET evaluate(ARG2 arg2) {
                   return functor.evaluate(arg1, arg2);
               }
           };
       }
   
       public static void main(String[] args) {
           Currier.CurriableFunctor<Integer, Integer, Integer> add
               = new Currier.CurriableFunctor<Integer, Integer, Integer>() {
                   public Integer evaluate(Integer arg1, Integer arg2) {
                       return new Integer(arg1.intValue() + arg2.intValue());
                   }
           };
           
           Currier<Integer, Integer, Integer> currier
               = new Currier<Integer, Integer, Integer>(add);
           
           Currier.CurriedFunctor<Integer, Integer> add5
               = currier.curry(new Integer(5));
           
           System.out.println(add5.evaluate(new Integer(2)));
       }
   }</lang>

JavaScript

<lang javascript> function addN(n) {

   var curry = function(x) {
       return x + n;
   };
   return curry;
}
add2 = addN(2);
alert(add2);
alert(add2(7));</lang>

ML

Suppose that plus is a function taking two arguments x and y and returning x + y. In the ML programming language we would define it as follows:

   plus = fn(x, y) => x + y

and plus(1, 2) returns 3 as we expect.

The curried version of plus takes a single argument x and returns a new function which takes a single argument y and returns x + y. In ML we would define it as follows:

   curried_plus = fn(x) => fn(y) => x + y

and now when we call curried_plus(1) we get a new function that adds 1 to its argument:

   plus_one = curried_plus(1)

and now plus_one(2) returns 3 and plus_one(7) returns 8.

When declaring functions in the strictly-typed OCaml programming language, the type returned by a function shows the Curried form of the function. Typing the function into the OCaml interpreter displays the type immediately:

   # let plus x y = x + y ;;
   val plus : int -> int -> int = <fun>

Perl

This is a Perl 5 example of a general curry function and curried plus using closures: <lang perl>sub curry{

 my ($func, @args) = @_;
 sub {
   #This @_ is later
   &$func(@args, @_);
 }

}

sub plusXY{

 $_[0] + $_[1];

}

my $plusXOne = curry(\&plusXY, 1); print &$plusXOne(3), "\n";</lang>

Python

<lang python> def addN(n):

    def adder(x):
        return x + n
    return adder</lang>

<lang python> >>> add2 = addN(2)

>>> add2
<function adder at 0x009F1E30>
>>> add2(7)
9</lang>

Scheme

This is a simple general currying function written in Scheme: <lang scheme>;curry:function,args->(function)

Adding using currying

(define (curry f . args) (lambda x (apply f (append args x))))</lang> This is an example of applying a curried function: <lang scheme>>((curry + 10) 10) 20</lang>

Tcl

The simplest way to do currying in Tcl is via an interpreter alias: <lang tcl>interp alias {} addone {} ::tcl::mathop::+ 1 puts [addone 6]; # => 7</lang> Tcl doesn't support automatic creation of curried functions though; the general variadic nature of a large proportion of Tcl commands makes that impractical.

History

The type of aliases used here are a simple restriction of general inter-interpreter aliases to the case where both the source and target interpreter are the current one; these aliases are a key component of the secure interpreter mechanism introduced in Tcl 7.6, and are the mechanism used to allow access to otherwise-insecure behavior from a secure context (e.g., to write to a particular file, but not any old file).