Where can it fail? Handled runtime exceptions & assertions Unhandled runtime failure
Handling runtime exceptions assert(!list.isEmpty, "List must be empty")
try { str.toInt } catch { case _:Throwable => 0 }
Where can it fail? Runtime checks Handled runtime exceptions & assertions Unhandled runtime failure
Runtime checks if(container == null)
if(container.isInstanceOf[ContainerA])
Where can it fail? Unit tests Runtime checks Handled runtime exceptions & assertions Unhandled runtime failure
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() }
Where can it fail? Linters Unit tests Runtime checks Handled runtime exceptions & assertions Unhandled runtime failure
Can we handle this? var man = becomeAMan(person) if(man != null) name else //...
Still not nice. code client has to clutter code with runtime checks (or fail) compiler won't complain if you forget to check
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
The problem is
insufficient type information! Return type should be something like ManOrNull
Option
Option sealed trait Option[T] case class Some[T](x: T) extends Option[T] case object None extends Option[Nothing]
Better API def becomeAMan(douchebag: Person): Option[Man] = if(douchebag.weight > 70) Some(new Man(douchebag.renameTo("Arny"))) else None code is documentation client has to deal with None result at compile time.
Unwrap? def willHaveASexyGirlfriend(douchebag: Person): Boolean = becomeAMan(douchebag) match { case Some(man) => true case None => false }
Exceptions
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
Let's add some types!
scala.Either or
scalaz.\/
Declare possible failure
Better API def workout(man:Man): ProteinFail \/ WorkoutResult = if(!man.hasShaker) ProteinFail("Not enough protein!!!!111").left else someWorkoutResult.right code is documentation client has to deal with errors at compile time.
scalaz.\/ sealed trait \/[E, R] case class \/[E](a: E) extends (E \/ Nothing) case class \/[R](a: R) extends (Nothing \/ R)
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" }
isInstanceOf[Man]
isInstanceOf[T] trait GymClient case class Man(name: String) extends GymClient case 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 }
So runtime. // Add another client type case class PrettyGirl(name:String) extends GymClient
It still compiles. And we charge girls as much as douchebags! It's an unhandled runtime failure!
isInstanceOf[T] trait GymClient case class Man(name: String) extends GymClient case class Douchebag(name: String) extends GymClient case 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 }
sealed ADT +
pattern matching
sealed = can't be extended in other files
Algebraic Data Type 1) Product types 2) Sum types
Compiler knows all the possible class/trait children.
Sealed ADT + pattern matching sealed trait GymClient case class Man(name: String) extends GymClient case 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
What if we add girls now? sealed trait GymClient case class Man(name: String) extends GymClient case class Douchebag(name: String) extends GymClient case 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.
Compiler saved us again!
Tagging
Gym DB case class Beefcake(id: String, name: String) case class GymPass(id: String, ownerId: String)
Safer: Tags trait JustTag def onlyTagged(value: String @@ JustTag): String = s"Tagged string: $value" // can use as plain String
onlyTagged("plain string") // Compiler error val tagged = tag[JustTag]("tagged") onlyTagged(tagged) // OK
Gym DB: safer keys case class Beefcake(id: String @@ Beefcake, name: String) case class GymPass(id: String @@ GymPass, ownerId: String @@ Beefcake)
Phantom Types
PullUp sealed trait PullUpState final class Up extends PullUpState final class Down extends PullUpState
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] }
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
Path Dependent Types
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
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!") } }
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: types don't match
Type depends on the value it belongs to.
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!
This is not a talk about Scala type system. Not covered: Trait composition Existential types Macros Type Classes Shapeless ...
Solid Type System Runtime Checks and Unit Tests - GitHub
insufficient type information! Return type should be something like ... type is. // ProteinFail \/ Future[List[FacebookLike]]. Unwrap? ... case \/(result) => s"Dude, eat proteins, or you won't do like me: $result" .... Thank you! goo.gl/U0WYAB · PDF.
School of Computer Science and Engineering ... collective operations are implemented efficiently and provide a high degree of parallelism, the result of each ...
tive of their potential of supporting existing and novel scientific computing practices and ... in a consistent way as the total number of cycles available year-to-year varies ... Table 1 Life-Science usage of the TG/XSEDE over the recent quarters. .
(here I put simply hostname ) and then click Save button. From now on your connection to remote host with tunnel is saved and can be reused anytime you open ...
Apr 10, 2013 - CPAN/Perl community has usually been good at preserving backwards compatibility ... and installed. â» Writing a best practices guide for tests ...
There was a problem previewing this document. Retrying... Download. Connect more apps... Try one of the apps below to open or edit this item. OPTIMAL ...
Apr 4, 2007 - Michael Feathers defines the qualities of a good unit test as: âthey run fast, they help us localize problems.â This can be hard to accomplish when your code accesses a database, hits another server, is time-dependent, etc. By subst
Apr 4, 2007 - Stubs Speed up. Your Unit Tests. Michael Feathers defines the qualities of a good unit test as: âthey run fast, they help us localize problems.
Jan 30, 2007 - For example, when it's hard to construct a sentence where the first word is the class under test, it suggests the test may be in the wrong place. And classes that are hard to describe in general often need to be broken down into smalle
website of DiffusionKit includes test data, a complete tutorial and a series of tutorial ..... The 3D show panel supports only one active image at a ..... Illustrations of how to extract a specific fiber bundles from entire brain tractography, ... As
10. Figure 4 - Sample Data Set of Routine Management System . .... platform apps, conventional software architectural design patterns may be adopted and ...
This section describes the scope of Project Odin, as well as an overview of the contents of the SRS doc- ument. ... .1 Purpose. The purpose of this document is to provide a thorough description of the requirements for Project Odin. .... Variables. â
System Requirements Specification. Project Odin. Kyle Erwin. Joshua Cilliers. Jason van Hattum. Dimpho Mahoko. Keegan Ferrett. Note: This document is constantly under revision due to our chosen methodology, ... This section describes the scope of Pro
Feb 10, 2018 - (Haskell allows to say deriving Eq on a datatype declaration, invoking compiler magic that conjures up a .... Since type-level programming is a bit peculiar in Haskell, we'll move step by step: from normal lists over .... Before we mov
Portland State University ... opportunity to develop my interests in computer science and to pursue graduate ..... 7.13 Type inference for reified state monad (1).
and another to perform a Buddy Count. Staff must begin an immediate search if a buddy is unaccounted for. When the water is clear and all Buddies are accounted for, the swimmers may reenter the water and resume activities. Using this system does not
opportunity to develop my interests in computer science and to pursue graduate ...... algebraic data types that I made in the course of this dissertation research. Here ..... APP This rule types a function application by typing the function (f) and i
The worker system consists of 3 components: ⢠REST server: ... a âcheck outâ call which is used to tell the server that a worker is shutting down and prevent it from.
Final result was a Matlab built software application, with an image database, that utilized ... The main idea is to integrate the strengths of content- and keyword-based image ..... In the following we present some of the best search results.
Jul 21, 2014 - Give a taste of a practical software development process that is: â» test-driven ... Recently, Apple ditched Objective C for its new language Swift!