Richard Searle's Blog

Thoughts about software

Surprising initialization of abstract Scala vals

Posted by eggsearle on January 11, 2012

Consider the problem of computing deltas between entries in a stream of events.  Each event is paired with the previous value and delivered to a derived implementation. This requires an initial value to be paired with initial value, what might be called the zero.

package function
trait Delta[T] {
   def zero: T
   private var before: T = zero
   def update(current: T) {
      if (before != current) {
         delta(before, current)
         before = current
      }
   }
   def delta(before: T, current: T)
}

In the above code, the zero is provided by an abstract function.

The implementation might then be

case class StringDelta extends Delta[String] {
def zero = ""
def delta(before: String, current: String) {
      println(before, current)
   }
}

 

This works fine, but looks a little odd. The zero is a constant, which one might expect to be defined using a val. Changing def zero to val zero compiles (Scala permits abstract vals) but the run-time value is actually null.

Changing the definition to be lazy, i.e. lazy val zero = “” , restores the desired behavior. The underlying implementation of lazy is obviously rather similar to def, being executed on first reference to the name.

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: