Scala:Demystifying TheFunky StuffDaniel HinojosaEmail: dhinojosa@evolutionnext.comTwitter: @dhinojosa Google+: gplus.to/dh...
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 & T...
Predef
Predef●   scala.Predef object●   Automatically available since scala package is    automatically included.●   Contains com...
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 bel...
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 =              ...
Stable/Singleton Typeobject SomeSingleton {   val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type =              ...
Stable/Singleton Typeobject SomeSingleton {   val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type =              ...
Stable/Singleton Typeobject SomeSingleton {   val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type =              ...
Stable/Singleton Typeobject SomeSingleton {   val z = "Grande Latte"}def drink(x:SomeSingleton.type) {   x.z should be ("G...
Stable/Singleton Typeobject SomeSingleton {   val z = "Grande Latte"}def drink(x:SomeSingleton.type) {   x.z should be ("G...
Stable/Singleton Typeobject SomeSingleton {   val z = "Grande Latte"}def drink(x:SomeSingleton.type) {   x.z should be ("G...
Stable/Singleton Typeobject SomeSingleton {   val z = "Grande Latte"}def drink(x:SomeSingleton.type) {   x.z should be ("G...
Stable/Singleton Typecase class Celebrity(firstName:String,                lastName:String)val tomHanks = new Celebrity("T...
Stable/Singleton Typeclass Celebrity(firstName:String,                lastName:String)val tomHanks = new Celebrity("Tom", ...
Stable/Singleton Typeclass Celebrity(firstName:String,                lastName:String)val tomHanks = new Celebrity("Tom", ...
Stable/Singleton Typeclass Celebrity(firstName:String,                lastName:String)val tomHanks = new Celebrity("Tom", ...
Stable/Singleton Typeclass Celebrity(firstName:String,                lastName:String)val tomHanks = new Celebrity("Tom", ...
Abstract Typesabstract class Generator {   type F   def generate: F}class StringGenerator extends Generator {   type F = S...
Abstract Typesabstract class Generator {   type F   def generate: F}class StringGenerator extends Generator {   type F = S...
Abstract Typesabstract class Generator {   type F   def generate: F}class StringGenerator extends Generator {   type F = S...
Abstract Typesabstract class Generator {   type F   def generate: F}class StringGenerator extends Generator {   type F = S...
Abstract Typesabstract class Generator {   type F   def generate: F}class StringGenerator extends Generator {   type F = S...
Abstract Typesabstract class Generator {   type F   def generate: F}class StringGenerator extends Generator {   type F = S...
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,...
Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple   (couple: Loves[Person,...
Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple   (couple: Loves[Person,...
Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple   (couple: Person Loves ...
Infix Typescase class Person(name: String)class Loves[A, B](val a: A, val b: B)def announceCouple   (couple: Person Loves ...
Infix Types with Infix Operatorscase class Person(name: String) {   def loves(person: Person) =      new Loves(this, perso...
Infix Types with Infix Operatorscase class Person(name: String) {   def loves(person: Person) =      new Loves(this, perso...
Infix Types with Infix Operatorscase class Person(name: String) {   def loves(person: Person) =      new Loves(this, perso...
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*la...
implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit   dollarsPerHour: BigDecimal) =    dollarsPerHour * hoursimp...
implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit   dollarsPerHour: BigDecimal) =    dollarsPerHour * hoursimp...
implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit   dollarsPerHour: BigDecimal) =    dollarsPerHour * hoursimp...
implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit   dollarsPerHour: BigDecimal) =    dollarsPerHour * hoursimp...
multiple implicit parameters
multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount:                                  BigDecimal...
multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount:                                  BigDecimal...
multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit                                  amount: BigDecimal...
multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit                                  amount: BigDecimal...
multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit                                  amount: BigDecimal...
multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit                                  amount: BigDecimal...
default arguments instead of          implicit
default arguments instead of            implicitdef howMuchCanIMake_?(hours: Int,                      amount: BigDecimal ...
default arguments instead of            implicitdef howMuchCanIMake_?(hours: Int,                      amount: BigDecimal ...
default arguments instead of            implicitdef howMuchCanIMake_?(hours: Int,                      amount: BigDecimal ...
default arguments instead of            implicitdef howMuchCanIMake_?(hours: Int,                      amount: BigDecimal ...
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 ...
implicit objects in implicit         parameterscase class Employee(firstName:String, lastName:String,salary:Float)implicit...
Meta-programming
Monkey Patching in Ruby             class Integer               def squared                 self * self               end ...
Issues with Monkey Patching in                   Ruby       ● Other imports can override the your         patch, effective...
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(v...
implicit wrappersclass MyIntWrapper(val original: Int) {     def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(v...
implicit wrappersclass MyIntWrapper(val original: Int) {     def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(v...
implicit wrappersclass MyIntWrapper(val original: Int) {     def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(v...
implicit wrappers class MyIntWrapper(val original: Int) {      def isOdd = original % 2 != 0 } implicit def int2MyIntWrapp...
implicit wrappersclass MyIntWrapper(val original: Int) {     def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(v...
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.toStrin...
implicit convertersimport java.math.BigIntegerimplicit def Int2BigIntegerConvert(value: Int) =new BigInteger(value.toStrin...
implicit converters with functionsimport java.math.BigIntegerimplicit val int2BigIntegerConvert = (value:Int) => new BigIn...
implicit converters with functionsimport java.math.BigIntegerimplicit val int2BigIntegerConvert = (value:Int) => new BigIn...
Where do implicits come from   other than declarations?
Importing implicitsobject MyPredef {   class MyIntWrapper(val original: Int) {     def isOdd() = original % 2 != 0       d...
Importing implicitsobject MyPredef {   class MyIntWrapper(val original: Int) {     def isOdd() = original % 2 != 0       d...
Importing implicitsobject MyPredef {   class MyIntWrapper(val original: Int) {     def isOdd() = original % 2 != 0       d...
Importing implicitsobject MyPredef {   class MyIntWrapper(val original: Int) {     def isOdd() = original % 2 != 0       d...
Importing implicitsobject MyPredef {   class MyIntWrapper(val original: Int) {     def isOdd() = original % 2 != 0       d...
Importing implicitsobject MyPredef {   class MyIntWrapper(val original: Int) {     def isOdd() = original % 2 != 0       d...
Companion implicitsclass StringNumbering(val s:String, val i:Int) {  override def toString = s  def + (other:StringNumberi...
Companion implicitsclass StringNumbering(val s:String, val i:Int) {  override def toString = s  def + (other:StringNumberi...
Companion implicitsclass StringNumbering(val s:String, val i:Int) {  override def toString = s  def + (other:StringNumberi...
Companion implicitsclass StringNumbering(val s:String, val i:Int) {  override def toString = s  def + (other:StringNumberi...
Companion implicitsclass StringNumbering(val s:String, val i:Int) {  override def toString = s  def + (other:StringNumberi...
package implicitspackage com.xyzcorppackage object abcproject {   implicit val preferredAppliance =         new Appliance(...
package implicitspackage com.xyzcorppackage object abcproject {   implicit val preferredAppliance =         new Appliance(...
package implicitspackage com.xyzcorppackage object abcproject {   implicit val preferredAppliance =         new Appliance(...
package implicitspackage com.xyzcorppackage object abcproject {   implicit val preferredAppliance =         new Appliance(...
implicitly[]
implicitly[]●   Contained within Predef●   Returns the implicit object (includes functions)    that is currently with scop...
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 ...
Manifestsdef inspect[T](l: List[T])              (implicit manifest:Manifest[T])              = manifest.toStringval list ...
Manifestsdef inspect[T](l: List[T])              (implicit manifest:Manifest[T])              = manifest.toStringval list ...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{    def +(t: T) = "1 %s has b...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{    def +(t: T) = "1 %s has b...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]){    def +(t: T) = "1 %s has ...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]){    def +(t: T) = "1 %s has ...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{    def +(t: T) = "1 %s has b...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{    def +(t: T) = "1 %s has b...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{    def +(t: T) = "1 %s has b...
Manifestscase class Monkey(name: String)class Barrel[T](implicit m:scala.reflect.Manifest[T]{    def +(t: T) = "1 %s has b...
Manifests*Code Smell: Use Sparingly
Type Variances
The Setuptrait Fruitabstract class Citrus extends Fruitclass Orange extends Citrusclass Tangelo extends Citrusclass Apple ...
Simple Invariant Caseclass MyContainer[A](a: A)                     (implicit manifest:                      scala.reflect...
Simple Invariant Caseclass MyContainer[A](a: A)                     (implicit manifest:                      scala.reflect...
Simple Invariant Caseclass MyContainer[A](a: A)                     (implicit manifest:                      scala.reflect...
Simple Invariant Caseclass MyContainer[A](a: A)                     (implicit manifest:                      scala.reflect...
Explicitly Declaring Typeclass MyContainer[A](a: A)                     (implicit manifest:                     scala.refl...
Explicitly Declaring Typeclass MyContainer[A](a: A)                     (implicit manifest:                     scala.refl...
Explicitly Declaring Type Differentlyclass MyContainer[A](a: A)                    (implicit manifest:                    ...
Explicitly Declaring Type Differentlyclass MyContainer[A](a: A)                    (implicit manifest:                    ...
Explicitly Type Coersionclass MyContainer[A](a: A)                     (implicit manifest:                      scala.refl...
Explicitly Type Coersionclass MyContainer[A](a: A)                     (implicit manifest:                      scala.refl...
Explicitly Type Coersionclass MyContainer[A](a: A)                     (implicit manifest:                      scala.refl...
Attempting Polymorphismclass MyContainer[A](a: A)                     (implicit manifest:                      scala.refle...
Attempting Polymorphismclass MyContainer[A](a: A)                     (implicit manifest:                      scala.refle...
Covariance
Covarianceclass MyContainer[+A](a: A)                     (implicit manifest:                      scala.reflect.Manifest[...
Covarianceclass MyContainer[+A](a: A)                     (implicit manifest:                      scala.reflect.Manifest[...
Covarianceclass MyContainer[+A](a: A)                     (implicit manifest:                      scala.reflect.Manifest[...
Covarianceclass MyContainer[+A](a: A)                     (implicit manifest:                      scala.reflect.Manifest[...
Covarianceclass MyContainer[+A](a: A)                     (implicit manifest:                      scala.reflect.Manifest[...
Covarianceclass MyContainer[+A](a: A)                     (implicit manifest:                      scala.reflect.Manifest[...
Covarianceclass MyContainer[+A](a: A)                     (implicit manifest:                      scala.reflect.Manifest[...
Covariance Explained      trait Fruit      abstract class Citrus extends Fruit      class Orange extends Citrus      class...
Contravariance
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravarianceclass MyContainer[-A](a: A)                     (implicit manifest:                      scala.reflect.Manif...
Contravariance Explained        trait Fruit        abstract class Citrus extends Fruit        class Orange extends Citrus ...
Invariance Revisitedclass MyContainer[A](a: A)                     (implicit manifest:                      scala.reflect....
Invariance Revisitedclass MyContainer[A](a: A)                     (implicit manifest:                      scala.reflect....
Invariance Revisitedclass MyContainer[A](a: A)                     (implicit manifest:                      scala.reflect....
Real Life Scala Funkabstract class Funny[+A, +B] {       def foo(a:A):B}[error] covariant type A occurs in contravariant  ...
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 ...
Type Bounds●   Constrain what can be used in a class●   Constrain what can be used in a type●   They are orthogonal to typ...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Upper Boundclass MyContainer[A <: Citrus](a: A)                      (implicit manifest:                       scala.refle...
Covariance Type Param with           Upper Boundclass MyContainer[+A <: Citrus](a: A)      (implicit manifest:       scala...
Covariance Type Param with           Upper Boundclass MyContainer[+A <: Citrus](a: A)      (implicit manifest:       scala...
Covariance Type Param with           Upper Boundclass MyContainer[+A <: Citrus](a: A)      (implicit manifest:       scala...
Covariance Type Param with           Upper Boundclass MyContainer[+A <: Citrus](a: A)      (implicit manifest:       scala...
Contravariance Type Param with         Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Ma...
Contravariance Type Param with         Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Ma...
Contravariance Type Param with         Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Ma...
Contravariance Type Param with         Upper Boundclass MyContainer[-A <: Citrus](a: A)(implicitmanifest: scala.reflect.Ma...
Contravariance Type Param with both Upper and Lower Boundsclass MyContainer[-A >: Citrus <: AnyRef](a: A)      (implicit m...
Contravariance Type Param with both Upper and Lower Boundsclass MyContainer[-A >: Citrus <: AnyRef](a: A)      (implicit m...
Contravariance Type Param with both Upper and Lower Boundsclass MyContainer[-A >: Citrus <: AnyRef](a: A)      (implicit m...
Too many permutations, but just         a reminder...●   Type Variances have little to do with Type    Bounds.●   The left...
View Bounds
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
View Boundsimport java.math.{BigInteger => JBigInt}implicit def Int2BigIntegerConvert(value: Int) =             new JBigIn...
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) // 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) // 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...
Partial Functions
Partial Functions●   Performs an function●   If Criteria is met
Partial Functionsval doubleEvens: PartialFunction[Int, Int] =      new PartialFunction[Int, Int] {    def isDefinedAt(x: I...
Partial Functionsval doubleEvens: PartialFunction[Int, Int] =      new PartialFunction[Int, Int] {    def isDefinedAt(x: I...
Partial Functionsval doubleEvens: PartialFunction[Int, Int] =      new PartialFunction[Int, Int] {    def isDefinedAt(x: I...
Partial Functionsval doubleEvens: PartialFunction[Int, Int] =      new PartialFunction[Int, Int] {    def isDefinedAt(x: I...
Partial Functionsval doubleEvens: PartialFunction[Int, Int] =      new PartialFunction[Int, Int] {    def isDefinedAt(x: I...
Partial Functionsval doubleEvens: PartialFunction[Int, Int] =      new PartialFunction[Int, Int] {    def isDefinedAt(x: I...
Partial Functions as case            statementsval doubleEvens: PartialFunction[Int, Int] =           new PartialFunction[...
Partial Functions as case         statementsval doubleEvens: PartialFunction[Int, Int] = {  case x: Int if ((x % 2) == 0) ...
andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2) == 0) => x * 2}v...
andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2) == 0) => x * 2}v...
andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2) == 0) => x * 2}v...
andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2) == 0) => x * 2}v...
andThen More Partial Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2) == 0) => x * 2}v...
andThen More Compound Partial         Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2)...
andThen More Compound Partial         Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2)...
andThen More Compound Partial         Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2)...
andThen More Compound Partial         Functionsval doubleEvens: PartialFunction[Int, Int] = {      case x: Int if ((x % 2)...
Overtime?
Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList =                List("1", "2", "3", "4", "5")d...
Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList =                List("1", "2", "3", "4", "5")d...
Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList =                List("1", "2", "3", "4", "5")d...
Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList =                List("1", "2", "3", "4", "5")d...
Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList =      List("1", "2", "3", "4", "5")def    crea...
Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList =      List("1", "2", "3", "4", "5")def    crea...
Context Boundimplicit val intList = List(1,2,3,4,5)implicit val stringList =      List("1", "2", "3", "4", "5")def    crea...
Generalized Type Constraints     <:<    <%<     =:=
Generalized Type Constraintsclass Pair[T](val first: T, val second: T) {   def smaller = if (first < second) first        ...
Generalized Type Constraintsclass Pair[T](val first: T, val second: T) {   def smaller = if (first < second) first        ...
Generalized Type Constraintsclass Pair[T <: Ordered[T]]          (val first: T, val second: T) {   def smaller = if (first...
Generalized Type Constraintsclass Pair[T]          (val first: T, val second: T) {   def smaller(implicit ev: T <:< Ordere...
Generalized Type Constraintsclass Pair[T]          (val first: T, val second: T) {   def smaller(implicit ev: T <:< Ordere...
Conclusion
Thank you
Upcoming SlideShare
Loading in …5
×

Scala Demystifying the Funky Stuff

927 views
874 views

Published on

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

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
927
On SlideShare
0
From Embeds
0
Number of Embeds
21
Actions
Shares
0
Downloads
36
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Scala Demystifying the Funky Stuff

  1. 1. Scala:Demystifying TheFunky StuffDaniel HinojosaEmail: dhinojosa@evolutionnext.comTwitter: @dhinojosa Google+: gplus.to/dhinojosa
  2. 2. The Goal“To make Scala less mysterious, less intimidating”
  3. 3. Funky def.Funky(slang): strange, far out
  4. 4. 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
  5. 5. Predef
  6. 6. Predef● scala.Predef object● Automatically available since scala package is automatically included.● Contains commons type aliases, and implicits (to be discussed)
  7. 7. Types, Abstract Types and Type Projections
  8. 8. Typestype Goober = Intval x:Goober = 3
  9. 9. Typesclass Foo { class Bar {}}val foo = new Foo()val bar = new foo.Bar()
  10. 10. 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
  11. 11. Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
  12. 12. Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
  13. 13. Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
  14. 14. Typesclass Foo { class Bar {}}val foo = new Foo()val bar:Foo#Bar = new foo.Bar()val bar:foo.Bar = new foo.Bar()
  15. 15. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
  16. 16. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
  17. 17. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
  18. 18. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}val favoriteDrink: SomeSingleton.type = SomeSingletonfavoriteDrink.z // Grande Latte"
  19. 19. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
  20. 20. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
  21. 21. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
  22. 22. Stable/Singleton Typeobject SomeSingleton { val z = "Grande Latte"}def drink(x:SomeSingleton.type) { x.z should be ("Grande Latte")}drink(SomeSingleton)
  23. 23. 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) {}
  24. 24. 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) {}
  25. 25. 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
  26. 26. 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
  27. 27. 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
  28. 28. 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
  29. 29. 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
  30. 30. 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
  31. 31. 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
  32. 32. 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
  33. 33. 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”
  34. 34. Abstract Types vs.Parameterized Types?
  35. 35. Infix Types
  36. 36. 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")
  37. 37. 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")
  38. 38. 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")
  39. 39. 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")
  40. 40. 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”
  41. 41. 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")
  42. 42. 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")
  43. 43. 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
  44. 44. implicit
  45. 45. implicitparameters
  46. 46. implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hours
  47. 47. implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hours
  48. 48. implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hours*last curried parameter
  49. 49. implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hoursimplicit var hourlyRate = BigDecimal(34.00)*implicit reference must be in scope to be satisfied
  50. 50. implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hoursimplicit var hourlyRate = BigDecimal(34.00)howMuchCanIMake_?(30) //1020.00
  51. 51. implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit dollarsPerHour: BigDecimal) = dollarsPerHour * hoursimplicit var hourlyRate = BigDecimal(34.00)howMuchCanIMake_?(30) //1020.00hourlyRate = BigDecimal(95.00) //reassigning
  52. 52. 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)
  53. 53. multiple implicit parameters
  54. 54. multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyName
  55. 55. multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyName
  56. 56. multiple implicit parametersdef howMuchCanIMake_?(hours: Int)(implicit amount: BigDecimal, currencyName: String) = (amount * hours).toString() + " " + currencyNameimplicit var hourlyRate = BigDecimal(34.00)implicit val currencyName = "Dollars"
  57. 57. 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"
  58. 58. 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)
  59. 59. 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"
  60. 60. default arguments instead of implicit
  61. 61. default arguments instead of implicitdef howMuchCanIMake_?(hours: Int, amount: BigDecimal = 34, currencyName: String ="Dollars") = (amount * hours).toString() + " " + currencyName
  62. 62. default arguments instead of implicitdef howMuchCanIMake_?(hours: Int, amount: BigDecimal = 34, currencyName: String ="Dollars") = (amount * hours).toString() + " " + currencyNamehowMuchCanIMake_?(30) // 1020 Dollars
  63. 63. 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
  64. 64. 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
  65. 65. implicit objects in implicit parameters
  66. 66. implicit objects in implicit parameterscase class Employee(firstName:String, lastName:String,salary:Float)
  67. 67. implicit objects in implicit parameterscase class Employee(firstName:String, lastName:String,salary:Float)implicit object CEO extends Employee("Charo", "Frostycorn", 499000.22f)
  68. 68. 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.
  69. 69. Meta-programming
  70. 70. 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
  71. 71. 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
  72. 72. Mopping in Groovyclass Integer def squared self * self endend>> 4.squared=> 16
  73. 73. implicit wrappers
  74. 74. implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}
  75. 75. implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newIntWrapper(value)
  76. 76. implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)
  77. 77. implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)
  78. 78. implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)
  79. 79. 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
  80. 80. implicit wrappersclass MyIntWrapper(val original: Int) { def isOdd = original % 2 != 0}implicit def int2MyIntWrapper(value: Int) = newMyIntWrapper(value)19.isOdd // true20.isOdd // false
  81. 81. implicit converters
  82. 82. implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
  83. 83. implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
  84. 84. implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
  85. 85. implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
  86. 86. implicit convertersimport java.math.BigIntegerimplicit def int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
  87. 87. implicit convertersimport java.math.BigIntegerimplicit def Int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)
  88. 88. implicit convertersimport java.math.BigIntegerimplicit def Int2BigIntegerConvert(value: Int) =new BigInteger(value.toString)def add(a: BigInteger, b: BigInteger) = a.add(b)
  89. 89. 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"))
  90. 90. 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"))
  91. 91. 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"))
  92. 92. Where do implicits come from other than declarations?
  93. 93. 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
  94. 94. 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
  95. 95. 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
  96. 96. 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
  97. 97. 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
  98. 98. 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
  99. 99. 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
  100. 100. 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
  101. 101. 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
  102. 102. 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
  103. 103. 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
  104. 104. 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
  105. 105. 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
  106. 106. 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
  107. 107. 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
  108. 108. implicitly[]
  109. 109. implicitly[]● Contained within Predef● Returns the implicit object (includes functions) that is currently with scope at moment of request.
  110. 110. implicitly[]implicit val secretOfLife=42implicitly[Int] // 42
  111. 111. implicitly[]implicit val secretOfLife=42implicitly[Int] // 42
  112. 112. implicitly[]implicit val secretOfLife=42implicitly[Int] // 42
  113. 113. implicitly[]implicitly[[Ordering[Int]] //From Predef
  114. 114. implicitly[]implicitly[[Ordering[Int]] //From Predefscala.math.Ordering$Int$@5aa77506
  115. 115. Manifests
  116. 116. Manifestsdef inspect[T](l: List[T]) (implicit manifest:Manifest[T]) = manifest.toStringval list = 1 :: 2 :: 3 :: 4 :: 5 :: Nilinspect(list) // Int
  117. 117. Manifestsdef inspect[T](l: List[T]) (implicit manifest:Manifest[T]) = manifest.toStringval list = 1 :: 2 :: 3 :: 4 :: 5 :: Nilinspect(list) // Int
  118. 118. Manifestsdef inspect[T](l: List[T]) (implicit manifest:Manifest[T]) = manifest.toStringval list = 1 :: 2 :: 3 :: 4 :: 5 :: Nilinspect(list) // Int
  119. 119. 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"
  120. 120. 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"
  121. 121. 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"
  122. 122. 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"
  123. 123. 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"
  124. 124. 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"
  125. 125. 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"
  126. 126. 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"
  127. 127. Manifests*Code Smell: Use Sparingly
  128. 128. Type Variances
  129. 129. The Setuptrait Fruitabstract class Citrus extends Fruitclass Orange extends Citrusclass Tangelo extends Citrusclass Apple extends Fruitclass Banana extends Fruitclass NavelOrange extends Fruit
  130. 130. 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
  131. 131. 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
  132. 132. 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
  133. 133. 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
  134. 134. 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
  135. 135. 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
  136. 136. 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
  137. 137. 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
  138. 138. 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"
  139. 139. 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"
  140. 140. 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
  141. 141. 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())
  142. 142. 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]
  143. 143. Covariance
  144. 144. 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
  145. 145. 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
  146. 146. 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
  147. 147. 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!
  148. 148. 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!
  149. 149. 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!
  150. 150. 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!
  151. 151. 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
  152. 152. Contravariance
  153. 153. 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}
  154. 154. 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}
  155. 155. 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}
  156. 156. 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
  157. 157. 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
  158. 158. 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
  159. 159. 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
  160. 160. 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
  161. 161. 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
  162. 162. 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]
  163. 163. 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?
  164. 164. 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
  165. 165. 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
  166. 166. 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
  167. 167. 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
  168. 168. 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
  169. 169. Real Life Scala Funk (Fixed)abstract class Funny[-A, +B] { def foo(a:A):B}Mind Trick: - goes in ; + goes out
  170. 170. 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()}
  171. 171. 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
  172. 172. 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}
  173. 173. 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}
  174. 174. 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
  175. 175. 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
  176. 176. 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
  177. 177. 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
  178. 178. 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
  179. 179. 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
  180. 180. 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]
  181. 181. 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}
  182. 182. 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}
  183. 183. 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
  184. 184. 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]
  185. 185. 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}
  186. 186. 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
  187. 187. 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
  188. 188. 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]
  189. 189. 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}
  190. 190. 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}
  191. 191. 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}
  192. 192. 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.
  193. 193. View Bounds
  194. 194. 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)
  195. 195. 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)
  196. 196. 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)
  197. 197. 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)
  198. 198. 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)
  199. 199. 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)
  200. 200. 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)
  201. 201. 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)
  202. 202. Partially Applied Functions vs. Partial Functions
  203. 203. Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15
  204. 204. Partially Applied Functiondef sum(a: Int, b: Int, c: Int) = a + b + cval sum3 = sum _sum3(1, 9, 7) // 17sum(4, 5, 6) // 15
  205. 205. 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
  206. 206. 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
  207. 207. 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
  208. 208. 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
  209. 209. Partial Functions
  210. 210. Partial Functions● Performs an function● If Criteria is met
  211. 211. Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}
  212. 212. Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}
  213. 213. Partial Functionsval doubleEvens: PartialFunction[Int, Int] = new PartialFunction[Int, Int] { def isDefinedAt(x: Int) = x % 2 == 0 def apply(v1: Int) = v1 * 2}
  214. 214. 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}
  215. 215. 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
  216. 216. 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
  217. 217. 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}
  218. 218. 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
  219. 219. 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
  220. 220. 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
  221. 221. 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
  222. 222. 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
  223. 223. 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
  224. 224. 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
  225. 225. 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
  226. 226. 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
  227. 227. 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")
  228. 228. Overtime?
  229. 229. 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"
  230. 230. 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"
  231. 231. 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"
  232. 232. 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"
  233. 233. 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”
  234. 234. 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”
  235. 235. 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”
  236. 236. Generalized Type Constraints <:< <%< =:=
  237. 237. Generalized Type Constraintsclass Pair[T](val first: T, val second: T) { def smaller = if (first < second) first else second}
  238. 238. 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]
  239. 239. 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]
  240. 240. Generalized Type Constraintsclass Pair[T] (val first: T, val second: T) { def smaller(implicit ev: T <:< Ordered[T]) = if (first < second) first else second}
  241. 241. Generalized Type Constraintsclass Pair[T] (val first: T, val second: T) { def smaller(implicit ev: T <:< Ordered[T]) = if (first < second) first else second}
  242. 242. Conclusion
  243. 243. Thank you

×