5

I don't have very clear the partial application of functions in Scala... I will do an example:

def myOperation(x: Int)(y: Int): Int = {
    val complexVal = complexCalc(x)
    println("complexVal calculated")
    complexVal + y
}
def complexCalc(x: Int): Int = x * 2

val partial = myOperation(5)_

println("calculate")
println("result(3): " + partial(3))
println("result(1): " + partial(1))

The output of this will be:

calculate
complexVal calculated
result(3): 13
complexVal calculated
result(1): 11

So the complexVal was calculated 2 times, what if I want to calculate it just once?

For who has javascript knowledge something like:

function myOperation(x) {
     var complexVal = complexCalc(x)
     return function(y){
         complexVal + y
     }
}

EDIT:
So what's the difference between what I've written previously and this:

def myOperation2(x: Int, y: Int): Int = {
    val complexVal = complexCalculation(x)
    println("complexVal calculated")
    complexVal + y
}

val partial = myOperation(5)_
val partial2 = myOperation2(5, _: Int)
rascio
  • 8,968
  • 19
  • 68
  • 108

3 Answers3

4

You can explicitly return a function from myOperation:

def myOperation(x: Int): Int => Int = {
    val complexVal = complexCalc(x)
    println("complexVal calculated")
    (y: Int) => complexVal + y
}
Lee
  • 142,018
  • 20
  • 234
  • 287
  • So the shorthand `def myOperation(x: Int)(y: Int): Int` is totally unuseful for this case? – rascio May 26 '14 at 15:06
  • 3
    People often mistake multiple parameter list functions as being currying, which they are not. True currying, which is what is being done here, actually executes a function that returns another function. A multiple parameter list function is in no way "shorthand" for an actual curried function. – reggert May 26 '14 at 15:17
  • I've updated the question with another thing, are that two ways of write the same stuff? – rascio May 26 '14 at 15:32
  • At the bytecode level, a function with multiple parameter lists is identical to a function with a single parameter list containing multiple parameters. Only the Scala compiler cares that they are different. – reggert May 26 '14 at 15:38
3

Partial application just creates a new function by filling in some of the arguments of an existing function, but does not actually execute any part of that function.

For what you're trying to do, you want to return a function from a function. In this case, what you're actually doing is currying (true currying).

Try this:

def myOperation(x : Int) : (Int => Int => Int) = {
   val complexVal = complexCalc(x)
   (y : Int) => complexVal + y
}
reggert
  • 732
  • 3
  • 10
2

Partial application binds a value to a function argument to give you a function with decreased arity (i.e. fewer arguments). This does not provide any form of memoisation of your expensive computation.

Lee's answer is perfectly good way of solving that problem.

pete23
  • 2,204
  • 23
  • 28