SlideShare a Scribd company logo
ASSOCIATE EXPRESSIONS TO NAMES IN
SCALA
VAL, LAZY VAL, AND DEF
VAL
LAZY VAL
DEF
VAL
LAZY VAL
DEF
VAR
VAL
LAZY VAL
DEF
VAR
VAL
LAZY VAL
DEF
VAL
LAZY VAL
DEF
IN SCOPE
ACCESSED
ACCESSED
VAL
LAZY VAL
DEF
ONCE
ONCE
EVERY TIME
IN SCOPE
ACCESSED
ACCESSED
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
d evaluated
res4: String = result of d
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
d evaluated
res4: String = result of d
scala> Foo.d
object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
d evaluated
res4: String = result of d
scala> Foo.d
d evaluated
res5: String = result of d
VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
Only when parent Val is
not implemented
VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
Only when parent Val is
not implemented
Can Not Be Abstract
abstract class A {
val v: String
lazy val lv: String
def d: String
}
abstract class A {
val v: String
lazy val lv: String
def d: String
}
Can Not Be Abstract
abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
class B extends A {
lazy val v: String = "value of v"
override lazy val lv: String = "value of lv"
lazy val d: String = "value of d"
}
abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
class B extends A {
lazy val v: String = "value of v"
override lazy val lv: String = "value of lv"
lazy val d: String = "value of d"
}
class C extends A {
val v: String = "value of v"
override lazy val lv: String = "value of lv"
val d: String = "value of d"
}
abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
class B extends A {
lazy val v: String = "value of v"
override lazy val lv: String = "value of lv"
lazy val d: String = "value of d"
}
class C extends A {
val v: String = "value of v"
override lazy val lv: String = "value of lv"
val d: String = "value of d"
}
class D extends A {
val v: String = "value of v"
override lazy val lv: String = "value of lv"
def d: String = "value of d"
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
scala> c.resultB
res1: String = hello, null
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
scala> c.resultB
res1: String = hello, null
scala> c.resultA
res2: String = null, null
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = C: hello, dad
scala> c.resultB
res1: String = B: hello, null
scala> c.resultA
res2: String = null, null
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultA
res2: String = hello, dad
INITIALIZATION ORDERS IN OVERRIDES
▸ Superclasses are fully initialized before subclasses.
▸ Otherwise, in declaration order
▸ When a `val` is overriden, it is not initialized more than once.
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultA
res0: String = null, null
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultA
res0: String = null, null
scala> c.resultB
res1: String = hello, null
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultA
res0: String = null, null
scala> c.resultB
res1: String = hello, null
scala> c.resultC
res2: String = hello, dad
abstract class D {
val c: C
val x3 = c.x1
}
class E extends D {
val c = new C
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class D {
val c: C
val x3 = c.x1
}
class E extends D {
val c = new C
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> new E
abstract class D {
val c: C
val x3 = c.x1
}
class E extends D {
val c = new C
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> new E
java.lang.NullPointerException
... 30 elided
FIX 1 - USE EARLY DEFINITIONS
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends {
val x1: String = "hello"
} with A {
val resultB = x1 + ", " + x2
}
class C extends {
override val x2: String = "dad"
} with B {
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends {
val x1: String = "hello"
} with A {
val resultB = x1 + ", " + x2
}
class C extends {
override val x2: String = "dad"
} with B {
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@22d9bc14
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends {
val x1: String = "hello"
} with A {
val resultB = x1 + ", " + x2
}
class C extends {
override val x2: String = "dad"
} with B {
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@22d9bc14
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad
FIX 2 - USE LAZY VALS
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
Only when parent Val is
not implemented
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
lazy val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
lazy val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@2f74900b
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad
abstract class A {
val x1: String
lazy val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@2f74900b
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad
THANK YOU!
References: https://docs.scala-lang.org/tutorials/FAQ/initialization-order.html
@realstraw
in/kexinxie

More Related Content

PDF
A bit about Scala
PDF
WTF Oriented Programming, com Fabio Akita
PDF
Scala for Jedi
PDF
Type classes 101 - classification beyond inheritance
PDF
Object Oriented Design(s) in R
PDF
Scala intro workshop
PDF
Exploring ZIO Prelude: The game changer for typeclasses in Scala
PDF
Exploring type level programming in Scala
A bit about Scala
WTF Oriented Programming, com Fabio Akita
Scala for Jedi
Type classes 101 - classification beyond inheritance
Object Oriented Design(s) in R
Scala intro workshop
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring type level programming in Scala

Similar to Assiciate Expressions to Names in Scala (20)

PDF
Kotlin Basics - Apalon Kotlin Sprint Part 2
PDF
Scala 101
PDF
redis überall
PDF
Scala Quick Introduction
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
PDF
RxSwift 시작하기
PDF
Kotlin : Advanced Tricks - Ubiratan Soares
PDF
Laziness in Swift
PDF
Scala Intro
PPTX
“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...
PDF
Introduction to programming in scala
PPT
SDC - Einführung in Scala
ODP
Object Equality in Scala
KEY
ddd+scala
PPTX
Concurrent Application Development using Scala
PPTX
Switching from java to groovy
PDF
Introduction to Scala
Kotlin Basics - Apalon Kotlin Sprint Part 2
Scala 101
redis überall
Scala Quick Introduction
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
RxSwift 시작하기
Kotlin : Advanced Tricks - Ubiratan Soares
Laziness in Swift
Scala Intro
“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...
Introduction to programming in scala
SDC - Einführung in Scala
Object Equality in Scala
ddd+scala
Concurrent Application Development using Scala
Switching from java to groovy
Introduction to Scala
Ad

Recently uploaded (20)

PPTX
CyberSecurity Mobile and Wireless Devices
PDF
Influence of Green Infrastructure on Residents’ Endorsement of the New Ecolog...
PPTX
Fundamentals of safety and accident prevention -final (1).pptx
PPTX
6ME3A-Unit-II-Sensors and Actuators_Handouts.pptx
PDF
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
PPTX
Current and future trends in Computer Vision.pptx
PPTX
Chemical Technological Processes, Feasibility Study and Chemical Process Indu...
PPTX
Module 8- Technological and Communication Skills.pptx
PPTX
Fundamentals of Mechanical Engineering.pptx
PPTX
Information Storage and Retrieval Techniques Unit III
PDF
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
PPTX
CURRICULAM DESIGN engineering FOR CSE 2025.pptx
PDF
distributed database system" (DDBS) is often used to refer to both the distri...
PDF
BIO-INSPIRED ARCHITECTURE FOR PARSIMONIOUS CONVERSATIONAL INTELLIGENCE : THE ...
PDF
22EC502-MICROCONTROLLER AND INTERFACING-8051 MICROCONTROLLER.pdf
PPTX
introduction to high performance computing
PDF
Categorization of Factors Affecting Classification Algorithms Selection
PPTX
Amdahl’s law is explained in the above power point presentations
PDF
EXPLORING LEARNING ENGAGEMENT FACTORS INFLUENCING BEHAVIORAL, COGNITIVE, AND ...
PDF
August -2025_Top10 Read_Articles_ijait.pdf
CyberSecurity Mobile and Wireless Devices
Influence of Green Infrastructure on Residents’ Endorsement of the New Ecolog...
Fundamentals of safety and accident prevention -final (1).pptx
6ME3A-Unit-II-Sensors and Actuators_Handouts.pptx
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
Current and future trends in Computer Vision.pptx
Chemical Technological Processes, Feasibility Study and Chemical Process Indu...
Module 8- Technological and Communication Skills.pptx
Fundamentals of Mechanical Engineering.pptx
Information Storage and Retrieval Techniques Unit III
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
CURRICULAM DESIGN engineering FOR CSE 2025.pptx
distributed database system" (DDBS) is often used to refer to both the distri...
BIO-INSPIRED ARCHITECTURE FOR PARSIMONIOUS CONVERSATIONAL INTELLIGENCE : THE ...
22EC502-MICROCONTROLLER AND INTERFACING-8051 MICROCONTROLLER.pdf
introduction to high performance computing
Categorization of Factors Affecting Classification Algorithms Selection
Amdahl’s law is explained in the above power point presentations
EXPLORING LEARNING ENGAGEMENT FACTORS INFLUENCING BEHAVIORAL, COGNITIVE, AND ...
August -2025_Top10 Read_Articles_ijait.pdf
Ad

Assiciate Expressions to Names in Scala

  • 1. ASSOCIATE EXPRESSIONS TO NAMES IN SCALA VAL, LAZY VAL, AND DEF
  • 8. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } }
  • 9. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo
  • 10. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba
  • 11. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v
  • 12. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v
  • 13. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv
  • 14. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv lv evaluated res2: String = result of lv
  • 15. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv lv evaluated res2: String = result of lv scala> Foo.lv
  • 16. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv lv evaluated res2: String = result of lv scala> Foo.lv res3: String = result of lv
  • 17. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv lv evaluated res2: String = result of lv scala> Foo.lv res3: String = result of lv scala> Foo.d
  • 18. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv lv evaluated res2: String = result of lv scala> Foo.lv res3: String = result of lv scala> Foo.d d evaluated res4: String = result of d
  • 19. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv lv evaluated res2: String = result of lv scala> Foo.lv res3: String = result of lv scala> Foo.d d evaluated res4: String = result of d scala> Foo.d
  • 20. object Foo { val v: String = { println("v evaluated") "result of v" } lazy val lv: String = { println("lv evaluated") "result of lv" } def d: String = { println("d evaluated") "result of d" } } scala> Foo v evaluated res0: Foo.type = Foo$@32f96bba scala> Foo.v res1: String = result of v scala> Foo.lv lv evaluated res2: String = result of lv scala> Foo.lv res3: String = result of lv scala> Foo.d d evaluated res4: String = result of d scala> Foo.d d evaluated res5: String = result of d
  • 21. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF LAZY VAL VAL DEF Overrides Variable
  • 22. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF LAZY VAL VAL DEF Overrides Variable
  • 23. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF LAZY VAL VAL DEF Overrides Variable
  • 24. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF LAZY VAL VAL DEF Overrides Variable
  • 25. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF LAZY VAL VAL DEF Overrides Variable
  • 26. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF LAZY VAL VAL DEF Overrides Variable Only when parent Val is not implemented
  • 27. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF LAZY VAL VAL DEF Overrides Variable Only when parent Val is not implemented Can Not Be Abstract
  • 28. abstract class A { val v: String lazy val lv: String def d: String }
  • 29. abstract class A { val v: String lazy val lv: String def d: String } Can Not Be Abstract
  • 30. abstract class A { val v: String lazy val lv: String = "value of lv in A" def d: String }
  • 31. abstract class A { val v: String lazy val lv: String = "value of lv in A" def d: String } class B extends A { lazy val v: String = "value of v" override lazy val lv: String = "value of lv" lazy val d: String = "value of d" }
  • 32. abstract class A { val v: String lazy val lv: String = "value of lv in A" def d: String } class B extends A { lazy val v: String = "value of v" override lazy val lv: String = "value of lv" lazy val d: String = "value of d" } class C extends A { val v: String = "value of v" override lazy val lv: String = "value of lv" val d: String = "value of d" }
  • 33. abstract class A { val v: String lazy val lv: String = "value of lv in A" def d: String } class B extends A { lazy val v: String = "value of v" override lazy val lv: String = "value of lv" lazy val d: String = "value of d" } class C extends A { val v: String = "value of v" override lazy val lv: String = "value of lv" val d: String = "value of d" } class D extends A { val v: String = "value of v" override lazy val lv: String = "value of lv" def d: String = "value of d" }
  • 34. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 }
  • 35. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736
  • 36. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultC res0: String = hello, dad
  • 37. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultC res0: String = hello, dad scala> c.resultB res1: String = hello, null
  • 38. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultC res0: String = hello, dad scala> c.resultB res1: String = hello, null scala> c.resultA res2: String = null, null
  • 39. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultC res0: String = C: hello, dad scala> c.resultB res1: String = B: hello, null scala> c.resultA res2: String = null, null
  • 40. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultC res0: String = hello, dad scala> c.resultB res1: String = hello, dad scala> c.resultA res2: String = hello, dad
  • 41. INITIALIZATION ORDERS IN OVERRIDES ▸ Superclasses are fully initialized before subclasses. ▸ Otherwise, in declaration order ▸ When a `val` is overriden, it is not initialized more than once.
  • 42. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultA res0: String = null, null
  • 43. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultA res0: String = null, null scala> c.resultB res1: String = hello, null
  • 44. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@7cfb4736 scala> c.resultA res0: String = null, null scala> c.resultB res1: String = hello, null scala> c.resultC res2: String = hello, dad
  • 45. abstract class D { val c: C val x3 = c.x1 } class E extends D { val c = new C } abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 }
  • 46. abstract class D { val c: C val x3 = c.x1 } class E extends D { val c = new C } abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> new E
  • 47. abstract class D { val c: C val x3 = c.x1 } class E extends D { val c = new C } abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> new E java.lang.NullPointerException ... 30 elided
  • 48. FIX 1 - USE EARLY DEFINITIONS
  • 49. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends { val x1: String = "hello" } with A { val resultB = x1 + ", " + x2 } class C extends { override val x2: String = "dad" } with B { val resultC = x1 + ", " + x2 }
  • 50. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends { val x1: String = "hello" } with A { val resultB = x1 + ", " + x2 } class C extends { override val x2: String = "dad" } with B { val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@22d9bc14 scala> c.resultA res0: String = hello, dad scala> c.resultB res1: String = hello, dad scala> c.resultC res2: String = hello, dad
  • 51. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends { val x1: String = "hello" } with A { val resultB = x1 + ", " + x2 } class C extends { override val x2: String = "dad" } with B { val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@22d9bc14 scala> c.resultA res0: String = hello, dad scala> c.resultB res1: String = hello, dad scala> c.resultC res2: String = hello, dad
  • 52. FIX 2 - USE LAZY VALS
  • 53. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 }
  • 54. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { lazy val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override lazy val x2: String = "dad" val resultC = x1 + ", " + x2 }
  • 55. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { lazy val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override lazy val x2: String = "dad" val resultC = x1 + ", " + x2 } Only when parent Val is not implemented
  • 56. abstract class A { val x1: String val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override val x2: String = "dad" val resultC = x1 + ", " + x2 } abstract class A { val x1: String lazy val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { lazy val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override lazy val x2: String = "dad" val resultC = x1 + ", " + x2 }
  • 57. abstract class A { val x1: String lazy val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { lazy val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override lazy val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@2f74900b scala> c.resultA res0: String = hello, dad scala> c.resultB res1: String = hello, dad scala> c.resultC res2: String = hello, dad
  • 58. abstract class A { val x1: String lazy val x2: String = "mom" val resultA = x1 + ", " + x2 } class B extends A { lazy val x1: String = "hello" val resultB = x1 + ", " + x2 } class C extends B { override lazy val x2: String = "dad" val resultC = x1 + ", " + x2 } scala> val c = new C c: C = C@2f74900b scala> c.resultA res0: String = hello, dad scala> c.resultB res1: String = hello, dad scala> c.resultC res2: String = hello, dad