29

There are tons of tutorials on how to curry functions, and as many questions here at stackoverflow. However, after reading The Little Schemer, several books, tutorials, blog posts, and stackoverflow threads I still don't know the answer to the simple question: "What's the point of currying?" I do understand how to curry a function, just not the "why?" behind it.

Could someone please explain to me the practical uses of curried functions (outside of languages that only allow one argument per function, where the necessity of using currying is of course quite evident.)

edit: Taking into account some examples from TLS, what's the benefit of

(define (action kind)
    (lambda (a b)
        (kind a b)))

as opposed to

(define (action kind a b)
    (kind a b))

I can only see more code and no added flexibility...

Philip Seyfi
  • 929
  • 1
  • 10
  • 24
  • Use 4 indents, when formatting your code. See [Editing Help](http://stackoverflow.com/editing-help). – YasirA Feb 03 '11 at 18:14
  • 2
    Two definitions, you provided, don't use currying, we're talking about, these are just examples of different ways to define a function. See the link to another question in the comment to my answer. – YasirA Feb 03 '11 at 18:51
  • Interesting, cause 'currying' is exactly how TLS calls it... Quoting: "`(lambda (a) (lambda (x) (eq? x a)))` ... Is that 'Curry-ing?' ... [Yes.]" – Philip Seyfi Feb 03 '11 at 19:05
  • Forgot about 1 argument. That article at Wikipedia I referenced explains it in more details :-) – YasirA Feb 03 '11 at 19:12
  • Happy to see, when people are learning functional programming. You're welcome ;-) – YasirA Feb 03 '11 at 19:19
  • 3
    I think it's worth noting that currying is more useful when the language makes it simpler. In Scheme, you have to write `(define (action kind) (lambda (a) (lambda (b) (kind a b))))` and then `(((action +) 3) 4)`, which is really bulky. In Haskell, on the other hand, you write simply `action kind a b = kind a b`, and then `action (+) 3 4`; the former is implicitly equivalent to `action = \kind -> \a -> \b -> kind a b` (where `\x -> y` is `(lambda (x) y)`), and the latter is parsed as `((action (+)) 3) 4`. So having currying implicit lets you leverage the benefits without the cruft. – Antal Spector-Zabusky Feb 03 '11 at 20:02
  • *"outside of languages that only allow one argument per function"* ??? Are there such programming languages? The lambda calculus itself is the only "language" that I know of has neither tuples nor anything (only lambda, parameters, and brackets). Multi-parameter functions are nothing else than one-parameter functions with a tuple as parameter. There are –of course– some (imperative) programming languages without proper support for tuples, but they have multi-parameter functions, too. – comonad Feb 15 '11 at 13:26

10 Answers10

24

One effective use of curried functions is decreasing of amount of code.

Consider three functions, two of which are almost identical:

(define (add a b)
  (action + a b))

(define (mul a b)
  (action * a b))

(define (action kind a b)
  (kind a b))

If your code invokes add, it in turn calls action with kind +. The same with mul.

You defined these functions like you would do in many imperative popular languages available (some of them have been including lambdas, currying and other features usually found in functional world, because all of it is terribly handy).

All add and sum do, is wrapping the call to action with the appropriate kind. Now, consider curried definitions of these functions:

(define add-curried
  ((curry action) +))

(define mul-curried
  ((curry action) *))

They've become considerable shorter. We just curried the function action by passing it only one argument, the kind, and got the curried function which accepts the rest two arguments.

This approach allows you to write less code, with high level of maintainability.

Just imagine that function action would immediately be rewritten to accept 3 more arguments. Without currying you would have to rewrite your implementations of add and mul:

(define (action kind a b c d e)
  (kind a b c d e))

(define (add a b c d e)
  (action + a b c d e))

(define (mul a b c d e)
  (action * a b c d e))

But currying saved you from that nasty and error-prone work; you don't have to rewrite even a symbol in the functions add-curried and mul-curried at all, because the calling function would provide the necessary amount of arguments passed to action.

YasirA
  • 9,531
  • 2
  • 40
  • 61
  • Taking into account some examples from TLS, and your example above, what's the benefit of `(define (action kind)(lambda (a b)(kind a b)))` as opposed to `(define (action kind a b)(kind a b))`? I can only see more code and no added flexibility... – Philip Seyfi Feb 03 '11 at 17:47
  • @Philip: There's no benefit, except the taste and the number of keystrokes :-) See "[Why all the lambdas in The Little Schemer?](http://stackoverflow.com/q/4777865/298282)". – YasirA Feb 03 '11 at 18:11
  • I'm not talking about lambdas... If I understand it right, the first function is curried, and the second isn't. Again, if I am not mistaken, both do exactly the same thing, but the curried version is longer both in its definition and when its called — `((action *) 5 5)` as opposed to `(action * 5 5)` – Philip Seyfi Feb 03 '11 at 18:26
  • @Philip: If you wouldn't curry `action` in `add`, passing 7 arguments to it, you'd get `add` defined like `(define (add a b c d e f g) (action + a b c d e f g))`. Compare with its curried and less verbose counterpart: `(define add-curried (curry action +))`. – YasirA Feb 03 '11 at 18:42
  • 1. Isn't that just partial application? 2. So `(define (action kind)(lambda (a b)(kind a b))` is not a curried function? 3. How would one call add-curried? – Philip Seyfi Feb 03 '11 at 18:54
  • `add-curried` can be called like `(add-curried 1 2 3 4 5)`, which results in `15`. See how differ currying and partial application here [Currying: Contrast with partial function application](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application). – YasirA Feb 03 '11 at 19:07
  • Is curring similar to template in c++ ?? – Ahtisham Aug 27 '17 at 13:57
