Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between currying and multiple parameter lists?

Tags:

scala

currying

Everywhere I look, I see the terms multiple parameter lists and currying used interchangably. I see it in dozens of stackoverflow questions, and even on scala-lang.org. This page, for example, has the title "Currying". And the first sentence? "Methods may define multiple parameter lists."

And yet some very knowledgeable people get annoyed when they see multiple parameter lists and currying equated. I posted an answer to this question but then deleted it when I saw Randall Schulz's comment because I was afraid I might be inadvertently spreading misinformation. My understanding was that a function with multiple parameter lists is necessarily a curried function, but that function currying can be achieved in other ways as well (the top answer to this question lists four ways), but I'm not sure that's the whole story. I want to really understand the distinction.

I know there are a lot of very similar questions to this one on stackoverflow, but I haven't found one that precisely spells out the difference. What do I need to understand about multiple parameter lists and currying in order to speak accurately about them?

like image 893
Matt Malone Avatar asked Nov 11 '13 20:11

Matt Malone


People also ask

When should we use currying?

Currying is helpful when you have to frequently call a function with a fixed argument. Considering, for example, the following function: If we want to define the function error , warn , and info , for every type, we have two options. Currying provides a shorter, concise, and more readable solution.

What is the advantage of currying in Scala?

Advantages of Currying Function in Scala One benefit is that Scala currying makes creating anonymous functions easier. Scala Currying also makes it easier to pass around a function as a first-class object. You can keep applying parameters when you find them.

Why is currying required?

Currying is a checking method to make sure that you get everything you need before you proceed. It helps you to avoid passing the same variable again and again. It divides your function into multiple smaller functions that can handle one responsibility.

What is currying in programming?

The "currying" is the process of taking the function of multiple arguments and converting it into a serious of functions that each take a single argument and return a function of a single argument, or in the case of the final function, return the actual result.


1 Answers

I hope you don't mind if I start with a Haskell example, since Haskell is a vastly simpler language than Scala. In Haskell all functions are functions in the mathematical sense—they take one argument and return one value. Haskell also has tuples, and you can write a function that looks a little like it takes multiple parameters, as a function from a tuple to whatever. For example:

Prelude> let add = (\(x, y) -> x + y) :: (Int, Int) -> Int
Prelude> add (1, 2)
3

Now we can curry this function to get a function with type Int -> Int -> Int instead of (Int, Int) -> Int:

Prelude> let curriedAdd = curry add

This allows us to partially apply the function, for example:

Prelude> let add3 = curriedAdd 3
Prelude> add3 1
4

So we have a nice clean definition of currying—it's a function that takes a function with a tuple (specifically a pair) for an argument and returns a function that takes as an argument the first type in the pair and returns a function from the second type in the pair to the original return type. Which is just a wordy way to say this:

Prelude> :t curry
curry :: ((a, b) -> c) -> a -> b -> c

Okay, now for Scala.

In Scala you can also have functions that take a tuple argument. Scala also has "functions" that take more than one argument (Function2 and up). These are (confusingly) different kinds of animals.

Scala also has methods, which are different from functions (although they can be converted to functions more or less automatically via eta expansion). Methods can have multiple parameters, or tuple parameters, or multiple parameter lists.

So what does it mean to say we're currying something in this context?

Most literally, currying is something you do with a Function2 (and up):

scala> val add: Function2[Int, Int, Int] = (x: Int, y: Int) => x + y
add: (Int, Int) => Int = <function2>

scala> val curriedAdd = add.curried
curriedAdd: Int => (Int => Int) = <function1>

scala> val add3 = curriedAdd(3)
add3: Int => Int = <function1>

This is about the same as what we saw in the Haskell case, except that we're currying a function with multiple arguments, which is something that doesn't properly exist in Haskell.

Now I'm pretty sure this is the only context in which the word curry actually appears in the Scala standard library (not counting the accompanying uncurried on the Function companion object), but given the enormous mess that Scala makes of the idea of methods, functions, etc. (don't get me wrong—I love Scala, but this part of the language is a complete disaster), it seems pretty reasonable to me to apply the word in the following context as well:

def add(x: Int, y: Int) = x + y
def curriedAdd(x: Int)(y: Int) = add(x, y)

Here we've turned a method that takes two parameters into a method with multiple parameter lists—each of which only takes a single parameter (this last part is important).

And in fact the language specification also uses the term in this context, describing the following as "a single, curried function definition":

def func(x: Int)
        (y: Int) = x + y

(Which is of course confusing as hell, since this is a method, not a function.)

So to sum up: multiple parameter lists are one way to implement currying in Scala, but not all methods with multiple parameter lists are curried—only ones where each parameter list has a single parameter. And all the terminology is pretty mushy, anyway, so don't worry too much about getting it right.

like image 111
Travis Brown Avatar answered Oct 18 '22 16:10

Travis Brown