• Like
  • Save
Scala Demystifying the Funky Stuff
Upcoming SlideShare
Loading in...5
×
 

Scala Demystifying the Funky Stuff

on

  • 705 views

Presentation on Scala, and enlightening on the weird stuff that beginners may find.

Presentation on Scala, and enlightening on the weird stuff that beginners may find.

Statistics

Views

Total Views
705
Views on SlideShare
692
Embed Views
13

Actions

Likes
2
Downloads
28
Comments
0

4 Embeds 13

https://twitter.com 6
http://www.linkedin.com 5
https://si0.twimg.com 1
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Scala Demystifying the Funky Stuff Scala Demystifying the Funky Stuff Presentation Transcript

    • Scala:Demystifying TheFunky StuffDaniel HinojosaEmail: dhinojosa@evolutionnext.comTwitter: @dhinojosa Google+: gplus.to/dhinojosa
    • The Goal“To make Scala less mysterious, less intimidating”
    • Funky def.Funky(slang): strange, far out
    • Are you interested?● Covers some of the harder Scala concepts● Predef and package objects● Types, Abstract Types & Type Projections● implicit Parameters, Converters, Wrappers● Manifests● Type Variances and Bounds● Other goodness
    • Predef
    • Predef● scala.Predef object● Automatically available since scala package is automatically included.● Contains commons type aliases, and implicits (to be discussed)
    • Types, Abstract Types and Type Projections
    • Typestype Goober = Intval x:Goober = 3
    • Typesclass Foo { class Bar {}}val foo = new Foo()val bar = new foo.Bar()
    • Types class Foo { class Bar {} } val foo = new Foo() val bar = new foo.Bar()* As opposed to Java, Inner objects belong to the Outer Object not the outer class
    • Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
    • Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
    • Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
    • Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
    • Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
    • Stable/Singleton Typecase class Celebrity(firstName:String, lastName:String)val tomHanks = new Celebrity("Tom", "Hanks")val jodieFoster = new Celebrity("Jodie","Foster")val tomHanksImposter = new Celebrity("Tom", "Hanks")def enterTomHanksHouse(x:tomHanks.type) {}
    • Stable/Singleton Typeclass Celebrity(firstName:String, lastName:String)val tomHanks = new Celebrity("Tom", "Hanks")val jodieFoster = Celebrity("Jodie", "Foster")val tomHanksImposter = new Celebrity("Tom", "Hanks")def enterTomHanksHouse(x:tomHanks.type) {}
    • Stable/Singleton Typeclass Celebrity(firstName:String, lastName:String)val tomHanks = new Celebrity("Tom", "Hanks")val jodieFoster = Celebrity("Jodie", "Foster")val tomHanksImposter = new Celebrity("Tom", "Hanks")def enterTomHanksHouse(x:tomHanks.type) {}enterTomHanksHouse(tomHanks) //OK
    • Stable/Singleton Typeclass Celebrity(firstName:String, lastName:String)val tomHanks = new Celebrity("Tom", "Hanks")val jodieFoster = Celebrity("Jodie", "Foster")val tomHanksImposter = new Celebrity("Tom", "Hanks")def enterTomHanksHouse(x:tomHanks.type) {}enterTomHanksHouse(tomHanks) //OKenterTomHanksHouse(jodieFoster) //Wrong
    • Stable/Singleton Typeclass Celebrity(firstName:String, lastName:String)val tomHanks = new Celebrity("Tom", "Hanks")val jodieFoster = Celebrity("Jodie", "Foster")val tomHanksImposter = new Celebrity("Tom", "Hanks")def enterTomHanksHouse(x:tomHanks.type) {}enterTomHanksHouse(tomHanks) //OKenterTomHanksHouse(jodieFoster) //WrongenterTomHanksHouse(tomHanksImposter) //Wrong
    • Abstract Typesabstract class Generator { type F def generate: F}class StringGenerator extends Generator { type F = String def generate = "Scooters are fun"}new StringGenerator().generate // Scooters are fun
    • Abstract Typesabstract class Generator { type F def generate: F}class StringGenerator extends Generator { type F = String def generate = "Scooters are fun"}new StringGenerator().generate // Scooters are fun
    • Abstract Typesabstract class Generator { type F def generate: F}class StringGenerator extends Generator { type F = String def generate = "Scooters are fun"}new StringGenerator().generate // Scooters are fun
    • Abstract Typesabstract class Generator { type F def generate: F}class StringGenerator extends Generator { type F = String def generate = "Scooters are fun"}new StringGenerator().generate // Scooters are fun
    • Abstract Typesabstract class Generator { type F def generate: F}class StringGenerator extends Generator { type F = String def generate = "Scooters are fun"}val x = new StringGenerator()classOf[x.F] = class java.lang.StringclassOf[x.type#F] = class java.lang.StringclassOf[StringGenerator#F] = class java.lang.String
    • Abstract Typesabstract class Generator { type F def generate: F}class StringGenerator extends Generator { type F = String def generate = "Scooters are fun"}val x = new StringGenerator()classOf[x.F] = class java.lang.StringclassOf[x.type#F] = class java.lang.StringclassOf[StringGenerator#F] = class java.lang.Stringval w:x.F = “Oh yeah!”val x:x.type#F = “Rock and Roll”
    • Abstract Types vs.Parameterized Types?
    • Infix Types
    • Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple (couple: Loves[Person, Person]) = { couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(new Loves(romeo, juliet)) //Romeo is in love with Juliet")
    • Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple (couple: Loves[Person, Person]) = { couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(new Loves(romeo, juliet)) //Romeo is in love with Juliet")
    • Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple (couple: Loves[Person, Person]) = { couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(new Loves(romeo, juliet)) //Romeo is in love with Juliet")
    • Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple (couple: Person Loves Person) = { couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(new Loves(romeo, juliet)) //Romeo is in love with Juliet")
    • Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple (couple: Person Loves Person) = { couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(new Loves(romeo, juliet))//Romeo is in love with Juliet*It would be nice to say “romeo loves juliet”
    • Infix Types with Infix Operatorscase class Person(name: String) { def loves(person: Person) = new Loves(this, person)}class Loves[A, B](val a: A, val b: B)def announceCouple(couple: Person Loves Person) ={ couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(romeo loves juliet)//Romeo is in love with Juliet")
    • Infix Types with Infix Operatorscase class Person(name: String) { def loves(person: Person) = new Loves(this, person)}class Loves[A, B](val a: A, val b: B)def announceCouple(couple: Person Loves Person) ={ couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(romeo loves juliet)//Romeo is in love with Juliet")
    • Infix Types with Infix Operatorscase class Person(name: String) { def loves(person: Person) = new Loves(this, person)}class Loves[A, B](val a: A, val b: B)def announceCouple(couple: Person Loves Person) ={ couple.a.name + " is in love with " + couple.b.name}val romeo = new Person("Romeo")val juliet = new Person("Juliet")announceCouple(romeo loves juliet)//Romeo is in loveyou can omitJuliet param methods *Scala is a loose syntax language, with the () for one
    • implicit
    • implicitparameters
    • implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hours
    • implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hours
    • implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hours*last curried parameter
    • implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hoursimplicit var hourlyRate = BigDecimal(34.00)*implicit reference must be in scope to be satisfied
    • implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hoursimplicit var hourlyRate = BigDecimal(34.00)howMuchCanIMake_?(30) //1020.00
    • implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hoursimplicit var hourlyRate = BigDecimal(34.00)howMuchCanIMake_?(30) //1020.00hourlyRate = BigDecimal(95.00) //reassigning
    • implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hoursimplicit var hourlyRate = BigDecimal(34.00)howMuchCanIMake_?(30) //1020.00hourlyRate = BigDecimal(95.00) //reassigninghowMuchCanIMake_?(95) //(9025.00)
    • multiple implicit parameters
    • multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyName
    • multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyName
    • multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyNameimplicit var hourlyRate = BigDecimal(34.00)implicit val currencyName = "Dollars"
    • multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyNameimplicit var hourlyRate = BigDecimal(34.00)implicit val currencyName = "Dollars"howMuchCanIMake_?(30) // "1020.0 Dollars"
    • multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyNameimplicit var hourlyRate = BigDecimal(34.00)implicit val currencyName = "Dollars"howMuchCanIMake_?(30) // "1020.0 Dollars"hourlyRate = BigDecimal(95.00)
    • multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyNameimplicit var hourlyRate = BigDecimal(34.00)implicit val currencyName = "Dollars"howMuchCanIMake_?(30) // "1020.0 Dollars"hourlyRate = BigDecimal(95.00)howMuchCanIMake_?(95) // "9025.0 Dollars"
    • default arguments instead of implicit
    • default arguments instead of implicitdef howMuchCanIMake_?(hours: Int, amount: BigDecimal = 34, currencyName: String ="Dollars") = (amount * hours).toString() + " " + currencyName
    • default arguments instead of implicitdef howMuchCanIMake_?(hours: Int, amount: BigDecimal = 34, currencyName: String ="Dollars") = (amount * hours).toString() + " " + currencyNamehowMuchCanIMake_?(30) // 1020 Dollars
    • default arguments instead of implicitdef howMuchCanIMake_?(hours: Int, amount: BigDecimal = 34, currencyName: String ="Dollars") = (amount * hours).toString() + " " + currencyNamehowMuchCanIMake_?(30) // 1020 DollarshowMuchCanIMake_?(95, 95) // 9025 Dollars
    • default arguments instead of implicitdef howMuchCanIMake_?(hours: Int, amount: BigDecimal = 34, currencyName: String ="Dollars") = (amount * hours).toString() + " " + currencyNamehowMuchCanIMake_?(30) // 1020 DollarshowMuchCanIMake_?(95, 95) // 9025 DollarshowMuchCanIMake_?(currencyName="Yen", amount=925, hours =29) // 26825 Yen
    • implicit objects in implicit parameters
    • implicit objects in implicit parameterscase class Employee(firstName:String, lastName:String,salary:Float)
    • implicit objects in implicit parameterscase class Employee(firstName:String, lastName:String,salary:Float)implicit object CEO extends Employee("Charo", "Frostycorn", 499000.22f)
    • implicit objects in implicit parameterscase class Employee(firstName:String, lastName:String,salary:Float)implicit object CEO extends Employee("Charo", "Frostycorn", 499000.22f)def isEmployeePaidTooMuch_?(salary:Float)(implicitmodelEmployee:Employee) = salary > modelEmployee.salary* Using floating point as currency used for demonstration purposes only.
    • Meta-programming
    • Monkey Patching in Ruby class Integer def squared self * self end end >> 4.squared => 16Source: http://paulbarry.com/articles/2009/04/17/implicit-conversions-scalas-type-safe-answer-to-rubys-open-class
    • Issues with Monkey Patching in Ruby ● Other imports can override the your patch, effectively making debugging difficult. ● There are other ways of achieving the same effect. http://bit.ly/RBid2DSource:http://www.rubyinside.com/the-end-of-monkeypatching-4570.html
    • Mopping in Groovyclass Integer def squared self * self endend>> 4.squared=> 16
    • implicit wrappers
    • implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}
    • implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newIntWrapper(value)
    • implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)
    • implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)
    • implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)
    • implicit wrappers class MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0 } implicit def int2MyIntWrapper(value: Int) = new MyIntWrapper(value)* The implicit needs to be within the same scope it is to be used
    • implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)19.isOdd // true20.isOdd // false
    • implicit converters
    • implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
    • implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
    • implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
    • implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
    • implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
    • implicit convertersimport java.math.BigIntegerimplicit def Int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
    • implicit convertersimport java.math.BigIntegerimplicit def Int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)def add(a: BigInteger, b: BigInteger) = a.add(b)
    • implicit convertersimport java.math.BigIntegerimplicit def Int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)def add(a: BigInteger, b: BigInteger) = a.add(b)add(3, 6) // new BigInteger("9"))
    • implicit converters with functionsimport java.math.BigIntegerimplicit val int2BigIntegerConvert = (value:Int) => new BigInteger(value.toString)def add(a: BigInteger, b: BigInteger) = a.add(b)add(3, 6) // new BigInteger("9"))
    • implicit converters with functionsimport java.math.BigIntegerimplicit val int2BigIntegerConvert = (value:Int) => new BigInteger(value.toString)def add(a: BigInteger, b: BigInteger) = a.add(b)add(3, 6) // new BigInteger("9"))
    • Where do implicits come from other than declarations?
    • Importing implicitsobject MyPredef { class MyIntWrapper(val original: Int) { def isOdd() = original % 2 != 0 def isEven() = !isOdd() } implicit def int2MyIntWrapper(value: Int) = new MyIntWrapper(value)}import MyPredef._19.isOdd() // true20.isOdd() // false
    • Importing implicitsobject MyPredef { class MyIntWrapper(val original: Int) { def isOdd() = original % 2 != 0 def isEven() = !isOdd() } implicit def int2MyIntWrapper(value: Int) = new MyIntWrapper(value)}import MyPredef._19.isOdd() // true20.isOdd() // false
    • Importing implicitsobject MyPredef { class MyIntWrapper(val original: Int) { def isOdd() = original % 2 != 0 def isEven() = !isOdd() } implicit def int2MyIntWrapper(value: Int) = new MyIntWrapper(value)}import MyPredef._19.isOdd() // true20.isOdd() // false
    • Importing implicitsobject MyPredef { class MyIntWrapper(val original: Int) { def isOdd() = original % 2 != 0 def isEven() = !isOdd() } implicit def int2MyIntWrapper(value: Int) = new MyIntWrapper(value)}import MyPredef._19.isOdd() // true20.isOdd() // false
    • Importing implicitsobject MyPredef { class MyIntWrapper(val original: Int) { def isOdd() = original % 2 != 0 def isEven() = !isOdd() } implicit def int2MyIntWrapper(value: Int) = new MyIntWrapper(value)}import MyPredef._19.isOdd() // true20.isOdd() // false
    • Importing implicitsobject MyPredef { class MyIntWrapper(val original: Int) { def isOdd() = original % 2 != 0 def isEven() = !isOdd() } implicit def int2MyIntWrapper(value: Int) = new MyIntWrapper(value)}import MyPredef._19.isOdd() // true20.isOdd() // false
    • Companion implicitsclass StringNumbering(val s:String, val i:Int) { override def toString = s def + (other:StringNumbering) = other.i + i}object StringNumbering { implicit def fromInt(i:Int):StringNumbering = new StringNumbering("Unknown", I) implicit def fromSnToInt(sn:StringNumbering):Int = sn.i}val numberOne = new StringNumbering("One", 1)(numberOne + 3) // 4(3 + numberOne) // 4
    • Companion implicitsclass StringNumbering(val s:String, val i:Int) { override def toString = s def + (other:StringNumbering) = other.i + i}object StringNumbering { implicit def fromInt(i:Int):StringNumbering = new StringNumbering("Unknown", I) implicit def fromSnToInt(sn:StringNumbering):Int = sn.i}val numberOne = new StringNumbering("One", 1)(numberOne + 3) // 4(3 + numberOne) // 4
    • Companion implicitsclass StringNumbering(val s:String, val i:Int) { override def toString = s def + (other:StringNumbering) = other.i + i}object StringNumbering { implicit def fromInt(i:Int):StringNumbering = new StringNumbering("Unknown", I) implicit def fromSnToInt(sn:StringNumbering):Int = sn.i}val numberOne = new StringNumbering("One", 1)(numberOne + 3) // 4(3 + numberOne) // 4
    • Companion implicitsclass StringNumbering(val s:String, val i:Int) { override def toString = s def + (other:StringNumbering) = other.i + i}object StringNumbering { implicit def fromInt(i:Int):StringNumbering = new StringNumbering("Unknown", i) implicit def fromSnToInt(sn:StringNumbering):Int = sn.i}val numberOne = new StringNumbering("One", 1)(numberOne + 3) // 4(3 + numberOne) // 4
    • Companion implicitsclass StringNumbering(val s:String, val i:Int) { override def toString = s def + (other:StringNumbering) = other.i + i}object StringNumbering { implicit def fromInt(i:Int):StringNumbering = new StringNumbering("Unknown", I) implicit def fromSnToInt(sn:StringNumbering):Int = sn.i}val numberOne = new StringNumbering("One", 1)(numberOne + 3) // 4(3 + numberOne) // 4
    • package implicitspackage com.xyzcorppackage object abcproject { implicit val preferredAppliance = new Appliance("Dryer", "Gas")}In file com/xyzcorp/project/package.scalapackage com.xyzcorp.abcproject;class Appliance(val name: String, val powerType: String)class SomeClass { def foo (implicit v:Appliance) { println(v.name) //Dryer }}In file com/xyzcorp/abcproject/SomeClass.scala
    • package implicitspackage com.xyzcorppackage object abcproject { implicit val preferredAppliance = new Appliance("Dryer", "Gas")}In file com/xyzcorp/project/package.scalapackage com.xyzcorp.abcproject;class Appliance(val name: String, val powerType: String)class SomeClass { def foo (implicit v:Appliance) { println(v.name) //Dryer }}In file com/xyzcorp/abcproject/SomeClass.scala
    • package implicitspackage com.xyzcorppackage object abcproject { implicit val preferredAppliance = new Appliance("Dryer", "Gas")}In file com/xyzcorp/project/package.scalapackage com.xyzcorp.abcproject;class Appliance(val name: String, val powerType: String)class SomeClass { def foo (implicit v:Appliance) { println(v.name) //Dryer }}In file com/xyzcorp/abcproject/SomeClass.scala
    • package implicitspackage com.xyzcorppackage object abcproject { implicit val preferredAppliance = new Appliance("Dryer", "Gas")}In file com/xyzcorp/project/package.scalapackage com.xyzcorp.abcproject;class Appliance(val name: String, val powerType: String)class SomeClass { def foo (implicit v:Appliance) { println(v.name) //Dryer }}In file com/xyzcorp/abcproject/SomeClass.scala
    • implicitly[]
    • implicitly[]● Contained within Predef● Returns the implicit object (includes functions) that is currently with scope at moment of request.
    • implicitly[]implicit val secretOfLife=42implicitly[Int] // 42
    • implicitly[]implicit val secretOfLife=42implicitly[Int] // 42
    • implicitly[]implicit val secretOfLife=42implicitly[Int] // 42
    • implicitly[]implicitly[[Ordering[Int]] //From Predef
    • implicitly[]implicitly[[Ordering[Int]] //From Predefscala.math.Ordering$Int$@5aa77506
    • Manifests
    • Manifestsdef inspect[T](l: List[T]) (implicit manifest:Manifest[T]) = manifest.toStringval list = 1 :: 2 :: 3 :: 4 :: 5 :: Nilinspect(list) // Int
    • Manifestsdef inspect[T](l: List[T]) (implicit manifest:Manifest[T]) = manifest.toStringval list = 1 :: 2 :: 3 :: 4 :: 5 :: Nilinspect(list) // Int
    • Manifestsdef inspect[T](l: List[T]) (implicit manifest:Manifest[T]) = manifest.toStringval list = 1 :: 2 :: 3 :: 4 :: 5 :: Nilinspect(list) // Int
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]){ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]){ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{ def +(t: T) = "1 %s has been added".format(m.erasure.getSimpleName)}val monkeyBarrel = new Barrel[Monkey]monkeyBarrel + new Monkey("Shotgun")// "1 Monkey has been added"
    • Manifests*Code Smell: Use Sparingly
    • Type Variances
    • The Setuptrait Fruitabstract class Citrus extends Fruitclass Orange extends Citrusclass Tangelo extends Citrusclass Apple extends Fruitclass Banana extends Fruitclass NavelOrange extends Fruit
    • Simple Invariant Caseclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer(new Orange())fruitBasket.contents // Orange
    • Simple Invariant Caseclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer(new Orange())fruitBasket.contents // Orange
    • Simple Invariant Caseclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer(new Orange())fruitBasket.contents // Orange
    • Simple Invariant Caseclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer(new Orange())fruitBasket.contents // Orange
    • Explicitly Declaring Typeclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer[Fruit] (new Orange()) //Explicit callfruitBasket.contents // Fruit - static type
    • Explicitly Declaring Typeclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer[Fruit] (new Orange()) //Explicit callfruitBasket.contents // Fruit - static type
    • Explicitly Declaring Type Differentlyclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer(new Orange():Fruit) //Explicit callfruitBasket.contents // "Fruit" - static type
    • Explicitly Declaring Type Differentlyclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket = new MyContainer(new Orange():Fruit) //Explicit callfruitBasket.contents // "Fruit" - static type
    • Explicitly Type Coersionclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer(new Orange())//CoercedfruitBasket.contents // "Fruit"
    • Explicitly Type Coersionclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer(new Orange())//CoercedfruitBasket.contents // "Fruit"
    • Explicitly Type Coersionclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer(new Orange())//CoercedfruitBasket.contents // "Fruit"*Based on the expected type it fills it in with type inference
    • Attempting Polymorphismclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket:MyContainer[Fruit] = newMyContainer[Orange](new Orange())
    • Attempting Polymorphismclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def get = item def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket:MyContainer[Fruit] = newMyContainer[Orange](new Orange())[error] type mismatch;[error] found : MyContainer[Orange][error] required: MyContainer[Fruit]
    • Covariance
    • Covarianceclass MyContainer[+A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer[Orange](new Orange())fruitBasket.contents // Orange
    • Covarianceclass MyContainer[+A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer[Orange](new Orange())fruitBasket.contents // Orange
    • Covarianceclass MyContainer[+A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer[Orange](new Orange())fruitBasket.contents // Orange*There is something missing*No Method Parameters
    • Covarianceclass MyContainer[+A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}class NavelOrange extends Orangeval navelOrangeBasket: MyContainer[NavelOrange] = new MyContainer[Orange](new Orange()) //Bad!val tangeloBasket: MyContainer[Tangelo] = new MyContainer[Orange](new Orange()) //Bad!
    • Covarianceclass MyContainer[+A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}class NavelOrange extends Orangeval navelOrangeBasket: MyContainer[NavelOrange] = new MyContainer[Orange](new Orange()) //Bad!val tangeloBasket: MyContainer[Tangelo] = new MyContainer[Orange](new Orange()) //Bad!
    • Covarianceclass MyContainer[+A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}class NavelOrange extends Orangeval navelOrangeBasket: MyContainer[NavelOrange] = new MyContainer[Orange](new Orange()) //Bad!val tangeloBasket: MyContainer[Tangelo] = new MyContainer[Orange](new Orange()) //Bad!
    • Covarianceclass MyContainer[+A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}class NavelOrange extends Orangeval navelOrangeBasket: MyContainer[NavelOrange] = new MyContainer[Orange](new Orange()) //Bad!val tangeloBasket: MyContainer[Tangelo] = new MyContainer[Orange](new Orange()) //Bad!
    • Covariance Explained trait Fruit abstract class Citrus extends Fruit class Orange extends Citrus class Tangelo extends Citrus class Apple extends Fruit class Banana extends Fruit class NavelOrange extends OrangeI have an Orange Basket, you have a Fruit Basket
    • Contravariance
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.contents // Citrus
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.contents // Citrus
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}*There is something missing *No Return Values
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.contents // Citrus
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val orangeBasket: MyContainer[Orange] = new MyContainer[Citrus](new Tangelo)orangeBasket.contents // Citrus
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val tangeloBasket: MyContainer[Tangelo] = new MyContainer[Citrus](new Orange)tangeloBasket.contents // Citrus
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer[Orange](new Orange())type mismatch;[error] found : MyContainer[Orange][error] required: MyContainer[Fruit]
    • Contravarianceclass MyContainer[-A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val fruitBasket: MyContainer[Fruit] = new MyContainer(new Orange())*This is ok! Why?
    • Contravariance Explained trait Fruit abstract class Citrus extends Fruit class Orange extends Citrus class Tangelo extends Citrus class Apple extends Fruit class Banana extends Fruit class NavelOrange extends OrangeI have an Orange Basket, you have a NavelOrange Basket
    • Invariance Revisitedclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // CitruscitrusBasket.set(new Tangelo)citrusBasket.contents // Citrus
    • Invariance Revisitedclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // CitruscitrusBasket.set(new Tangelo)citrusBasket.contents // Citrus
    • Invariance Revisitedclass MyContainer[A](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // CitruscitrusBasket.set(new Tangelo)citrusBasket.contents // Citrus
    • Real Life Scala Funkabstract class Funny[+A, +B] { def foo(a:A):B}[error] covariant type A occurs in contravariant position in type A of value a[error] def foo(a:A):B[error] ^[error] one error found*Method Parameter is in the contravariant position*Return Value is in the covariant position
    • Real Life Scala Funk (Fixed)abstract class Funny[-A, +B] { def foo(a:A):B}Mind Trick: - goes in ; + goes out
    • Function1package scalatrait Function1[-T1, +R] extends java.lang.Object with scala.ScalaObject { def $init$() : Unit def apply(v1 : T1) : R def compose[A](g : Function1[A, T1]) : Function1[A, R] def andThen[A](g : Function1[R, A]) : Function1[T1, A] override def toString()}
    • Type Bounds● Constrain what can be used in a class● Constrain what can be used in a type● They are orthogonal to type variance● Scala Only
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // Citrus
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // Citrus
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // Citrus
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // Citrus
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.set(new Orange)citrusBasket.contents // CitruscitrusBasket.set(new Tangelo)citrusBasket.contents // Citrus
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}new MyContainer(new Orange) //OK
    • Upper Boundclass MyContainer[A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def get = item def contents = manifest.erasure.getSimpleName}new MyContainer(new Orange) //OKnew MyContainer[Fruit](new Orange)type arguments [Fruit] do not conform to classMyContainers type parameter bounds [A <: Citrus]
    • Covariance Type Param with Upper Boundclass MyContainer[+A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}
    • Covariance Type Param with Upper Boundclass MyContainer[+A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}
    • Covariance Type Param with Upper Boundclass MyContainer[+A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket: MyContainer[Citrus] = new MyContainer[Citrus](new Orange)citrusBasket.contents // Citrusval citrusBasket2: MyContainer[Citrus] = new MyContainer(new Tangelo)citrusBasket2.contents // Citrus
    • Covariance Type Param with Upper Boundclass MyContainer[+A <: Citrus](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] val item = a def get = item def contents = manifest.erasure.getSimpleName}val citrusBasket6: MyContainer[Fruit] = new MyContainer(new Orange)type arguments [Fruit] do not conform to classMyContainers type parameter bounds [+A <: Citrus]
    • Contravariance Type Param with Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}
    • Contravariance Type Param with Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val citrusBasket1: MyContainer[Citrus] = new MyContainer(new Tangelo)citrusBasket1.contents // Citrusval citrusBasket2 = new MyContainer(new Tangelo)citrusBasket2.contents // Tangelo
    • Contravariance Type Param with Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val citrusBasket1: MyContainer[Citrus] = new MyContainer(new Tangelo)citrusBasket1.contents // Citrusval citrusBasket2 = new MyContainer(new Tangelo)citrusBasket2.contents // Tangeloval citrusBasket3 = new MyContainer(new Orange)citrusBasket3.contents // Orange
    • Contravariance Type Param with Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}val citrusBasket6 = new MyContainer(new Apple)val citrusBasket7 = new MyContainer(new Orange():Fruit)val citrusBasket8:MyContainer[Fruit] = new MyContainer(new Orange())inferred type arguments do not conform to classMyContainers type parameter bounds [-A <:AboutTypeBounds.this.Citrus]
    • Contravariance Type Param with both Upper and Lower Boundsclass MyContainer[-A >: Citrus <: AnyRef](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}
    • Contravariance Type Param with both Upper and Lower Boundsclass MyContainer[-A >: Citrus <: AnyRef](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}
    • Contravariance Type Param with both Upper and Lower Boundsclass MyContainer[-A >: Citrus <: AnyRef](a: A) (implicit manifest: scala.reflect.Manifest[A]) { private[this] var item = a def set(a: A) {item = a} def contents = manifest.erasure.getSimpleName}
    • Too many permutations, but just a reminder...● Type Variances have little to do with Type Bounds.● The left hand type must be undefined, the others defined.● Scala will coerce and infer types for you.
    • View Bounds
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T] (x: T, y: T)(implicit v: T => JBigInt) = v(y).add(v(x))add(3, 5) // BigInteger(15)
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T] (x: T, y: T)(implicit v: T => JBigInt) = v(y).add(v(x))add(3, 5) // BigInteger(15)
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T] (x: T, y: T)(implicit v: T => JBigInt) = v(y).add(v(x))add(3, 5) // BigInteger(15)
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T] (x: T, y: T)(implicit v: T => JBigInt) = v(y).add(v(x))add(3, 5) // BigInteger(15)
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T] (x: T, y: T)(implicit v: T => JBigInt) = v(y).add(v(x))add(3, 5) // BigInteger(15)
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T] (x: T, y: T)(implicit v: T => JBigInt) = y.add(x)add(3, 5) // BigInteger(15)
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T <% JBigInt] (x: T, y: T) = y.add(x)add(3, 5) // BigInteger(15)
    • View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) = new JBigInt(value.toString)def add[T <% JBigInt] (x: T, y: T) = y.add(x)add(3, 5) // BigInteger(15)
    • Partially Applied Functions vs. Partial Functions
    • Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15
    • Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15
    • Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15def sum(a: Int, b: Int, c: Int) = a + b + cval sumC = sum(1, 10, _:Int) //not a castsumC(4) // 15sum(4, 5, 6) // 15
    • Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15def sum(a: Int, b: Int, c: Int) = a + b + cval sumC = sum(1, 10, _:Int) //not a castsumC(4) // 15sum(4, 5, 6) // 15
    • Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15def sum(a: Int, b: Int, c: Int) = a + b + cval sumC = sum(1, 10, _:Int) //not a castsumC(4) // 15sum(4, 5, 6) // 15
    • Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15def sum(a: Int, b: Int, c: Int) = a + b + cval sumC = sum(1, 10, _:Int) //not a castsumC(4) // 15sum(4, 5, 6) // 15
    • Partial Functions
    • Partial Functions● Performs an function● If Criteria is met
    • Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}
    • Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}
    • Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}
    • Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}val tripleOdds: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 != 0 def apply(v1: Int) = v1 * 3}
    • Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}val tripleOdds: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 != 0 def apply(v1: Int) = v1 * 3}val whatToDo = doubleEvens orElse tripleOdds
    • Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}val tripleOdds: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 != 0 def apply(v1: Int) = v1 * 3}val whatToDo = doubleEvens orElse tripleOddswhatToDo(3) // 9whatToDo(4) // 8
    • Partial Functions as case statementsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}Can become...val doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}
    • Partial Functions as case statementsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val whatToDo = doubleEvens orElse tripleOddswhatToDo(3) // 9whatToDo(4) // 8
    • andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val addFive = (x: Int) => x + 5val whatToDo = doubleEvens orElse tripleOdds andThen addFivewhatToDo(3) // 14whatToDo(4) // 13
    • andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val addFive = (x: Int) => x + 5val whatToDo = doubleEvens orElse tripleOdds andThen addFivewhatToDo(3) // 14whatToDo(4) // 13
    • andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val addFive = (x: Int) => x + 5val whatToDo = doubleEvens orElse tripleOdds andThen addFivewhatToDo(3) // 14whatToDo(4) // 13
    • andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val addFive = (x: Int) => x + 5val whatToDo = doubleEvens orElse tripleOdds andThen addFivewhatToDo(3) // 14whatToDo(4) // 13
    • andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val addFive = (x: Int) => x + 5val whatToDo = doubleEvens orElse tripleOdds andThen addFivewhatToDo(3) // 14whatToDo(4) // 13
    • andThen More Compound Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val printEven: PartialFunction[Int, String] = { case x: Int if ((x % 2) == 0) => "Even"}val printOdd: PartialFunction[Int, String] = { case x: Int if ((x % 2) != 0) => "Odd"}val whatToDo = doubleEvens orElse tripleOdds andThen (printEven orElse printOdd)whatToDo(3) // OddwhatToDo(4) // Even
    • andThen More Compound Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val printEven: PartialFunction[Int, String] = { case x: Int if ((x % 2) == 0) => "Even"}val printOdd: PartialFunction[Int, String] = { case x: Int if ((x % 2) != 0) => "Odd"}val whatToDo = doubleEvens orElse tripleOdds andThen (printEven orElse printOdd)whatToDo(3) // OddwhatToDo(4) // Even
    • andThen More Compound Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val printEven: PartialFunction[Int, String] = { case x: Int if ((x % 2) == 0) => "Even"}val printOdd: PartialFunction[Int, String] = { case x: Int if ((x % 2) != 0) => "Odd"}val whatToDo = doubleEvens orElse tripleOdds andThen (printEven orElse printOdd)whatToDo(3) // OddwhatToDo(4) // Even
    • andThen More Compound Partial Functionsval doubleEvens: PartialFunction[Int, Int] = { case x: Int if ((x % 2) == 0) => x * 2}val tripleOdds: PartialFunction[Int, Int] = { case x: Int if ((x % 2) != 0) => x * 3}val printEven: PartialFunction[Int, String] = { case x: Int if ((x % 2) == 0) => "Even"}val printOdd: PartialFunction[Int, String] = { case x: Int if ((x % 2) != 0) => "Odd"}val whatToDo = doubleEvens orElse tripleOdds andThen (printEven orElse printOdd)whatToDo(3) should be("Odd")whatToDo(4) should be("Even")
    • Overtime?
    • Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList = List("1", "2", "3", "4", "5")def createCollectionBasedOnSample[A](a:A) (implicit m:Manifest[A], sample:List[A]) = { sample}createCollectionBasedOnSample(1).apply(0) //1createCollectionBasedOnSample("Foo").apply(0) //"1"
    • Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList = List("1", "2", "3", "4", "5")def createCollectionBasedOnSample[A](a:A) (implicit m:Manifest[A], sample:List[A]) = { sample}createCollectionBasedOnSample(1).apply(0) //1createCollectionBasedOnSample("Foo").apply(0) //"1"
    • Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList = List("1", "2", "3", "4", "5")def createCollectionBasedOnSample[A](a:A) (implicit m:Manifest[A], sample:List[A]) = { sample}createCollectionBasedOnSample(1).apply(0) //1createCollectionBasedOnSample("Foo").apply(0) //"1"
    • Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList = List("1", "2", "3", "4", "5")def createCollectionBasedOnSample[A](a:A) (implicit m:Manifest[A], sample:List[A]) = { sample}createCollectionBasedOnSample(1).apply(0) //1createCollectionBasedOnSample("Foo").apply(0) //"1"
    • Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList = List("1", "2", "3", "4", "5")def createCollectionBasedOnSample[A:Manifest:List] (a:A) = { implicitly[List[A]]}createCollectionBasedOnSample(2).apply(0) //1createCollectionBasedOnSample(“Foo”).apply(0) //”1”
    • Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList = List("1", "2", "3", "4", "5")def createCollectionBasedOnSample[A:Manifest:List] (a:A) = { implicitly[List[A]]}createCollectionBasedOnSample(2).apply(0) //1createCollectionBasedOnSample(“Foo”).apply(0) //”1”
    • Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList = List("1", "2", "3", "4", "5")def createCollectionBasedOnSample[A:Manifest:List] (a:A) = { implicitly[List[A]]}createCollectionBasedOnSample(2).apply(0) //1createCollectionBasedOnSample(“Foo”).apply(0) //”1”
    • Generalized Type Constraints <:< <%< =:=
    • Generalized Type Constraintsclass Pair[T](val first: T, val second: T) { def smaller = if (first < second) first else second}
    • Generalized Type Constraintsclass Pair[T](val first: T, val second: T) { def smaller = if (first < second) first else second}*This only works if type T is is Ordered[T]
    • Generalized Type Constraintsclass Pair[T <: Ordered[T]] (val first: T, val second: T) { def smaller = if (first < second) first else second}*Not all T is Ordered[T]
    • Generalized Type Constraintsclass Pair[T] (val first: T, val second: T) { def smaller(implicit ev: T <:< Ordered[T]) = if (first < second) first else second}
    • Generalized Type Constraintsclass Pair[T] (val first: T, val second: T) { def smaller(implicit ev: T <:< Ordered[T]) = if (first < second) first else second}
    • Conclusion
    • Thank you