solid type systemprintln("wazzup, hetch!") }} path dependent types class a { class b} val...
TRANSCRIPT
![Page 1: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/1.jpg)
Solid Type Systemvs
Runtime Checks and Unit TestsVladimir Pavkin
![Page 2: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/2.jpg)
PlanFail Fast conceptType Safe Patterns
![Page 3: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/3.jpg)
Fail Fast
![Page 4: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/4.jpg)
Immediate andvisible failure
![Page 5: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/5.jpg)
Where can it fail?
Handled runtime exceptions & assertionsUnhandled runtime failure
![Page 6: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/6.jpg)
Handling runtime exceptions
assert(!list.isEmpty, "List must be empty")
try { str.toInt} catch { case _:Throwable => 0}
![Page 7: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/7.jpg)
Where can it fail?
Runtime checksHandled runtime exceptions & assertionsUnhandled runtime failure
![Page 8: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/8.jpg)
Runtime checks
if(container == null)
if(container.isInstanceOf[ContainerA])
![Page 9: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/9.jpg)
Where can it fail?Unit testsRuntime checksHandled runtime exceptions & assertionsUnhandled runtime failure
![Page 10: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/10.jpg)
Unit tests
it should "throw NoSuchElementException for empty stack" in { val emptyStack = new Stack[Int] a [NoSuchElementException] should be thrownBy { emptyStack.pop() }}
it should "not throw for empty stack" in { val stackWrapper = StackWrapper(new Stack[Int]) noException should be thrownBy stackWrapper.pop()}
![Page 11: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/11.jpg)
Where can it fail?LintersUnit testsRuntime checksHandled runtime exceptions & assertionsUnhandled runtime failure
![Page 12: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/12.jpg)
Linters
scalacOptions ++= Seq( "Xlint", "deprecation", "Xfatalwarnings")
// Wrong number of args to format()logger.error( "Failed to open %s. Error: %d" .format(file))
![Page 13: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/13.jpg)
Where can it fail?CompilerLintersUnit testsRuntime checksHandled runtime exceptions & assertionsUnhandled runtime failure
![Page 14: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/14.jpg)
The goalTo move as much as possible to
the Compiler
![Page 15: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/15.jpg)
How?Just give it
enough type information.Type system to the rescue!
![Page 16: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/16.jpg)
Before we start...
Examplesdomain?
![Page 17: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/17.jpg)
Beefcakes!
No offense intended :)
![Page 18: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/18.jpg)
Ok?
def becomeAMan(douchebag: Person): Man = if(douchebag.weight > 70) new Man(douchebag.renameTo("Arny")) else null
No! Unhandled runtime failure!
becomeAMan(vpavkin).name //vpavkin.weight < 70
![Page 19: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/19.jpg)
NULL
![Page 20: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/20.jpg)
Can we handle this?
var man = becomeAMan(person)if(man != null) nameelse //...
![Page 21: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/21.jpg)
Still not nice.code client has to clutter code with runtime checks (or fail)compiler won't complain if you forget to check
![Page 22: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/22.jpg)
If you control the source code,don't ever use null as a return result.
It's like farting in an elevator.
Some random guy at a random Scala forum
![Page 23: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/23.jpg)
The problem is
insufficient type information!Return type should be something like
ManOrNull
![Page 24: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/24.jpg)
Option
![Page 25: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/25.jpg)
Option
sealed trait Option[T]case class Some[T](x: T) extends Option[T]case object None extends Option[Nothing]
![Page 26: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/26.jpg)
Better API
def becomeAMan(douchebag: Person): Option[Man] = if(douchebag.weight > 70) Some(new Man(douchebag.renameTo("Arny"))) else None
code is documentationclient has to deal with None result at compile time.
![Page 27: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/27.jpg)
Use wrapped value?
def firstWorkout(douchebag: Person): Option[WorkoutResult] = becomeAMan(douchebag).map(man => man.workout())
Unwrap?
def willHaveASexyGirlfriend(douchebag: Person): Boolean = becomeAMan(douchebag) match { case Some(man) => true case None => false }
![Page 28: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/28.jpg)
Exceptions
![Page 29: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/29.jpg)
Classic
def workout(man: Man): WorkoutResult = if(!man.hasShaker) throw new Error("Not enough protein!!!!111") else // do some squats or stare in the mirror for 1h
Again!Client either uses try/catch or fails at runtime!Return type doesn't tell anything about possible failure
![Page 30: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/30.jpg)
Let's add sometypes!
![Page 31: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/31.jpg)
scala.Eitheror
scalaz.\/
![Page 32: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/32.jpg)
Declare possible failure
![Page 33: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/33.jpg)
Better API
def workout(man:Man): ProteinFail \/ WorkoutResult = if(!man.hasShaker) ProteinFail("Not enough protein!!!!111").left else someWorkoutResult.right
code is documentationclient has to deal with errors at compile time.
![Page 34: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/34.jpg)
scalaz.\/
sealed trait \/[E, R]case class \/[E](a: E) extends (E \/ Nothing)case class \/[R](a: R) extends (Nothing \/ R)
![Page 35: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/35.jpg)
Use wrapped value?
workout(man).map(result => submitToFacebook(result))// type is// ProteinFail \/ Future[List[FacebookLike]]
Unwrap?
def tellAboutTheWorkout(w: ProteinFail \/ WorkoutResult): String = w match { case \/(fail) => "F**k your proteins, I can do without it" case \/(result) => s"Dude, eat proteins, or you won't do like me: $result" }
![Page 36: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/36.jpg)
isInstanceOf[Man]
![Page 37: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/37.jpg)
isInstanceOf[T]
trait GymClientcase class Man(name: String) extends GymClientcase class Douchebag(name: String) extends GymClient
def gymPrice(h: GymClient): Int = if(h.isInstanceOf[Man]){ val man = h.asInstanceOf[Man] if(man.name == "Arny") 0 else 100 } else { 200 }
![Page 38: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/38.jpg)
So runtime.
// Add another client typecase class PrettyGirl(name:String) extends GymClient
It still compiles.
And we charge girls as much asdouchebags!
It's an unhandled runtime failure!
![Page 39: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/39.jpg)
isInstanceOf[T]
trait GymClientcase class Man(name: String) extends GymClientcase class Douchebag(name: String) extends GymClientcase class PrettyGirl(name:String) extends GymClient
def gymPrice(h: GymClient): Int = if(h.isInstanceOf[Man]){ val man = h.asInstanceOf[Man] if(man.name == "Arny") 0 else 100 } else { 200 }
![Page 40: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/40.jpg)
sealed ADT+
pattern matching
![Page 41: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/41.jpg)
sealed = can't be extended inother files
![Page 42: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/42.jpg)
Algebraic Data Type
1) Product types
2) Sum types
![Page 43: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/43.jpg)
Compiler knowsall the possible class/trait
children.
![Page 44: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/44.jpg)
Sealed ADT + pattern matching
sealed trait GymClientcase class Man(name: String) extends GymClientcase class Douchebag(name: String) extends GymClient
def gymPrice(h: GymClient): Int = h match { case Man("Arny") => 0 case _: Man => 100 case _: Douchebag => 200}// compiler checks, that match is exhaustive
![Page 45: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/45.jpg)
What if we add girls now?
sealed trait GymClientcase class Man(name: String) extends GymClientcase class Douchebag(name: String) extends GymClientcase class PrettyGirl(name:String) extends GymClient
def gymPrice(h: GymClient): Int = h match { case Man("Arny") => 0 case _: Man => 100 case _: Douchebag => 200}// COMPILE ERROR! Match fails for PrettyGirl.
![Page 46: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/46.jpg)
Compiler saved us again!
![Page 47: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/47.jpg)
Tagging
![Page 48: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/48.jpg)
Gym DB
case class Beefcake(id: String, name: String)case class GymPass(id: String, ownerId: String)
![Page 49: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/49.jpg)
Safer: Tags
trait JustTagdef onlyTagged(value: String @@ JustTag): String = s"Tagged string: $value" // can use as plain String
onlyTagged("plain string") // Compiler errorval tagged = tag[JustTag]("tagged")onlyTagged(tagged) // OK
![Page 50: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/50.jpg)
Gym DB: safer keys
case class Beefcake(id: String @@ Beefcake, name: String)case class GymPass(id: String @@ GymPass, ownerId: String @@ Beefcake)
![Page 51: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/51.jpg)
Phantom Types
![Page 52: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/52.jpg)
PullUp
sealed trait PullUpStatefinal class Up extends PullUpStatefinal class Down extends PullUpState
![Page 53: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/53.jpg)
PullUp
class Beefcake[S <: PullUpState] private () { def pullUp[T >: S <: Down]() = this.asInstanceOf[Beefcake[Up]]
def pullDown[T >: S <: Up]() = this.asInstanceOf[Beefcake[Down]]}
object Beefcake { def create() = new Beefcake[Down]}
![Page 54: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/54.jpg)
PullUp
val fresh = Beefcake.create() //Beefcake[Down]val heDidIt = fresh.pullUp() //Beefcake[Up]val notAgainPlease = heDidIt.pullUp()// CompileError:// inferred type arguments [Up] do not conform// to method pullUp's type parameter bounds
![Page 55: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/55.jpg)
Path Dependent Types
![Page 56: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/56.jpg)
The Two Gyms
class Gym(val name: String)class Beefcake(val gym: Gym){ def talkTo(other: Beefcake): Unit = println("Wazzup, Hetch!")}
val normalGym = new Gym("nicefitness")val swagGym = new Gym("kimberly")val normalGuy = new Beefcake(normalGym)val swagGuy = new Beefcake(swagGym)normalGuy.talkTo(swagGuy) // we don't want that
![Page 57: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/57.jpg)
The Two Gyms
Runtime solution
class Beefcake(val gym: Gym){ def talkTo(other: Beefcake): Unit = { // throws IllegalArgumentException if false require(this.gym == other.gym) println("Wazzup, Hetch!") }}
![Page 58: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/58.jpg)
Path Dependent Types
class A { class B}val a1 = new Aval a2 = new Avar b = new a1.B // type is a1.Bb = new a2.B // Compile Error: types don't match
Type depends on the value it belongs to.
![Page 59: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/59.jpg)
Type safe solution
class Gym(val name: String){ class Beefcake(val gym: Gym){ def talkTo(other: Beefcake): Unit = println("Wazzup, Hetch!") }}
val normalGym = new Gym("nicefitness")val swagGym = new Gym("kimberly")val normalGuy = new normalGym.Beefcake(normalGym)val swagGuy = new swagGym.Beefcake(swagGym)normalGuy.talkTo(swagGuy) // doesn't compile, Yay!
![Page 60: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/60.jpg)
This is not a talk about Scala type system.
Not covered:Trait compositionExistential typesMacrosType ClassesShapeless...
![Page 61: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/61.jpg)
Q & A
![Page 62: Solid Type Systemprintln("Wazzup, Hetch!") }} Path Dependent Types class A { class B} val a1 = new A val a2 = new A var b = new a1.B // type is a1.B b = new a2.B // Compile Error:](https://reader033.vdocuments.mx/reader033/viewer/2022051914/60053e9e4c17d2137171ebe9/html5/thumbnails/62.jpg)
Thank you!
goo.gl/U0WYABPDF