CSC/ECE 517 Fall 2011/ch1 2a bi

From Expertiza_Wiki
Revision as of 00:07, 23 September 2011 by Briyenga (talk | contribs)
Jump to navigation Jump to search

Introduction

Currying is a function transformation supported by some programming languages. It transforms a function that accepts n parameters and generates from it, one of more functions with some parameter values already filled in. These broken down functions can then be called in a chain to obtain a result equivalent to that obtained by calling the original function.

History and Definition

Currying has its origins in the mathematical study of functions. It was observed by Frege in 1893 that it suffices to restrict attention to functions of a single argument. For example, for any two parameter function f(x,y), there is a one parameter function f' such that f'(x) is a function that can be applied to y to give (f'(x))(y) = f (x,y). This corresponds to the well known fact that the sets (AxB -> C) and (A -> (B -> C)) are isomorphic, where "x" is cartesian product and "->" is function space. It was independently re-discovered by Moses Schönfinkel [REFERENCE] and by Haskell Curry [reference] and made it into the Haskell functional programming language as a primary feature.[Reference] In essence, the currying process takes a function of two parameters and returns a pointer to a function of one parameter. The function body itself doesn't change. The newly returned function pointer can then be called with the parameter that was left out in the first transformation.

Another way to think about this, is in terms of the default values for function parameters that most programming languages permit. Default argument is the part of function declaration and it tells compiler what value to pass for an argument if the programmer deliberately misses the argument when calling the function. In the common case that many arguments are almost always the same, this saves the programmer's time and effort required to remember and specify all arguments. Default arguments are useful in situations where some arguments always have the same value. The default parameter values however are constricting, in that the program is only allowed to use those values in case the function call is missing a particular parameter value. Currying enables us to overcome this restriction by essentially generating additional function definitions for the same underlying function with different default values. Consider a C++ function, sample_test(bool test = false, int data), here the default value of the parameter test is set to 'false' and will remain so for the life of the program. However with currying, we can transform the function to: sample_test_1(1), sample_test_1(1) can then be called either as sample_test_1(true, 1) or sample_test_1(false, 1).


Currying In Modern Languages

Currying, as a language feature, has made the cross over the functional programming languages[REFERENCE] to imperative programming languages. Languages such as Scala[REFERENCE], Ruby[REFERENCE], Perl[REFERENCE] and Groovy[REFERENCE] support currying. Functional programs such as Haskell have always supported it. We will look at how to use this feature in a few modern languages in the sections below.

Currying In Ruby

Ruby is a pure object oriented programming language that has built in support for currying. Ruby supports currying mainly by using 'Proc' objects. Proc objects are blocks of code that have been bound to a set of local variables. Once bound, the code may be called in different contexts and still access those variables. The Proc class implements a 'curry ' function that can be called on any function. The curry function returns a curried proc. A curried proc receives some arguments. If a sufficient number of arguments are supplied, it passes the supplied arguments to the original proc and returns the result. Otherwise, it returns another curried proc that takes the rest of arguments.

For e.g.

 code_blob = Proc.new {|x, y, z| z= x+y}
 code_blob.curry[1, 2]

The Ruby kernel function lambda also returns a Proc object and hence can call the curry function as well.

 code_blob = lambda {|x, y, z| z= x+y}
 code_blob.curry[1, 2]


Currying In Perl

The Perl6::Currying module is used to implement currying in Perl. In Perl 6 any subroutine can be "partially bound", i.e., some of its arguments can be supplied and thereby create another subroutine that calls the original with those arguments automatically supplied.

Subroutine parameters are partially bound by calling the prebind method on the subroutine. This method call returns a reference to a new subroutine that calls the original subroutine, inserting into its argument list the prebound arguments. For example:


       sub divide ($numerator, $denominator) {
               return $numerator / $denominator;
       }
       my $halve = &divide.prebind(denominator=>2);

Having prebound the denominator, if we now call the subroutine referred to by $halve the effect is to call divide with an automagically supplied denominator of 2. That is:

       print divide(42,2);     # calls &divide...prints 21
       print $halve(42);       # calls &divide...prints 21 

Currying In Scala

Currying In C

Usage

Most programming languages such as C++ allow function parameters to be assigned to default values. However, the default values are restricted

Contrast with partial programs

References

Links