44
Scala implicits Jordi Pradel - @agile_jordi @scalabcn Follow me: https://github.com/agile-jordi/scalabcn-implicits-2015

Introduction to Scala Implicits, Pimp my library and Typeclasses

Embed Size (px)

Citation preview

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

let’s code!(Steps 1 - 3)

ImplicitParamers101.scala

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 scope

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?

rules of static overloading resolution

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

Let’s code!(Steps 4 - 7)

ImplicitConversions101.scala

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.

ouch! the good parts…

Benjamin Franklin

“Lost time is never found again”

A raging ScalaBcn member

“Lost time is never found again, motherfucker!”

Scala implicit idioms

• Pimp my library

• Context bounds (& typeclasses)

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

Let’s code!(Steps 8 - 11)

PimpMyLibrary101.scala

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

Let’s code!(Steps 12 - 17)

TypeClasses101.scala

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

View bounds

def f[A <% B](a: A)

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

type level programming ahead

Let’s code!(Steps 18-19)

ImplicitTypeBounds101.scala

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

Jordi Pradel@agile_jordi

[email protected]

Thanks!!