Łukasz Rzeszotarski Łukasz Rzeszotarski - 1 month ago 4
Scala Question

When to use lazy values in Scala?

Why Scala introduces lazy parameters. Shouldn't it be managed by the JVM (invisible for the user) how the value is initialized? What is the real world use case in which it is worth to give the control into developers hand and define values as lazy?


The by-name parameters: one of the primary motivations was to support dsls. They allow you to have a really nice syntax in APIs, that almost feel as if they're built into the language. For example, you can very easily define your own custom repeat-loop:

def repeat(body: =>Unit)(until: =>Boolean): Unit = {
  if (until) {} else repeat(body)(until)

And then use it as if it were a part of the language.

var i = 0
repeat {
  i += 1
} (i < 3)

Or you could similarly spawn a new thread like this: spawn { println("on the new thread!") }, or you could do automatic resource management of your FileInputStreams like this: withFile("/home/john/.bashrc") { println(_.contents) }.

The lazy values - the motivations here are:

  1. lazy data-structures like Streams that are popular in functional languages that you can use to implement efficient data-structure a-la Okasaki's functional queues.
  2. to avoid allocating or initializing some expensive resources if they're never used in some object, e.g. file handles or database connections.
  3. to initialize objects fields in the correct order, for objects composed of many mixins.
  4. to achieve a correct "initialize only once" semantics when there are many threads sharing a single value (see introduction here).
  5. to have a translation scheme for nested singleton objects:

class A { object B }

becomes something like:

class A {
  class A$B$
  lazy val B = new A$B$