11

They can make code easier to read. Consider the following two Haskell snippets:

lengths :: [[a]] -> [Int]
lengths xs = map length xs

lengths' :: [[a]] -> [Int]
lengths' = map length

Why give a name to a variable you're not going to use?

Curried functions also help in situations like this:

doubleAndSum ys = map (\xs -> sum (map (*2) xs) ys

doubleAndSum' = map (sum . map (*2))

Removing those extra variables makes the code easier to read and there's no need for you to mentally keep clear what xs is and what ys is.

HTH.

Bill
  • 44,502
  • 24
  • 122
  • 213
  • 1
    this is called the *pointfree* programming style, which is only possible with curried code. – comonad Feb 15 '11 at 13:09
  • 4
    Haskell's partial application is so much cooler than explicit currying. – Austin Taylor Mar 09 '11 at 03:51
  • 2
    Programming in the pointfree or tacit style does not require curried functions. It can be done using combinators, for example. Said style is prominent with the J programming language. In J currying does not occur by default, and tacit form never depends on it. – kaleidic Mar 09 '11 at 03:52
4

You can see currying as a specialization. Pick some defaults and leave the user (maybe yourself) with a specialized, more expressive, function.

Francesco
  • 3,200
  • 1
  • 34
  • 46
3

I think that currying is a traditional way to handle general n-ary functions provided that the only ones you can define are unary.

For example, in lambda calculus (from which functional programming languages stem), there are only one-variable abstractions (which translates to unary functions in FPLs). Regarding lambda calculus, I think it's easier to prove things about such a formalism since you don't actually need to handle the case of n-ary functions (since you can represent any n-ary function with a number of unary ones through currying).

(Others have already covered some of the practical implications of this decision so I'll stop here.)

Artyom Shalkhakov
  • 1,101
  • 7
  • 14
  • 1
    Quoting from my initial question: `(outside of languages that only allow one argument per function, where the necessity of using currying is of course quite evident.)` :) – Philip Seyfi Feb 05 '11 at 09:37
2

We cannot directly compose functions that takes multiple parameters. Since function composition is one of the key concept in functional programming. By using Currying technique we can compose functions that takes multiple parameters.

altayseyhan
  • 735
  • 1
  • 7
  • 18
2

Using all :: (a -> Bool) -> [a] -> Bool with a curried predicate.

all (`elem` [1,2,3]) [0,3,4,5]

Haskell infix operators can be curried on either side, so you can easily curry the needle or the container side of the elem function (is-element-of).

u0b34a0f6ae
  • 48,117
  • 14
  • 92
  • 101
1

I would like to add example to @Francesco answer.

enter image description here

zawhtut
  • 8,335
  • 5
  • 52
  • 76
0

So you don't have to increase boilerplate with a little lambda.

Anonymous
  • 821
  • 1
  • 5
  • 14
0

It is very easy to create closures. From time to time i use SRFI-26. It is really cute.

knivil
  • 916
  • 5
  • 10
0

In and of itself currying is syntactic sugar. Syntactic sugar is all about what you want to make easy. C for example wants to make instructions that are "cheap" in assembly language like incrementing, easy and so they have syntactic sugar for incrementation, the ++ notation.

 t = x + y
 x = x + 1

is replaced by t = x++ + y

Functional languages could just as easily have stuff like.

f(x,y,z) = abc 
g(r,s)(z) = f(r,s,z). 
h(r)(s)(z) = f(r,s,z)

but instead its all automatic. And that allows for a g bound by a particular r0, s0 (i.e. specific values) to be passed as a one variable function.

Take for example perl's sort function which takes sort sub list where sub is a function of two variables that evaluates to a boolean and list is an arbitrary list.

You would naturally want to use comparison operators (<=>) in Perl and have sortordinal = sort (<=>) where sortordinal works on lists. To do this you would sort to be a curried function.
And in fact sort of a list is defined in precisely this way in Perl.

In short: currying is sugar to make first class functions more natural.

jbolden1517
  • 319
  • 1
  • 3