Wednesday, April 3, 2013

Scala: Call by Name

Functional languages typically implement the call by name evaluation strategy natively. There are some special use cases where such an evaluation strategy may boost performance and one of the examples was given here.

The case  in consideration is how log statements within code can be made more efficient while being clean. Typically log level determines if the log statement actually does something in the code. 

For example, lets say you wanted to put the following log statement in the code:

logger.info("ok" + "to" + "concatenate" + "string" + "to" + "log" +"message")

If the check for the log level is done inside the log method, then by the time the check is done, the string concatenation would already have been performed. That would lead to bad performance. So the solution would be to wrap the code above with a check on the log level:

if (logger.isEnabledFor(Logger.INFO)) {
    // Ok to log now.
    logger.info("ok" + "to" + "concatenate" + "string" + "to" + "log" +"message");
}

In a language like Scala, this would be achieved by using a call by name argument to the logger method. The call by name argument is evaluated (pretty much like a parameter-less function call) only when needed. It is different from a lazy evaluation in that it is evaluated each time it is needed (call it lazy with no memory!).

Here is the code quoted from the above article:

def log(level: Level, message: => String) = if (logger.level.intValue >= level.intValue) logger.log(level, msg)

Another excellent example can be seen here.


No comments: