loop is defined as below:
 def loop : Boolean = loop
When x is defined as: def x = loop then "x: Boolean" is shown in console.
and
When x is defined as: val x = loop then it goes to infinite loop
I know def is using call by-name and val is using call by-value. Even though this point about loop defined above is not much clear.
a new value can be defined with keyword val. eg. val x: Int = 5. Here type is optional as scala can infer it from the assigned value.
def is the keyword you use to define a method, the method name is double , and the input parameter a has the type Int , which is Scala's integer data type. The body of the function is shown on the right side, and in this example it simply doubles the value of the input parameter a : def double(a: Int) = a * 2 -----
Difference between Scala Functions & Methods: Function is a object which can be stored in a variable. But a method always belongs to a class which has a name, signature bytecode etc. Basically, you can say a method is a function which is a member of some object.
The multiple assignments can be possible in Scala in one line by using 'val' keyword with variable name separated by commas and the "=" sign with the value for the variable.
def doesn't evaluate the right-hand side of the assignment. Just like
def f(x : Int) = x + 2
doesn't (in this case logically can't) evaluate f of anything, just defines what the function f, means, neither def loop : Boolean = loop nor def x = loop evaluate anything. You are just defining a function to be executed at some other point.
But vals do require the right-hand side of the assignment to be evaluated. So val x = loop tries to execute the expression on the right-hand side. Trying to evaluate loop never terminates, though, since loop is an infinite loop.
The call-by-name or call-by-value distinction seems less useful in this case, because neither your x, nor your loop take any arguments.
But there are two other ways in which val and def differ.
First distinction is: eager vs. lazy.
val is evaluated eagerly, as soon as the val is defined.def is evaluated lazily, as soon as the
def is accessed.For example:
def x = { println("x is evaluated"); 42 } 
val y = { println("y is evaluated"); 42 }
x
Will print:
y is evaluated
x is evaluated
because y is evaluated immediately, whereas x is evaluated only when we call it.
The other difference is whether the result of the computation is cached or not:
val is evaluated once, and then cacheddef is evaluated every time we call the functionThis is why
def dice = { new scala.util.Random().nextInt(6) + 1 }
val once = { new scala.util.Random().nextInt(6) + 1 }
println(dice + " <-> " + once)
println(dice + " <-> " + once)
println(dice + " <-> " + once)
println(dice + " <-> " + once)
will output:
5 <-> 6
4 <-> 6
6 <-> 6
5 <-> 6
that is, dice is a more or less useful random number generator that generates values 1-6, whereas once is a rather useless random value that is fixed once it's created.
Now, you can think of a 2x2-table with eager-vs-lazy in one dimension, and cached-vs-not-cached on the other:
val is eager and cached
lazy val is lazy and cached (so are memoized defs)def is lazy and uncached
def main is a def, it always gets called anyway, so in a sense it's both kind-of eager and uncached.In your code, loop is essentially a tail-recursive version of the non-terminating
def loop: Boolean = { while (true) {}; true }
but since loop is a def, and therefore lazy, the right hand side is not evaluated when you define it.
If you now define
def x = loop
nothing is happening still, because x is also lazy, so the right hand side is again not evaluated.
But if you define
val x = loop
then x is a val, thus its right hand side is evaluated eagerly. On the right hand side of the definition, there is an invocation of loop. Now loop is accessed, and since it is a def, it now evaluates its body, and goes into an infinite loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With