Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: normal functions vs tupled functions?

What's the difference between these? I know that their type signatures are different, and that all functions start off normal and have to be .tupled to get their tupled form. What's the advantage of using un-tupled (but non-curried) functions? Especially because it seems to me that passing multiple arguments to a tupled function automagically unpacks them anyway, so by all appearances they are the same.

One difference i see is that it forces you to have types for every number of function arguments: Function0, Function1, Function2, Function3 etc, whereas tupled functions are all just Function1[A, R], but that seems like a downside. What's the big advantage of using non-tupled functions that they're the default?

like image 890
Li Haoyi Avatar asked Nov 29 '11 07:11

Li Haoyi


2 Answers

Tupled functions require that a tuple object be created when they are called (unless the arguments happen to already be packed into a tuple). Non-tupled functions simply define a method that takes the appropriate number of arguments. Thus, given the JVM architecture, non-tupled functions are more efficient.

like image 61
Rex Kerr Avatar answered Oct 30 '22 00:10

Rex Kerr


Consider this example:

scala> def mult = (x: Int, y: Int) => x * y
mult: (Int, Int) => Int

scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

scala> list zip list map mult
<console>:10: error: type mismatch;
 found   : (Int, Int) => Int
 required: ((Int, Int)) => ?
              list zip list map mult
                                ^

scala> list zip list map mult.tupled
res4: List[Int] = List(1, 4, 9)

There are many situations where you end up pairing elements in tuples. In such situations, you need a tupled function to handle it. But there are many other places where that is not true! For example:

scala> list.foldLeft(1)(mult)
res5: Int = 6

scala> list.foldLeft(1)(mult.tupled)
<console>:10: error: type mismatch;
 found   : ((Int, Int)) => Int
 required: (Int, Int) => Int
              list.foldLeft(1)(mult.tupled)
                                    ^

So, basically, Scala has a dichotomy between tuples and parameters, which means you have to convert functions from tupled to untupled and vice versa here and there.

like image 40
Daniel C. Sobral Avatar answered Oct 29 '22 22:10

Daniel C. Sobral