Currying, which is named after the logician Haskell Curry, means to
turn a function taking multiple arguments simultaneously into a function of
the same body (modulo corresponding recursive function calls being changed
accordingly) that takes these arguments sequentially. Uncurrying means
precisely the opposite of currying. In the following code, both of the
defined functions acker1 and acker2 implement the
Ackermann's function (which is famous for being recursive but not primitive
recursive):
The function
acker2 is a curried version of
acker1 while the function
acker1 in an uncurried
version of
acker2. Applying
acker2 to an integer
value generates a linear function closure, which I will explain elsewhere.
In functional languages such as ML and Haskell, a function of multiple
arguments needs to be either curried or translated into a corresponding
unary function of a single argument that itself is a tuple. In such
languages, currying often leads to better performance at run-time and thus
is preferred. In ATS, functions of multiple arguments are supported
directly. Also, given a function of multiple arguments, a curried version
of the function is likely to perform less efficiently at run-time than the
function itself (due to the treatment of curried functions by the ATS
compiler atsopt). Therefore, the need for currying in
ATS is greatly diminished. Unless convincing reasons can be given, currying
is in general not a recommended programming style in ATS.