Kshitiz Sharma Kshitiz Sharma - 4 days ago 7
Scala Question

Defining variables in scala using def

In scala def is used to define a method and val, var are used for defining variables.

Consider the following code:

scala> def i = 3
i: Int

scala> i.getClass()
res0: Class[Int] = int

scala> val v = 2
v: Int = 2

scala> v.getClass()
res1: Class[Int] = int

scala> println(v)
2

scala> println(i)
3

scala> i+v
res4: Int = 5

scala> def o = () => 2+3
o: () => Int

scala> o.getClass()
res5: Class[_ <: () => Int] = class $$Lambda$1139/1753607449


Why does variable definition work using
def
? If it is defining a function that returns an
Int
then why does
getClass
show
Int
instead of a function object?

Answer

Unlike val or var declaration, def i = 3 is not variable declaration. You are defining a method/function which returns a constant 3 and i does not take any parameters.

declaration using val and var get evaluated immediately but in case of lazy val and def evaluation happens when called explicitly.

i is a not argument function. In order to get rid of confusion you could declare it using empty parenthesis as well

def i() = 3

Difference between lazy val and def is

  1. lazy val is lazily evaluated and the result is cached. That means further

  2. def declaration is evaluated every time you call method name.

Example using Scala REPL

scala> lazy val a = { println("a evaluated"); 1}
a: Int = <lazy>

scala> def i = { println("i function evaluated"); 2}
i: Int

scala> a
a evaluated
res0: Int = 1

scala> a
res1: Int = 1

scala> a
res2: Int = 1

scala> i
i function evaluated
res3: Int = 2

scala> i
i function evaluated
res4: Int = 2

scala> i
i function evaluated
res5: Int = 2

Notice that a is evaluated only once and further invocations of a return the cached result i.e lazy val is evaluated once when it is called and the result is stored forever. So you see println output once

Notice function is evaluated every time it is invoked. In this case you see println output every time you invoke the function

General Convention

There's a convention of using an empty parameter list when the method has side effects and leaving them off when its pure.

edited

scala> def i = 1
i: Int

scala> :type i
Int

scala> :type i _
() => Int
Comments