Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Assiciate Expressions to Names in Scala

Avatar for Kexin Xie Kexin Xie
November 19, 2017

Assiciate Expressions to Names in Scala

Val, Lazy Val and Def

Avatar for Kexin Xie

Kexin Xie

November 19, 2017
Tweet

More Decks by Kexin Xie

Other Decks in Programming

Transcript

  1. 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" } }
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  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" } } 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
  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 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
  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 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
  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 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
  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 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
  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 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
  14. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM VAL LAZY VAL DEF

    LAZY VAL VAL DEF Overrides Variable Only when parent Val is not implemented
  15. 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
  16. abstract class A { val v: String lazy val lv:

    String def d: String } Can Not Be Abstract
  17. abstract class A { val v: String lazy val lv:

    String = "value of lv in A" def d: String }
  18. 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" }
  19. 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" }
  20. 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" }
  21. 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 }
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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.
  29. 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
  30. 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
  31. 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
  32. 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 }
  33. 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
  34. 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
  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 } 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 }
  36. 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
  37. 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
  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 }
  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 } 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 }
  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 } 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
  41. 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 }
  42. 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
  43. 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