Chris Snow
Chris Snow

Reputation: 24588

scala call-by-name - declaring parameters that aren't used

One of the benefits of call-by-name is that expensiveOperation() will not get run in the following examples:

Call-by-value:

def test( x: Int, y: Int ): Int = x * x

// expensiveOperation is evaluated and the result passed to test()
test( 4, expensiveOperation() )  

Call-by-name:

def test( x: Int, y: => Int ): Int = x * x

// expensionOperation is not evaluated
test( 4, expensiveOperation() ) 

My question though is why would you declare a function parameter (y in my case) when you aren't going to use it?

Upvotes: 1

Views: 170

Answers (3)

Emil Ivanov
Emil Ivanov

Reputation: 37633

Using logging is a much better example:

def debug(msg: String) = if (logging.enabled) println(msg)

debug(slowStatistics()) // slowStatistics will always be evaluated

While in the case of call-by-name:

def debug(msg: => String) = if (logging.enabled) println(msg)

debug(slowStatistics()) // slowStatistics will be evaluated only if logging.enabled

Upvotes: 2

vitalii
vitalii

Reputation: 3365

Your example is a bit contrived, consider this code

def test( x: Boolean, y: => Int ): Int = if(x) y else 0

// expensionOperation is not evaluated
test( false, expensiveOperation() ) 

When the first parameter is false you are saving a lot of time not evaluating expensive operation.

Upvotes: 4

adelbertc
adelbertc

Reputation: 7320

It is just a contrived example to illustrate the idea of call-by-name, namely that the argument passed in is never evaluated if never called.

Perhaps a better example would be the following:

trait Option[+T] {
    def getOrElse[B >: A](default: => B): B
}

If the Option is Some, then the wrapped value is returned and default is never evaluated. If it is None and only when it is None will default be evaluated (and consequently returned).

Upvotes: 2

Related Questions