Kevin Meredith
Kevin Meredith

Reputation: 41909

Higher Order Function w/ Call By-Name?

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?

Upvotes: 2

Views: 339

Answers (1)

justAbit
justAbit

Reputation: 4256

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.

Upvotes: 3

Related Questions