In the Laziness section of 'Effective Scala', it says:
Fields in scala are computed by need when val is prefixed with lazy. Because fields and methods are equivalent in Scala (lest the fields are private[this])
What does it mean by 'fields' and 'methods' being equivalent? Isn't it a rather strong statement?
Well it simply means that you can define an abstract
val
by adef
and an abstractdef
by aval
.For example
has an abstract function, namely
port
. You can for sure implement (or define or override) this with adef
, like thisBut in this case every access to
port
will cause a function application (or a method call) which is simply unnecessary. For this simple reason Scala gives us the possibility of implementing the abstractdef
with a value:The same applies to abstract values. You can define abstract values with the same syntax:
And you can override them with a
def
:Stability
You may wonder what will happen if you override an abstract
val
with adef
which gives you a different value each time you call it. Will you get the first computed value because the item is aval
or you will get a different value each time you call it because the actual implementation is adef
.For example:
Fortunately Scala compiler detects this and throws the following error:
Laziness
When it comes to laziness this uniform behavior (treating fields and methods in the same way) is very useful.
First note that a
lazy
abstract value does not exist, i.e. you can not define an abstractval
aslazy
.Implementing an abstract
def
by alazy val
, on the other hand, is perfectly legal and useful. Thelazy
value will be computed only on the first call and memoized (cached and used for future calls).