简体   繁体   中英

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?

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.

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).

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM