15
$\begingroup$

In several functional languages like Haskell and OCaml, functions are automatically curried. This means that a function taking two arguments (lambda x, y: x + y) is actually a function that returns a function (lambda x: lambda y: x + y).

But most programming languages, even many functional languages, like Elixir, don't do this.

What are the advantages and disadvantages of this approach to functions?

$\endgroup$
1
  • $\begingroup$ This is not enough to substantiate an answer, but I read a paper recently that mentioned currying as a heavy impediment to the notions of ownership and locality they were introducing. In general it seemed they had difficulty with enforce something like "this function may be used only once" in the presence of partial application. $\endgroup$ Commented Aug 8, 2024 at 20:42

4 Answers 4

12
$\begingroup$

Some pros:

  1. Being concise. It has less arguments and is more readable. It also enables partial functions.
  2. Flexibility. It allows for more flexibility in function composition and permits creation of more complex functions.

Some cons:

  1. Complexity. Always important. Adding this makes the language more complex to learn.

  2. Performance. Adding automatic currying worsens performance. In some situations, it is negligible; in others, it is a real problem.

$\endgroup$
6
  • 1
    $\begingroup$ In addition for at least Haskell's case, it might not be correct to consider it a "feature" since it's actually a side effect of Haskell functions not accepting multiple arguments. Every language that supports some sort of closures actually supports this, for example Javascript: javascript let fn = (a => (b => a+b)); console.log(fn(1)(2)); $\endgroup$ Commented May 17, 2023 at 23:38
  • 1
    $\begingroup$ @kouta-kun Haskell could easily have not added dedicated syntax for defining curried functions, and people could write it just fine by passing multiple arguments through product types instead, like the ML family tends to prefer. The "automatic currying" that the question asks about is a very intentional feature. $\endgroup$ Commented May 18, 2023 at 1:52
  • 3
    $\begingroup$ By "partial functions" do you mean "partially applied functions"? $\endgroup$ Commented May 18, 2023 at 6:11
  • 1
    $\begingroup$ @kouta-kun I think it's worth talking about etymology when we discuss the language Haskell and the term "currying" and why the Haskell language decided to opt for it. There is a mathematician that came up with the concept of a function that only takes a single parameter and instead of multiple parameters, it just returns a function. This allows for using some nice properties that work on single parameter functions and makes computing them easier and more in some cases. The concept of "currying" is thus named after the mathematician: Haskell Curry. $\endgroup$ Commented May 18, 2023 at 7:49
  • $\begingroup$ Welcome back to the site! $\endgroup$ Commented Jul 28, 2024 at 11:02
16
$\begingroup$

It introduces the limitation that a single function cannot take a variable number of arguments, since giving fewer than the maximum number of arguments will simply curry and return a function, rather than do the computation on the given number of arguments.

$\endgroup$
2
  • 2
    $\begingroup$ To be fair, you can do variadic functions in Haskell. But to be even more fair, Text.Printf is not really a shining example of good Haskell code. $\endgroup$ Commented May 18, 2023 at 14:11
  • $\begingroup$ Perhaps you can? Put a special last parameter, so that computation is carried out when it comes. Like a reversed printf. $\endgroup$ Commented Jul 14 at 12:22
5
$\begingroup$

Worse error messages

In a non-curried language, if you forget an argument to a function, you get an error message saying so. In a curried language, this may silently create a partially-applied function and then the error will pop up as a type error in a different place.

$\endgroup$
1
  • 4
    $\begingroup$ This is particularly a problem in dynamically typed languages. Partially-applied functions can propagate throughout the program until finally raising a runtime error, far from the site of the error. Without static types to catch accidentally partially applied functions early, this can be a pain to track down. $\endgroup$ Commented Aug 8, 2024 at 23:23
-1
$\begingroup$

Most languages do allow this just not as concisely:

fn Add10(addMe: i32) -> i32:
  return Add(10, addMe)

So, why would you add the extra complexity to a language by having special operators when there is a much simpler method?

$\endgroup$
2
  • 6
    $\begingroup$ Isn't the point of OP that there's no operator or syntax involved? $\endgroup$ Commented May 18, 2023 at 14:30
  • $\begingroup$ Yes it is...@Adám $\endgroup$ Commented Jul 5, 2023 at 11:02

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.