DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Languages
  4. Scala: Call Me By My Name Please?

Scala: Call Me By My Name Please?

Alex Staveley user avatar by
Alex Staveley
·
Jan. 24, 13 · Interview
Like (0)
Save
Tweet
Share
5.37K Views

Join the DZone community and get the full member experience.

Join For Free

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. 


Scala (programming language)

Published at DZone with permission of Alex Staveley, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Using the PostgreSQL Pager With MariaDB Xpand
  • Spring Cloud: How To Deal With Microservice Configuration (Part 1)
  • Kotlin Is More Fun Than Java And This Is a Big Deal
  • What Should You Know About Graph Database’s Scalability?

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: