Currying
|
|
This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (March 2011) |
In mathematics and computer science, currying is the technique of transforming a function that takes multiple arguments (or an n-tuple of arguments) in such a way that it can be called as a chain of functions each with a single argument (partial application). It was discovered by Moses Schönfinkel[1] and later re-discovered by Haskell Curry[2][not specific enough to verify]; because of this, some say it would be more correct to name it schönfinkeling.[3][4]
Uncurrying (also known as counter-currying) is the dual transformation to currying, and can be seen as a form of defunctionalization. It takes a function f(x) which returns another function g(y) as a result, and yields a new function f'(x, y) which takes a number of additional parameters and applies them to the function returned by f. The process can be iterated if necessary.
Contents |
[edit] Motivation
Currying is similar to the process of calculating a function of multiple variables for some given values on paper. For example, given the function
:
- To evaluate
, first replace
with 2.
- Since the result is a function of
, this function
can be defined as
.
- Next, replace the
argument with 3, producing
.
On paper, using classical notation, this is usually done all in one step. However, each argument can be replaced sequentially as well. Each replacement results in a function taking exactly one argument. This produces a chain of functions as in lambda calculus, and multi-argument functions are usually represented in curried form.
Some programming languages almost always use curried functions to achieve multiple arguments; notable examples are ML and Haskell, where in both cases all functions have exactly one argument.
This is similar in computer code: If we let f be a function
f(x,y) = y / x
then the function g
g x = \y -> f(x,y)
is a curried version of f. In particular,
g 2 = \y -> f(2,y)
is the curried equivalent of the example above. Though note that currying, while similar, is not the same operation as partial function application.
[edit] Definition
Given a function f of type
, currying it makes a function
. That is,
takes an argument of type
and returns a function of type
. Uncurrying is the reverse transformation, and is most easily understood in terms of its right adjoint, apply.
The → operator is often considered right-associative, so the curried function type
is often written as
. Conversely, function application is considered to be left-associative, so that
is equivalent to
.
Curried functions may be used in any language that supports closures; however, uncurried functions are generally preferred for efficiency reasons, since the overhead of partial application and closure creation can then be avoided for most function calls.
[edit] Mathematical view
In theoretical computer science, currying provides a way to study functions with multiple arguments in very simple theoretical models such as the lambda calculus in which functions only take a single argument.
In a set-theoretic paradigm, currying is the natural correspondence between the set
of functions from
to A, and the set
of functions from
to the set of functions from
to
. In category theory, currying can be found in the universal property of an exponential object, which gives rise to the following adjunction in cartesian closed categories: There is a natural isomorphism between the morphisms from a binary product
and the morphisms to an exponential object
. In other words, currying is the statement that product and Hom are adjoint functors; that is there is a natural transformation:
This is the key property of being a Cartesian closed category.
Under the Curry-Howard correspondence, the existence of currying and uncurrying is equivalent to the logical theorem
, as tuples (product type) corresponds to conjunction in logic, and function type corresponds to implication.
Curry is a continuous function in the Scott topology.
[edit] Example in Java
class CurryingTest { interface Compute<ReturnType, ParameterType> { ReturnType compute(final ParameterType o); } public static void main(String [] args) { Compute<Compute<Compute<Integer, Integer>, Integer>, Integer> someComputation = new Compute<Compute, Integer>() { public Object compute(final Integer o1) { return new Compute<Compute, Integer>() { public Object compute(final Integer o2) { return new Compute<Integer, Integer>() { public Integer compute(final Integer o3) { return o1 + o2 + o3; } }; } }; } }; System.out.println(someComputation.compute(1).compute(2).compute(3)); } }
[edit] Naming
The name "currying", coined by Christopher Strachey in 1967, is a reference to logician Haskell Curry. The alternative name "Schönfinkelisation", has been proposed as a reference to Moses Schönfinkel.[5]
[edit] Contrast with partial function application
Currying and partial function application are often conflated.[6] The difference between the two is clearest for functions taking more than two arguments.
Given a function of type
, currying produces
. That is, while an evaluation of the first function might be represented as
, evaluation of the curried function would be represented as
, applying each argument in turn to a single-argument function returned by the previous invocation. Note that after calling
, we are left with a function that takes a single argument and returns another function, not a function that takes two arguments.
In contrast, partial function application refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. Given the definition of
above, we might fix (or 'bind') the first argument, producing a function of type
. Evaluation of this function might be represented as
. Note that the result of partial function application in this case is a function that takes two arguments.
Intuitively, partial function application says "if you fix the first arguments of the function, you get a function of the remaining arguments". For example, if function div stands for the division operation x / y, then div with the parameter x fixed at 1 (i.e., div 1) is another function: the same as the function inv that returns the multiplicative inverse of its argument, defined by inv(y) = 1 / y.
The practical motivation for partial application is that very often the functions obtained by supplying some but not all of the arguments to a function are useful; for example, many languages have a function or operator similar to plus_one. Partial application makes it easy to define these functions, for example by creating a function that represents the addition operator with 1 bound as its first argument.
[edit] See also
[edit] Notes
- ^ Strachey, Christopher (2000). "Fundamental Concepts in Programming Languages". Higher-Order and Symbolic Computation 13: 11–49. doi:10.1023/A:1010000313106. "There is a device originated by Schönfinkel, for reducing operators with several operands to the successive application of single operand operators." (Reprinted lecture notes from 1967.)
- ^ (Barendregt 2000, p. 8)
- ^ Reynolds, John C. (1998). "Definitional Interpreters for Higher-Order Programming Languages". Higher-Order and Symbolic Computation 11 (4): 374. doi:10.1023/A:1010027404223. "In the last line we have used a trick called Currying (after the logician H. Curry) to solve the problem of introducing a binary operation into a language where all functions must accept a single argument. (The referee comments that although “Currying” is tastier, “Schönfinkeling” might be more accurate.)"
- ^ Kenneth Slonneger and Barry L. Kurtz. Formal Syntax and Semantics of Programming Languages. p. 144.
- ^ I. Heim and A. Kratzer (1998). Semantics in Generative Grammar. Blackwell.
- ^ Partial Function Application is not Currying
[edit] References
- Schönfinkel, Moses (1924). "Uber die Bausteine der mathematischen Logik". Math. Ann. 92 (3–4): 305–316. doi:10.1007/BF01448013.
- Heim, Irene; Kratzer, Angelika (1998). Semantics in a Generative Grammar. Malden: Blackwall Publishers
[edit] External links
| Look up currying in Wiktionary, the free dictionary. |
- Frequently Asked Questions for comp.lang.functional: Currying by Graham Hutton
- Currying Schonfinkelling at the Portland Pattern Repository
- Currying != Generalized Partial Application! - post at Lambda-the-Ultimate.org
- Language-specific implementations
, first replace
with 2.
, this function
can be defined as
.
.