E039: Forward Reference Extends Over Definition
This error is emitted when a forward reference to a value extends over the definition of another value.
Forward references are allowed only if there are no value definitions between the reference and the definition that is referred to. Specifically, any statement between the reference and the definition cannot be a variable definition, and if it's a value definition, it must be lazy.
Example
def example =
def a: Int = b
val b: Int = a
a
Error
-- [E039] Reference Error: example.scala:2:17 ----------------------------------
2 | def a: Int = b
| ^
| forward reference to b extends over the definition of b (on line 3)
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| b is used before you define it, and the definition of b
| appears between that use and the definition of b.
|
| Forward references are allowed only if there are no value definitions between
| the reference and the definition that is referred to.
| Specifically, any statement between the reference and the definition
| cannot be a variable definition, and if it's a value definition, it must be lazy.
|
| Define b before it is used,
| or move the definition of b so it does not appear between
| the declaration of b and its use,
| or define b as lazy.
-----------------------------------------------------------------------------
Solution
// Make the forward dependency lazy
// Warning: It still might fail at runtime
def example =
def a: Int = b
lazy val b: Int = a
a
// Even better ensure to always break the dependecny chain
def example =
lazy val a: Int = if b == 0 then 1 else b
lazy val b: Int = 0
a
In this article