Scala implicitsJordi Pradel - @agile_jordi
@scalabcn
Follow me: https://github.com/agile-jordi/scalabcn-implicits-2015
implicits?TO-DO In Progress Doneimplicit
parameters
implicitconversions
implicitclasses
contextbounds
viewbounds
implicittype bounds
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
implicitclasses
contextbounds
viewbounds
implicittype bounds
implicit parameters
• no runtime effect at all
• everything happens at compile time
• you still can use an explicit argument for an implicit parameter. In such case, implicit has no effect
implicit parameters resolution
1. implicits visible to current invocation scope
• via local declaration, imports, outer scope, inheritance, package object that are accessible without prefix
• must be an implicit definition (e.g. implicit val) or an implicit parameter
2. implicit scope
• all sort of companion objects and package object that bear some relation to the implicit's type which we search for
• ¿what the hell does this mean?
implicit parameter resolution• if the parameter has a default argument and no
implicit argument can be found the default argument is used
• if there are several elegible arguments which match the implicit parameter’s type:
• a most specific one will be chosen using the rules of static overloading resolution
• what the hell does this mean?
Wally Weaver – Watchmen
“Now if you begin to feel an intense and crushing feeling of religious terror at the
concept, don't be alarmed. That indicates only that you are still sane”
ouch! help!1. simplify all these implicit resolution rules to:
1. implicits visible to current invocation scope
2. implicits in companion objects or related types
3. in case of conflict, the most specific one is used
2. use an IDE capable of helping you
• IntelliJ ⌘+⇧+P: Show implicit parameters
the good parts…
• don’t (ab)use them!
• making the user explicit was not that bad!
• declare the types of implicit declarations!
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
implicitclasses
contextbounds
viewbounds
implicittype bounds
backlogTO-DO In Progress Done
implicitparametersimplicit
conversions
implicitclasses
contextbounds
viewbounds
implicittype bounds
implicit conversions• applied when
• an expression does not conform to the expected type
• in a selection e.m, m does not denote an accessible member of e
• in a selection e.m(args), m does denote a method of e, but it is not applicable to args
implicit conversions resolution
• exactly like implicit parameter resolution except that…
• The implicit view, if it is found, can accept is argument e as a call-by-value or as a call-by-name parameter. However, call-by-value implicits take precedence over call-by-name implicits.
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
implicitclasses
contextbounds
viewbounds
implicittype bounds
pimp mylibrary
type classes
backlogTO-DO In Progress Done
implicitparameters
implicitconversionsimplicit
classes
contextbounds
viewbounds
implicittype bounds
pimp mylibrary
type classes
pimp my library• you can extend any class, even if it is not yours
• it has a runtime impact…
• … but plays well with value classes to avoid it
• use your IntelliJ
• it shows implicit conversions
• it even autocompletes methods added by pimp my library
backlogTO-DO In Progress Done
implicitparameters
contextbounds
viewbounds
implicittype bounds
type classes
implicitconversions
pimp mylibrary
implicitclasses
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
contextbounds
viewbounds
implicittype bounds
pimp mylibrary
type classes
implicitclasses
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
implicittype bounds
pimp mylibrary
type classes
implicitclasses
contextbounds
viewbounds
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
viewbounds
implicittype bounds
pimp mylibrary
type classes
implicitclasses
contextbounds
Martin Odersky - Deprecating language features for 2.10
“Context bounds are essentially the replacement of view bounds. It's what we
should have done from the start, but we did not know better back then.”
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
pimp mylibrary
type classes
implicitclasses
contextbounds
viewboundsimplicit
type bounds
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
implicittype bounds
pimp mylibrary
type classes
implicitclasses
contextbounds
viewbounds
implicit type bounds
• Typical type bounds
• T1 <: T2: T1 must be a subtype of T2
• T1 >: T2: T1 must be a supertype of T1
def foo1[T1 >: T2, T2](v1:T1, v2:T2):Boolean = truedef foo2[T1, T2 <: T1](v1:T1, v2:T2):Boolean = truefoo1(new Dog, new Cat) // same as foo1[Pet,Cat](…)foo2(new Dog, new Cat) // same as foo2[Pet,Cat](…)
implicit type bounds• <:<
• T1 <: T2: T1 must be a subtype of T2
• T1 >: T2: T1 must be a supertype of T1
def foo3[T1,T2](v1:T1, v2:T2) (implicit ev: T1<:<T2):Boolean = true// foo3(new Dog, new Cat) // Won’t compile unless explicitly told to use supertype: foo3[Dog,Pet](new Dog, new Cat)
backlogTO-DO In Progress Done
implicitparameters
implicitconversions
pimp mylibrary
type classes
implicitclasses
contextbounds
viewbounds implicit
type bounds
Oracle
“Ohh, what's really going to bake your noodle later on is, would you still have broken it if I
hadn't said anything?”
what's really going to bake your noodle later on is…
• an implicit method… can take implicit parameters itself!
implicit def list2ordered[A](x: List[A]) (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]]
• e.g. an implicit conversion method that is only applied if another implicit is found
• e.g. an definition that is only passed as an implicit argument if another implicit is found
References• @derekwyatt, implicits in scala
• @eed3si9n, implicit paramter precedence again
• @odersky, deprecating language features for 2.10
• @scala_lang, scala language specification: Implicits
• @jetbrains, intelliJ: Working with Scala Implicit Conversions