Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Value Definitions: Confusing case for def and val evaluation

Since and I quote from Martin Odersky:

  • The def form is “by-name”, its right hand side is evaluated on each use.
  • The right-hand side of a val definition is evaluated at the point of the definition itself.

In this case:

  • def loop: Boolean = loop
  • val x = loop // Leads to an infinite loop

In this case:

  • val y: Boolean = y // Evaluated to false

I'm a little confused why:

  • val x = loop // doesn't get evaluated to false?
like image 372
Muhammad Ezzat Avatar asked Nov 29 '25 16:11

Muhammad Ezzat


1 Answers

If you use

val y: Boolean = y

in statement position inside method body, it doesn't evaluate to anything at all, because it gives a compile time error:

error: forward reference extends over definition of value y

However, if you use it as a member variable, it compiles to a separate private variable initialized with _, a getter def, and a separate initializer:

private[this] val y: Boolean = _;
<stable> <accessor> def y(): Boolean = XeqX.this.y;

[...]

def <init>(): WhateverYourClassIsCalled.type = {
  XeqX.super.<init>();
  XeqX.this.y = XeqX.this.y();
  ()
}

Since _ on right hand side for booleans evaluates to default value false, by the time you access it in initializer, the member y is already set to false.


In contrast to that

def loop: Boolean = loop

never terminates once it's called. Therefore

val x = loop

tries to evaluate its right hand side immediately, and then hangs forever.


Here is another answer for a similar problem (again, difference between def and val).

like image 83
Andrey Tyukin Avatar answered Dec 02 '25 06:12

Andrey Tyukin