Scala: call me by my name please?

In Java, when frameworks such as log4J became popular in Java architectures it was a common occurence to see code such as:
 
 
 
 
 
 
 
 
 

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

It was considered best practice to always check if your logging was enabled for the appropriate level before performing any String concatenation. I even remember working on a project ten years ago (a 3G radio network configuration tool for Ericsson) where String concatenation for logging actually resulted in noticeable performance degradation.

Since then, JVMs have been optimised and Moore’s Law has continued so that String concatenation isn’t as much of a worry as it used to be. Many frameworks (for example Hibernate), if you check the source code you’ll see logging code where there is no check to see if logging is enabled and the string concatenation happens regardless. However, let’s pretend concatenation is a performance issue. What we’d really like to do is remove the need for the if statements in order to stop code bloat. The nub of the issue here is that in Java, when you call a method with parameters the values of the parameters are all calculated before the method is called. This why the if statement is needed.

simpleComputation(expensiveComputation());// In Java, the expensive computation is called first.
logger.log(Level.INFO, 'Log this ' + message);// In Java, the String concatenation happens first

Scala provides a mechanism where you can defer parameter evaluation. This is called call-by-name.

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

The => before the String types means that the String parameter is not evaluated before invocation of the log function. Instead, there is a check to confirm the logger level value is at the appropriate value and if so the String will then evaluated. This check happens within the log function so there is no need to put the check before every invocation of it. What about that for code re-use?

Anything else?

Yes when pass-by-name is used, the parameter that is passed-by-name isn’t just evaluated once but everytime it is referenced in the function it is passed to. Let’s look at another example

scala> def nanoTime() = {
     |   println(">>nanoTime()")
     |   System.nanoTime // returns nanoTime
     | }
nanoTime: ()Long
 
scala> def printTime(time: => Long) = {    // => indicates a by name parameter
     |   println(">> printTime()")
     |   println("time= " + time)
     |   println("second time=" + time)
     |   println("third time=" + time)
     | }
printTime: (time: => Long)Unit
 
 
scala> printTime(nanoTime())
 
>> printTime()
>>nanoTime()
time= 518263321668117
>>nanoTime()
second time=518263324003767
>>nanoTime()
third time=518263324624587

In this example, we can see that nanoTime() isn’t just executed once but everytime it is referenced in the function, printTime it is passed to. This means it is executed three times in this function and hence we get three different times. ‘Til the next time, take care of yourselves.
 

Reference: Scala: call me by my name please? from our JCG partner Alex Staveley at the Dublin’s Tech Blog blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

One Response to "Scala: call me by my name please?"

  1. Matthew Harrison says:

    For Java, check out java.util.logging.Logger.log(Level.INFO, “{0} {1}”, new Object[] { value1, value2 }) in the core,
    or log5j, or slf4j. (log4j is stuck where it is, as it is used by many legacy systems which are still stuck on Java 1.4. slf4j is the successor to log4j)

Leave a Reply


nine + = 18



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close