2

Given:

def higherOrderCallByName(f: => Int => Int, x: Int): Int = f(x)
def higherOrderCallByValue(f: Int => Int, x: Int): Int = f(x)

under what circumstances is it idiomatic/proper to use call by-name for a a function argument, i.e f in higherOrderCallByName?

Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • 3
    If for some reason producing the function is an expensive call? – Michael Zajac Jul 07 '16 at 03:15
  • 1
    I don't think this makes any difference as in scala functions are by default call-by-name. Passing function as argument and making it call-by-value doesn't make any difference. I have tested this with a small demo function. Correct me if i am wrong. – Abhi Jul 07 '16 at 06:01
  • @ManjeetKumar **scala functions are by default call-by-name** can you please support this using an example? I think typically it's by-value. See example below. – justAbit Jul 07 '16 at 06:44
  • @SudhirSingh : scala functions are by default call-by-value. it's my mistake, i have interchanged the terms. – Abhi Jul 07 '16 at 06:47
  • Possible duplicate of [Call by name vs call by value in Scala, clarification needed](http://stackoverflow.com/questions/13337338/call-by-name-vs-call-by-value-in-scala-clarification-needed) – meucaa Jul 07 '16 at 08:43

1 Answers1

3

Just to clarify, in call-by-value, the value of the parameter is determined before it is passed to the function, while in call-by-name evaluation of the parameter is deferred until it is used inside the function.

I concur with m-z, higherOrderCallByName is perfectly valid where passed function can be an expensive call.

Another scenario I can think of is, if passed function has some side effect then by-name parameter will behave differently than by-value parameter. I have modified your example to demonstrate this:

def higherOrderCallByName(f: => Int => Int, x: Int): Int = {
  println("Inside by-name function.")
  f(x)
}

def higherOrderCallByValue(f: Int => Int, x: Int): Int = {
  println("Inside by-value function.")
  f(x)
}

def funWithSideEffect() : (Int) => Int = {
  println("Some side effect.") // some side-effect or some expensive call
  x => x + 1    // returns function which increments param
}

Now if you call higherOrderCallByValue(funWithSideEffect(), 2) output will be:

Some side effect.
Inside by-value function.

As output suggests, side-effect occurs before higherOrderCallByValue's body executes.

Whereas output of higherOrderCallByName(funWithSideEffect(), 2) will be like:

Inside by-name function.
Some side effect.

Where side-effect occurs inside higherOrderCallByName when f(x) is encountered. Now imagine the scenario where f(x) is executed multiple times inside higherOrderCallByName. Clearly it would have lot of impact in your application.

justAbit
  • 4,226
  • 2
  • 19
  • 34
  • So, besides the side effect case, what other reason would a function be "expensive"? – Kevin Meredith Jul 07 '16 at 11:27
  • As mentioned, `funWithSideEffect` can also have some expensive processing going on. Based on this as well you would want to decide if that calculation can be postponed for sometime later. – justAbit Jul 07 '16 at 11:33