SlideShare une entreprise Scribd logo
1  sur  74
Télécharger pour lire hors ligne
Implicits
Scalain
Derek Wyatt
Twitter: @derekwyatt
Email: derek@derekwyatt.org
Friday, 11 October, 13
Agenda
Lies and Damn Lies
Use Cases
Scope
ExampleCode!
Truths
Rules of Thumb
Friday, 11 October, 13
Implicits are NEW
Friday, 11 October, 13
Implicits are NEW
New things can be cool!
Friday, 11 October, 13
Implicits are NEW
New things can be cool!
New things can also be scary!
❉
Scala 2.10’s new set of
warnings don’t help the
situation.
❉
Friday, 11 October, 13
Implicits are NEW
New things can be cool!
New things can also be scary!
❉
Scala 2.10’s new set of
warnings don’t help the
situation.
❉
Especially when they’re complicated!
Friday, 11 October, 13
Implicits are NEW
New things can be cool!
Newness + Complexness = Fearsometimes
New things can also be scary!
❉
Scala 2.10’s new set of
warnings don’t help the
situation.
❉
Especially when they’re complicated!
Friday, 11 October, 13
Implicits are NEW
New things can be cool!
Newness + Complexness = Fearsometimes
Fear Avoidance
New things can also be scary!
❉
Scala 2.10’s new set of
warnings don’t help the
situation.
❉
Especially when they’re complicated!
Friday, 11 October, 13
Implicits are NEW
New things can be cool!
Newness + Complexness = Fearsometimes
Fear Avoidance
Avoidance :(
New things can also be scary!
❉
Scala 2.10’s new set of
warnings don’t help the
situation.
❉
Especially when they’re complicated!
Friday, 11 October, 13
Implicits
Friday, 11 October, 13
Implicits
Are Not
Friday, 11 October, 13
Implicits
Are Not
Global variables LIE!
Friday, 11 October, 13
Implicits
Are Not
Global variables
Dynamically Applied
LIE!
DAMN
LIE!
Friday, 11 October, 13
Implicits
Are Not
Global variables
Dynamically Applied
Dangerous (...much...)
LIE!
DAMN
LIE!
Fib
Friday, 11 October, 13
Implicits
Are Not
Global variables
Dynamically Applied
Dangerous (...much...)
Implicits are like scissors.
Use them. Don’t run with them.
LIE!
DAMN
LIE!
Fib
Friday, 11 October, 13
Use Cases
What are they used for?
Friday, 11 October, 13
Use Case: Type Classes
Friday, 11 October, 13
Use Case: Type Classes
val a = someInt()
val b = someOtherInt()
val lesser = if (lessThan(a, b)) a else b
Friday, 11 October, 13
Use Case: Type Classes
val a = someInt()
val b = someOtherInt()
val lesser = if (lessThan(a, b)) a else b
lessThan needsdefinition
Friday, 11 October, 13
Use Case: Type Classes
def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean =
o.lt(a, b)
val a = someInt()
val b = someOtherInt()
val lesser = if (lessThan(a, b)) a else b
lessThan needsdefinition
Friday, 11 October, 13
Use Case: Type Classes
def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean =
o.lt(a, b)
val a = someInt()
val b = someOtherInt()
val lesser = if (lessThan(a, b)) a else b
Ordering[Int]’s gottacome from somewhere
lessThan needsdefinition
Friday, 11 October, 13
Use Case: Type Classes
def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean =
o.lt(a, b)
implicit object intOrdering extends Ordering[Int] {
def compare(a: Int, b: Int): Int = a - b
}
val a = someInt()
val b = someOtherInt()
val lesser = if (lessThan(a, b)) a else b
Ordering[Int]’s gottacome from somewhere
lessThan needsdefinition
Friday, 11 October, 13
Use Case: Type Classes
def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean =
o.lt(a, b)
implicit object intOrdering extends Ordering[Int] {
def compare(a: Int, b: Int): Int = a - b
}
val a = someInt()
val b = someOtherInt()
val lesser = if (lessThan(a, b)) a else b
Ordering[Int]’s gottacome from somewhere
val a = someInt()
val b = someOtherInt()
val lesser = if (lessThan(a, b)(intOrdering)) a else b
lessThan needsdefinition
Friday, 11 October, 13
Use Case: Class Extension
Friday, 11 October, 13
Use Case: Class Extension
val hexVals = “implicit”.asHexSeq
// Vector(0x69, 0x6D, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74)
The “Pimp”
Friday, 11 October, 13
Use Case: Class Extension
val hexVals = “implicit”.asHexSeq
// Vector(0x69, 0x6D, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74)
The “Pimp”
implicit class HexableString(s: String) {
def asHexSeq: Seq[String] = s map { c =>
f”0x$c%02X”
}
}
The implicit class definition provides the
extension method
Friday, 11 October, 13
Use Case: Class Extension
val hexVals = “implicit”.asHexSeq
// Vector(0x69, 0x6D, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74)
The “Pimp”
implicit class HexableString(s: String) {
def asHexSeq: Seq[String] = s map { c =>
f”0x$c%02X”
}
}
The implicit class definition provides the
extension method
Bonus: If you extend implicit classes from AnyVal,
no temporary object construction will occur.
Friday, 11 October, 13
Use Case: Decluttering
val future1 = someCall(“a parameter”, 5.seconds)
val future2 = someCall(345, 5.seconds)
val future3 = someCall(235.9352, 5.seconds)
Friday, 11 October, 13
Use Case: Decluttering
val future1 = someCall(“a parameter”, 5.seconds)
val future2 = someCall(345, 5.seconds)
val future3 = someCall(235.9352, 5.seconds)
Blurgh
Friday, 11 October, 13
Use Case: Decluttering
val future1 = someCall(“a parameter”, 5.seconds)
val future2 = someCall(345, 5.seconds)
val future3 = someCall(235.9352, 5.seconds)
Blurgh
def someCall[A](a: A)(implicit timeout: Duration): Future[A] = ???
But, if we define someCall this way...
Friday, 11 October, 13
Use Case: Decluttering
val future1 = someCall(“a parameter”, 5.seconds)
val future2 = someCall(345, 5.seconds)
val future3 = someCall(235.9352, 5.seconds)
Blurgh
def someCall[A](a: A)(implicit timeout: Duration): Future[A] = ???
But, if we define someCall this way...
implicit val myTimeoutValue = 5.seconds
val future1 = someCall(“a parameter”)
val future2 = someCall(345)
val future3 = someCall(235.9352)
And define an
implicit value, we can
simplify the calls...
Friday, 11 October, 13
Use Case: Internal DSLs
Create your own sub-language with ease
Friday, 11 October, 13
Use Case: Internal DSLs
Create your own sub-language with ease
implicit class Recoverable[A](f: => A) {
def recover(g: Throwable => A): A =
try {
f
} catch {
case t: Throwable =>
g(t)
}
}
Friday, 11 October, 13
Use Case: Internal DSLs
Create your own sub-language with ease
implicit class Recoverable[A](f: => A) {
def recover(g: Throwable => A): A =
try {
f
} catch {
case t: Throwable =>
g(t)
}
}
def thisThrows(): Int = throw new Exception(“Argh!”)
val stable = thisThrows() recover { t =>
if (t.getMessage == “Argh!”)
10
else
5
} // stable == 10
Friday, 11 October, 13
Use Case: Other stuff...
Friday, 11 October, 13
Use Case: Other stuff...
Overriding defaults
def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A]
Friday, 11 October, 13
Use Case: Other stuff...
Overriding defaults
def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A]
Decoupled Dependency Injection
class Database(ec: ExecutionContext) {
def create(row: Row): Future[Result] = ???
def delete(id: RowId): Future[Result] = ???
// etc...
}
Friday, 11 October, 13
Use Case: Other stuff...
Overriding defaults
def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A]
Decoupled Dependency Injection
class Database(ec: ExecutionContext) {
def create(row: Row): Future[Result] = ???
def delete(id: RowId): Future[Result] = ???
// etc...
}
NO!
Friday, 11 October, 13
Use Case: Other stuff...
Overriding defaults
def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A]
Decoupled Dependency Injection
class Database {
def create(row: Row)(implicit ec: ExecutionContext): Future[Result]
def delete(id: RowId)(implicit ec: ExecutionContext): Future[Result]
// etc...
}
We can now vary the ExecutionContext at any
point by supplying the right implicit value
Friday, 11 October, 13
Implicit Scope
Rules!!!!
Friday, 11 October, 13
Implicit Scope
Rules!!!!
There are a Lot of Rules
Friday, 11 October, 13
Implicit Scope
Rules!!!!
There are a Lot of Rules
Read “Scala In Depth”*
*Josh Suereth
Friday, 11 October, 13
Implicit Scope
Rules!!!!
There are a Lot of Rules
Read “Scala In Depth”*
Implicits without the Import Tax*
*Josh Suereth
Friday, 11 October, 13
Implicit Scope
Rules!!!!
There are a Lot of Rules
Read “Scala In Depth”*
Implicits without the Import Tax*
*Josh Suereth
I don’t know them super well, and I haven’t cut my
arm off yet...
Friday, 11 October, 13
Creating a Protocol
Friday, 11 October, 13
Creating a Protocol
an Implicit
Friday, 11 October, 13
Creating a Protocol
an Implicit
We want:
actor emit Message(“Hello”)
Friday, 11 October, 13
Creating a Protocol
an Implicit
We want:
actor emit Message(“Hello”)
To Produce:
actor ! Envelope(ComponentType(“Client”),
ComponentType(“DBActor”),
ComponentId(“/user/supervisor/DB”),
WorkId(“764efa883dd7671c4a3bbd9e”),
MsgType(“org.my.Message”),
MsgNum(1),
Message(“Hello”))
Friday, 11 October, 13
An Actor Derivation
trait EnvelopingActor extends Actor
with EnvelopeImplicits
with ActorRefImplicits {
implicit val myCompType = ComponentType(getClass.getSimpleName)
implicit val myCompId = ComponentId(self.path)
private var currentWorkId = unknownWorkId
implicit def workId: WorkId = currentWorkId
private var currentMsgNum = MsgNum(-1)
implicit def msgNum: MsgNum = currentMsgNum
def derivedReceive: Receive
def derivedReceiveWrapper(wrapped: Receive): Receive = ???
final def receive = derivedReceiveWrapper(derivedReceive)
}
Friday, 11 October, 13
An Actor Derivation
trait EnvelopingActor extends Actor
with EnvelopeImplicits
with ActorRefImplicits {
implicit val myCompType = ComponentType(getClass.getSimpleName)
implicit val myCompId = ComponentId(self.path)
private var currentWorkId = unknownWorkId
implicit def workId: WorkId = currentWorkId
private var currentMsgNum = MsgNum(-1)
implicit def msgNum: MsgNum = currentMsgNum
def derivedReceive: Receive
def derivedReceiveWrapper(wrapped: Receive): Receive = ???
final def receive = derivedReceiveWrapper(derivedReceive)
}
Sets up the
implicits in a
high priority
scope
Friday, 11 October, 13
The Receive Wrapper
def derivedReceiveWrapper(wrapped: Receive): Receive = {
case Envelope(_, _, _, workId, _, messageNum, message) =>
currentWorkIdVar = workId
currentMessageNumVar = messageNum
wrapped(message)
case message =>
currentWorkIdVar = createWorkId()
currentMessageNumVar = MessageNum(-1)
wrapped(message)
}
Friday, 11 October, 13
The Receive Wrapper
def derivedReceiveWrapper(wrapped: Receive): Receive = {
case Envelope(_, _, _, workId, _, messageNum, message) =>
currentWorkIdVar = workId
currentMessageNumVar = messageNum
wrapped(message)
case message =>
currentWorkIdVar = createWorkId()
currentMessageNumVar = MessageNum(-1)
wrapped(message)
}
Ensures that the values that vary (workId and msgNum)
are updated in the implicit scope.
Friday, 11 October, 13
Envelope Implicits
trait EnvelopeImplicits {
import scala.language.implicitConversions
implicit def any2Envelope(a: Any)
(implicit fromCompType: ComponentType,
fromCompId: ComponentId,
workId: WorkId,
msgNum: MsgNum) =
Envelope(fromCompType, fromCompId, unknownCompId,
MsgType(a.getClass.getSimpleName),
workId, msgNum, a)
}
Allows us to substitute a concrete Envelope value where
an Any has been supplied. The implicit parameters make
this possible.
Friday, 11 October, 13
ActorRef Implicits
trait ActorRefImplicits {
implicit class PimpedActorRef(ref: ActorRef) {
def emit(envelope: Envelope)
(implicit sender: ActorRef = Actor.noSender): Unit = {
ref.tell(envelope.copy(
toComponentId = ComponentId(ref.path),
msgNum = envelope.msgNum.increment
), sender)
}
}
}
The emit method demands an Envelope. When you call
emit, that starts the implicit conversion! any2Envelope
creates it, and we update it here with better values.
Friday, 11 October, 13
Using the Protocol
class MyActor extends EnvelopingActor {
def derivedRecieve: Receive = {
case Message(str) =>
someOtherActor emit Message(s”I got: $str”)
}
}
Friday, 11 October, 13
Using the Protocol
class MyActor extends EnvelopingActor {
def derivedRecieve: Receive = {
case Message(str) =>
someOtherActor emit Message(s”I got: $str”)
}
}
Envelope(
ComponentType(“SomeActor”),
ComponentType(“MyActor”),
ComponentId(“/user/myactor”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(0),
Message(“SomeActor sent”))
Incoming
Friday, 11 October, 13
Using the Protocol
class MyActor extends EnvelopingActor {
def derivedRecieve: Receive = {
case Message(str) =>
someOtherActor emit Message(s”I got: $str”)
}
}
Envelope(
ComponentType(“SomeActor”),
ComponentType(“MyActor”),
ComponentId(“/user/myactor”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(0),
Message(“SomeActor sent”))
Incoming
Envelope(
ComponentType(“MyActor”),
ComponentType(“SomeOtherActor”),
ComponentId(“/user/someother”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(1),
Message(“I got: SomeActor sent”))
Outgoing
Friday, 11 October, 13
Using the Protocol
class MyActor extends EnvelopingActor {
def derivedRecieve: Receive = {
case Message(str) =>
someOtherActor emit Message(s”I got: $str”)
}
}
Envelope(
ComponentType(“SomeActor”),
ComponentType(“MyActor”),
ComponentId(“/user/myactor”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(0),
Message(“SomeActor sent”))
Incoming
Envelope(
ComponentType(“MyActor”),
ComponentType(“SomeOtherActor”),
ComponentId(“/user/someother”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(1),
Message(“I got: SomeActor sent”))
Outgoing
Chained
Friday, 11 October, 13
Using the Protocol
class MyActor extends EnvelopingActor {
def derivedRecieve: Receive = {
case Message(str) =>
someOtherActor emit Message(s”I got: $str”)
}
}
Envelope(
ComponentType(“SomeActor”),
ComponentType(“MyActor”),
ComponentId(“/user/myactor”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(0),
Message(“SomeActor sent”))
Incoming
Envelope(
ComponentType(“MyActor”),
ComponentType(“SomeOtherActor”),
ComponentId(“/user/someother”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(1),
Message(“I got: SomeActor sent”))
Outgoing
Maintained
Friday, 11 October, 13
Using the Protocol
class MyActor extends EnvelopingActor {
def derivedRecieve: Receive = {
case Message(str) =>
someOtherActor emit Message(s”I got: $str”)
}
}
Envelope(
ComponentType(“SomeActor”),
ComponentType(“MyActor”),
ComponentId(“/user/myactor”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(0),
Message(“SomeActor sent”))
Incoming
Envelope(
ComponentType(“MyActor”),
ComponentType(“SomeOtherActor”),
ComponentId(“/user/someother”),
WorkId(“ad7e877e41ff32a2”),
MsgType(“org.my.Message”),
MsgNum(1),
Message(“I got: SomeActor sent”))
Outgoing
Incremented
Friday, 11 October, 13
All the Implicits
Friday, 11 October, 13
All the Implicits
Pimp ActorRef with Emit
Friday, 11 October, 13
All the Implicits
Pimp ActorRef with Emit
Convert Any to envelope
Friday, 11 October, 13
All the Implicits
Pimp ActorRef with Emit
Convert Any to envelope
Simplify the API
Friday, 11 October, 13
All the Implicits
Pimp ActorRef with Emit
Convert Any to envelope
Simplify the API
actor emit Message(”Here’s a message”)
Just in case you forgot...
Friday, 11 October, 13
All the Implicits
Pimp ActorRef with Emit
Convert Any to envelope
Simplify the API
actor emit Message(”Here’s a message”)
Just in case you forgot...
SIMPLE
Friday, 11 October, 13
The Last Use Case
Friday, 11 October, 13
The Last Use Case
Implicits help you put complexity
where it belongs...
In your libraries!
&Away from your
Users!
Friday, 11 October, 13
Pitfalls
&Rules of Thumb
Friday, 11 October, 13
Pitfalls
&Rules of Thumb
Use very specific types
ComponentType(s: String) String()NOT
Friday, 11 October, 13
Pitfalls
&Rules of Thumb
Use very specific types
ComponentType(s: String) String()NOT
Enable by import, not compiler switches
Keeps libraries self-contained and avoids surprises
Friday, 11 October, 13
Pitfalls
&Rules of Thumb
Use very specific types
ComponentType(s: String) String()NOT
Enable by import, not compiler switches
Keeps libraries self-contained and avoids surprises
Push parameters to methods if you can
This keeps implicit resolution more flexible
Friday, 11 October, 13
Pitfalls
&Rules of Thumb
Use very specific types
ComponentType(s: String) String()NOT
Enable by import, not compiler switches
Keeps libraries self-contained and avoids surprises
Push parameters to methods if you can
This keeps implicit resolution more flexible
Use the right tool for the right job!!
Friday, 11 October, 13
Implicits
Scalain
Derek Wyatt
Twitter: @derekwyatt
Email: derek@derekwyatt.org
Thanks to @heathermiller for the presentation style
Source code is available at:
https://github.com/primal-github/implicit-messaging
Friday, 11 October, 13

Contenu connexe

En vedette

Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)mircodotta
 
Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design PatternsNLJUG
 
Demystifying Scala Type System
Demystifying Scala Type SystemDemystifying Scala Type System
Demystifying Scala Type SystemDavid Galichet
 
Advanced Non-Relational Schemas For Big Data
Advanced Non-Relational Schemas For Big DataAdvanced Non-Relational Schemas For Big Data
Advanced Non-Relational Schemas For Big DataVictor Smirnov
 
Baking Delicious Modularity in Scala
Baking Delicious Modularity in ScalaBaking Delicious Modularity in Scala
Baking Delicious Modularity in ScalaDerek Wyatt
 
Implicit Explicit Scala
Implicit Explicit ScalaImplicit Explicit Scala
Implicit Explicit ScalaKota Mizushima
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
Refactoring Design Patterns the Functional Way (in Scala)
Refactoring Design Patterns the Functional Way (in Scala)Refactoring Design Patterns the Functional Way (in Scala)
Refactoring Design Patterns the Functional Way (in Scala)Kfir Bloch
 
Android my Scala @ JFokus 2013
Android my Scala @ JFokus 2013Android my Scala @ JFokus 2013
Android my Scala @ JFokus 2013Konrad Malawski
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)mircodotta
 
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)Konrad Malawski
 
Type Parameterization
Type ParameterizationType Parameterization
Type ParameterizationKnoldus Inc.
 
Effective Programming In Scala
Effective Programming In ScalaEffective Programming In Scala
Effective Programming In ScalaHarsh Sharma
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsKonrad Malawski
 
Functional Programming and Concurrency Patterns in Scala
Functional Programming and Concurrency Patterns in ScalaFunctional Programming and Concurrency Patterns in Scala
Functional Programming and Concurrency Patterns in Scalakellogh
 
Effective Scala: Programming Patterns
Effective Scala: Programming PatternsEffective Scala: Programming Patterns
Effective Scala: Programming PatternsVasil Remeniuk
 
Simple Scala DSLs
Simple Scala DSLsSimple Scala DSLs
Simple Scala DSLslinxbetter
 

En vedette (20)

Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)
 
Scala’s implicits
Scala’s implicitsScala’s implicits
Scala’s implicits
 
Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design Patterns
 
Demystifying Scala Type System
Demystifying Scala Type SystemDemystifying Scala Type System
Demystifying Scala Type System
 
Advanced Non-Relational Schemas For Big Data
Advanced Non-Relational Schemas For Big DataAdvanced Non-Relational Schemas For Big Data
Advanced Non-Relational Schemas For Big Data
 
Baking Delicious Modularity in Scala
Baking Delicious Modularity in ScalaBaking Delicious Modularity in Scala
Baking Delicious Modularity in Scala
 
Implicit Explicit Scala
Implicit Explicit ScalaImplicit Explicit Scala
Implicit Explicit Scala
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Refactoring Design Patterns the Functional Way (in Scala)
Refactoring Design Patterns the Functional Way (in Scala)Refactoring Design Patterns the Functional Way (in Scala)
Refactoring Design Patterns the Functional Way (in Scala)
 
Android my Scala @ JFokus 2013
Android my Scala @ JFokus 2013Android my Scala @ JFokus 2013
Android my Scala @ JFokus 2013
 
Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)Effective Scala (JavaDay Riga 2013)
Effective Scala (JavaDay Riga 2013)
 
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
 
Effective Programming In Scala
Effective Programming In ScalaEffective Programming In Scala
Effective Programming In Scala
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
 
Functional Programming and Concurrency Patterns in Scala
Functional Programming and Concurrency Patterns in ScalaFunctional Programming and Concurrency Patterns in Scala
Functional Programming and Concurrency Patterns in Scala
 
Scala collections
Scala collectionsScala collections
Scala collections
 
Effective Scala: Programming Patterns
Effective Scala: Programming PatternsEffective Scala: Programming Patterns
Effective Scala: Programming Patterns
 
Simple Scala DSLs
Simple Scala DSLsSimple Scala DSLs
Simple Scala DSLs
 

Similaire à Scala Implicits - Not to be feared

Deconstructing Functional Programming
Deconstructing Functional ProgrammingDeconstructing Functional Programming
Deconstructing Functional ProgrammingC4Media
 
Rcos presentation
Rcos presentationRcos presentation
Rcos presentationmskmoorthy
 
Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Matt Aimonetti
 
Beginners guide-concurrency
Beginners guide-concurrencyBeginners guide-concurrency
Beginners guide-concurrencyMichael Barker
 
Intro to pattern matching in scala
Intro to pattern matching in scalaIntro to pattern matching in scala
Intro to pattern matching in scalaJan Krag
 
De vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored proceduresDe vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored proceduresNorman Clarke
 
JavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJan Kronquist
 
실시간 웹 협업도구 만들기 V0.3
실시간 웹 협업도구 만들기 V0.3실시간 웹 협업도구 만들기 V0.3
실시간 웹 협업도구 만들기 V0.3NAVER D2
 
Threequals - Case Equality in Ruby
Threequals - Case Equality in RubyThreequals - Case Equality in Ruby
Threequals - Case Equality in RubyLouis Scoras
 
First Ride on Rust
First Ride on RustFirst Ride on Rust
First Ride on RustDavid Evans
 
Celluloid - Beyond Sidekiq
Celluloid - Beyond SidekiqCelluloid - Beyond Sidekiq
Celluloid - Beyond SidekiqMarcelo Pinheiro
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 
Shoulders of giants: Languages Kotlin learned from
Shoulders of giants: Languages Kotlin learned fromShoulders of giants: Languages Kotlin learned from
Shoulders of giants: Languages Kotlin learned fromAndrey Breslav
 

Similaire à Scala Implicits - Not to be feared (20)

Deconstructing Functional Programming
Deconstructing Functional ProgrammingDeconstructing Functional Programming
Deconstructing Functional Programming
 
Clojure night
Clojure nightClojure night
Clojure night
 
Introduction to ansible
Introduction to ansibleIntroduction to ansible
Introduction to ansible
 
groovy & grails - lecture 3
groovy & grails - lecture 3groovy & grails - lecture 3
groovy & grails - lecture 3
 
Rcos presentation
Rcos presentationRcos presentation
Rcos presentation
 
Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010
 
Beginners guide-concurrency
Beginners guide-concurrencyBeginners guide-concurrency
Beginners guide-concurrency
 
Crystal Rocks
Crystal RocksCrystal Rocks
Crystal Rocks
 
Intro to pattern matching in scala
Intro to pattern matching in scalaIntro to pattern matching in scala
Intro to pattern matching in scala
 
De vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored proceduresDe vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored procedures
 
JavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java DevelopersJavaOne 2013 - Clojure for Java Developers
JavaOne 2013 - Clojure for Java Developers
 
실시간 웹 협업도구 만들기 V0.3
실시간 웹 협업도구 만들기 V0.3실시간 웹 협업도구 만들기 V0.3
실시간 웹 협업도구 만들기 V0.3
 
Immutability
ImmutabilityImmutability
Immutability
 
Threequals - Case Equality in Ruby
Threequals - Case Equality in RubyThreequals - Case Equality in Ruby
Threequals - Case Equality in Ruby
 
First Ride on Rust
First Ride on RustFirst Ride on Rust
First Ride on Rust
 
Celluloid - Beyond Sidekiq
Celluloid - Beyond SidekiqCelluloid - Beyond Sidekiq
Celluloid - Beyond Sidekiq
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
Scala in Practice
Scala in PracticeScala in Practice
Scala in Practice
 
JavaScript Neednt Hurt - JavaBin talk
JavaScript Neednt Hurt - JavaBin talkJavaScript Neednt Hurt - JavaBin talk
JavaScript Neednt Hurt - JavaBin talk
 
Shoulders of giants: Languages Kotlin learned from
Shoulders of giants: Languages Kotlin learned fromShoulders of giants: Languages Kotlin learned from
Shoulders of giants: Languages Kotlin learned from
 

Dernier

Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...Pooja Bhuva
 
Understanding Accommodations and Modifications
Understanding  Accommodations and ModificationsUnderstanding  Accommodations and Modifications
Understanding Accommodations and ModificationsMJDuyan
 
FSB Advising Checklist - Orientation 2024
FSB Advising Checklist - Orientation 2024FSB Advising Checklist - Orientation 2024
FSB Advising Checklist - Orientation 2024Elizabeth Walsh
 
Interdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptxInterdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptxPooja Bhuva
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxDenish Jangid
 
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptxOn_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptxPooja Bhuva
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.christianmathematics
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17Celine George
 
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptxMaritesTamaniVerdade
 
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxHMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxmarlenawright1
 
How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxCeline George
 
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfUGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfNirmal Dwivedi
 
How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17Celine George
 
REMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptxREMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptxDr. Ravikiran H M Gowda
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jisc
 
Salient Features of India constitution especially power and functions
Salient Features of India constitution especially power and functionsSalient Features of India constitution especially power and functions
Salient Features of India constitution especially power and functionsKarakKing
 
Graduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - EnglishGraduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - Englishneillewis46
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsMebane Rash
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxRamakrishna Reddy Bijjam
 
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...Pooja Bhuva
 

Dernier (20)

Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
Beyond_Borders_Understanding_Anime_and_Manga_Fandom_A_Comprehensive_Audience_...
 
Understanding Accommodations and Modifications
Understanding  Accommodations and ModificationsUnderstanding  Accommodations and Modifications
Understanding Accommodations and Modifications
 
FSB Advising Checklist - Orientation 2024
FSB Advising Checklist - Orientation 2024FSB Advising Checklist - Orientation 2024
FSB Advising Checklist - Orientation 2024
 
Interdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptxInterdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptx
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
 
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptxOn_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
 
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxHMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
 
How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptx
 
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfUGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
 
How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17How to Add New Custom Addons Path in Odoo 17
How to Add New Custom Addons Path in Odoo 17
 
REMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptxREMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptx
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)
 
Salient Features of India constitution especially power and functions
Salient Features of India constitution especially power and functionsSalient Features of India constitution especially power and functions
Salient Features of India constitution especially power and functions
 
Graduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - EnglishGraduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - English
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docx
 
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
 

Scala Implicits - Not to be feared

  • 1. Implicits Scalain Derek Wyatt Twitter: @derekwyatt Email: derek@derekwyatt.org Friday, 11 October, 13
  • 2. Agenda Lies and Damn Lies Use Cases Scope ExampleCode! Truths Rules of Thumb Friday, 11 October, 13
  • 3. Implicits are NEW Friday, 11 October, 13
  • 4. Implicits are NEW New things can be cool! Friday, 11 October, 13
  • 5. Implicits are NEW New things can be cool! New things can also be scary! ❉ Scala 2.10’s new set of warnings don’t help the situation. ❉ Friday, 11 October, 13
  • 6. Implicits are NEW New things can be cool! New things can also be scary! ❉ Scala 2.10’s new set of warnings don’t help the situation. ❉ Especially when they’re complicated! Friday, 11 October, 13
  • 7. Implicits are NEW New things can be cool! Newness + Complexness = Fearsometimes New things can also be scary! ❉ Scala 2.10’s new set of warnings don’t help the situation. ❉ Especially when they’re complicated! Friday, 11 October, 13
  • 8. Implicits are NEW New things can be cool! Newness + Complexness = Fearsometimes Fear Avoidance New things can also be scary! ❉ Scala 2.10’s new set of warnings don’t help the situation. ❉ Especially when they’re complicated! Friday, 11 October, 13
  • 9. Implicits are NEW New things can be cool! Newness + Complexness = Fearsometimes Fear Avoidance Avoidance :( New things can also be scary! ❉ Scala 2.10’s new set of warnings don’t help the situation. ❉ Especially when they’re complicated! Friday, 11 October, 13
  • 12. Implicits Are Not Global variables LIE! Friday, 11 October, 13
  • 13. Implicits Are Not Global variables Dynamically Applied LIE! DAMN LIE! Friday, 11 October, 13
  • 14. Implicits Are Not Global variables Dynamically Applied Dangerous (...much...) LIE! DAMN LIE! Fib Friday, 11 October, 13
  • 15. Implicits Are Not Global variables Dynamically Applied Dangerous (...much...) Implicits are like scissors. Use them. Don’t run with them. LIE! DAMN LIE! Fib Friday, 11 October, 13
  • 16. Use Cases What are they used for? Friday, 11 October, 13
  • 17. Use Case: Type Classes Friday, 11 October, 13
  • 18. Use Case: Type Classes val a = someInt() val b = someOtherInt() val lesser = if (lessThan(a, b)) a else b Friday, 11 October, 13
  • 19. Use Case: Type Classes val a = someInt() val b = someOtherInt() val lesser = if (lessThan(a, b)) a else b lessThan needsdefinition Friday, 11 October, 13
  • 20. Use Case: Type Classes def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean = o.lt(a, b) val a = someInt() val b = someOtherInt() val lesser = if (lessThan(a, b)) a else b lessThan needsdefinition Friday, 11 October, 13
  • 21. Use Case: Type Classes def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean = o.lt(a, b) val a = someInt() val b = someOtherInt() val lesser = if (lessThan(a, b)) a else b Ordering[Int]’s gottacome from somewhere lessThan needsdefinition Friday, 11 October, 13
  • 22. Use Case: Type Classes def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean = o.lt(a, b) implicit object intOrdering extends Ordering[Int] { def compare(a: Int, b: Int): Int = a - b } val a = someInt() val b = someOtherInt() val lesser = if (lessThan(a, b)) a else b Ordering[Int]’s gottacome from somewhere lessThan needsdefinition Friday, 11 October, 13
  • 23. Use Case: Type Classes def lessThan[A](a: A, b: A)(implicit o: Ordering[A]): Boolean = o.lt(a, b) implicit object intOrdering extends Ordering[Int] { def compare(a: Int, b: Int): Int = a - b } val a = someInt() val b = someOtherInt() val lesser = if (lessThan(a, b)) a else b Ordering[Int]’s gottacome from somewhere val a = someInt() val b = someOtherInt() val lesser = if (lessThan(a, b)(intOrdering)) a else b lessThan needsdefinition Friday, 11 October, 13
  • 24. Use Case: Class Extension Friday, 11 October, 13
  • 25. Use Case: Class Extension val hexVals = “implicit”.asHexSeq // Vector(0x69, 0x6D, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74) The “Pimp” Friday, 11 October, 13
  • 26. Use Case: Class Extension val hexVals = “implicit”.asHexSeq // Vector(0x69, 0x6D, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74) The “Pimp” implicit class HexableString(s: String) { def asHexSeq: Seq[String] = s map { c => f”0x$c%02X” } } The implicit class definition provides the extension method Friday, 11 October, 13
  • 27. Use Case: Class Extension val hexVals = “implicit”.asHexSeq // Vector(0x69, 0x6D, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74) The “Pimp” implicit class HexableString(s: String) { def asHexSeq: Seq[String] = s map { c => f”0x$c%02X” } } The implicit class definition provides the extension method Bonus: If you extend implicit classes from AnyVal, no temporary object construction will occur. Friday, 11 October, 13
  • 28. Use Case: Decluttering val future1 = someCall(“a parameter”, 5.seconds) val future2 = someCall(345, 5.seconds) val future3 = someCall(235.9352, 5.seconds) Friday, 11 October, 13
  • 29. Use Case: Decluttering val future1 = someCall(“a parameter”, 5.seconds) val future2 = someCall(345, 5.seconds) val future3 = someCall(235.9352, 5.seconds) Blurgh Friday, 11 October, 13
  • 30. Use Case: Decluttering val future1 = someCall(“a parameter”, 5.seconds) val future2 = someCall(345, 5.seconds) val future3 = someCall(235.9352, 5.seconds) Blurgh def someCall[A](a: A)(implicit timeout: Duration): Future[A] = ??? But, if we define someCall this way... Friday, 11 October, 13
  • 31. Use Case: Decluttering val future1 = someCall(“a parameter”, 5.seconds) val future2 = someCall(345, 5.seconds) val future3 = someCall(235.9352, 5.seconds) Blurgh def someCall[A](a: A)(implicit timeout: Duration): Future[A] = ??? But, if we define someCall this way... implicit val myTimeoutValue = 5.seconds val future1 = someCall(“a parameter”) val future2 = someCall(345) val future3 = someCall(235.9352) And define an implicit value, we can simplify the calls... Friday, 11 October, 13
  • 32. Use Case: Internal DSLs Create your own sub-language with ease Friday, 11 October, 13
  • 33. Use Case: Internal DSLs Create your own sub-language with ease implicit class Recoverable[A](f: => A) { def recover(g: Throwable => A): A = try { f } catch { case t: Throwable => g(t) } } Friday, 11 October, 13
  • 34. Use Case: Internal DSLs Create your own sub-language with ease implicit class Recoverable[A](f: => A) { def recover(g: Throwable => A): A = try { f } catch { case t: Throwable => g(t) } } def thisThrows(): Int = throw new Exception(“Argh!”) val stable = thisThrows() recover { t => if (t.getMessage == “Argh!”) 10 else 5 } // stable == 10 Friday, 11 October, 13
  • 35. Use Case: Other stuff... Friday, 11 October, 13
  • 36. Use Case: Other stuff... Overriding defaults def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A] Friday, 11 October, 13
  • 37. Use Case: Other stuff... Overriding defaults def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A] Decoupled Dependency Injection class Database(ec: ExecutionContext) { def create(row: Row): Future[Result] = ??? def delete(id: RowId): Future[Result] = ??? // etc... } Friday, 11 October, 13
  • 38. Use Case: Other stuff... Overriding defaults def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A] Decoupled Dependency Injection class Database(ec: ExecutionContext) { def create(row: Row): Future[Result] = ??? def delete(id: RowId): Future[Result] = ??? // etc... } NO! Friday, 11 October, 13
  • 39. Use Case: Other stuff... Overriding defaults def func[A](a: A)(implicit tout: Duration = 3.seconds): Future[A] Decoupled Dependency Injection class Database { def create(row: Row)(implicit ec: ExecutionContext): Future[Result] def delete(id: RowId)(implicit ec: ExecutionContext): Future[Result] // etc... } We can now vary the ExecutionContext at any point by supplying the right implicit value Friday, 11 October, 13
  • 41. Implicit Scope Rules!!!! There are a Lot of Rules Friday, 11 October, 13
  • 42. Implicit Scope Rules!!!! There are a Lot of Rules Read “Scala In Depth”* *Josh Suereth Friday, 11 October, 13
  • 43. Implicit Scope Rules!!!! There are a Lot of Rules Read “Scala In Depth”* Implicits without the Import Tax* *Josh Suereth Friday, 11 October, 13
  • 44. Implicit Scope Rules!!!! There are a Lot of Rules Read “Scala In Depth”* Implicits without the Import Tax* *Josh Suereth I don’t know them super well, and I haven’t cut my arm off yet... Friday, 11 October, 13
  • 45. Creating a Protocol Friday, 11 October, 13
  • 46. Creating a Protocol an Implicit Friday, 11 October, 13
  • 47. Creating a Protocol an Implicit We want: actor emit Message(“Hello”) Friday, 11 October, 13
  • 48. Creating a Protocol an Implicit We want: actor emit Message(“Hello”) To Produce: actor ! Envelope(ComponentType(“Client”), ComponentType(“DBActor”), ComponentId(“/user/supervisor/DB”), WorkId(“764efa883dd7671c4a3bbd9e”), MsgType(“org.my.Message”), MsgNum(1), Message(“Hello”)) Friday, 11 October, 13
  • 49. An Actor Derivation trait EnvelopingActor extends Actor with EnvelopeImplicits with ActorRefImplicits { implicit val myCompType = ComponentType(getClass.getSimpleName) implicit val myCompId = ComponentId(self.path) private var currentWorkId = unknownWorkId implicit def workId: WorkId = currentWorkId private var currentMsgNum = MsgNum(-1) implicit def msgNum: MsgNum = currentMsgNum def derivedReceive: Receive def derivedReceiveWrapper(wrapped: Receive): Receive = ??? final def receive = derivedReceiveWrapper(derivedReceive) } Friday, 11 October, 13
  • 50. An Actor Derivation trait EnvelopingActor extends Actor with EnvelopeImplicits with ActorRefImplicits { implicit val myCompType = ComponentType(getClass.getSimpleName) implicit val myCompId = ComponentId(self.path) private var currentWorkId = unknownWorkId implicit def workId: WorkId = currentWorkId private var currentMsgNum = MsgNum(-1) implicit def msgNum: MsgNum = currentMsgNum def derivedReceive: Receive def derivedReceiveWrapper(wrapped: Receive): Receive = ??? final def receive = derivedReceiveWrapper(derivedReceive) } Sets up the implicits in a high priority scope Friday, 11 October, 13
  • 51. The Receive Wrapper def derivedReceiveWrapper(wrapped: Receive): Receive = { case Envelope(_, _, _, workId, _, messageNum, message) => currentWorkIdVar = workId currentMessageNumVar = messageNum wrapped(message) case message => currentWorkIdVar = createWorkId() currentMessageNumVar = MessageNum(-1) wrapped(message) } Friday, 11 October, 13
  • 52. The Receive Wrapper def derivedReceiveWrapper(wrapped: Receive): Receive = { case Envelope(_, _, _, workId, _, messageNum, message) => currentWorkIdVar = workId currentMessageNumVar = messageNum wrapped(message) case message => currentWorkIdVar = createWorkId() currentMessageNumVar = MessageNum(-1) wrapped(message) } Ensures that the values that vary (workId and msgNum) are updated in the implicit scope. Friday, 11 October, 13
  • 53. Envelope Implicits trait EnvelopeImplicits { import scala.language.implicitConversions implicit def any2Envelope(a: Any) (implicit fromCompType: ComponentType, fromCompId: ComponentId, workId: WorkId, msgNum: MsgNum) = Envelope(fromCompType, fromCompId, unknownCompId, MsgType(a.getClass.getSimpleName), workId, msgNum, a) } Allows us to substitute a concrete Envelope value where an Any has been supplied. The implicit parameters make this possible. Friday, 11 October, 13
  • 54. ActorRef Implicits trait ActorRefImplicits { implicit class PimpedActorRef(ref: ActorRef) { def emit(envelope: Envelope) (implicit sender: ActorRef = Actor.noSender): Unit = { ref.tell(envelope.copy( toComponentId = ComponentId(ref.path), msgNum = envelope.msgNum.increment ), sender) } } } The emit method demands an Envelope. When you call emit, that starts the implicit conversion! any2Envelope creates it, and we update it here with better values. Friday, 11 October, 13
  • 55. Using the Protocol class MyActor extends EnvelopingActor { def derivedRecieve: Receive = { case Message(str) => someOtherActor emit Message(s”I got: $str”) } } Friday, 11 October, 13
  • 56. Using the Protocol class MyActor extends EnvelopingActor { def derivedRecieve: Receive = { case Message(str) => someOtherActor emit Message(s”I got: $str”) } } Envelope( ComponentType(“SomeActor”), ComponentType(“MyActor”), ComponentId(“/user/myactor”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(0), Message(“SomeActor sent”)) Incoming Friday, 11 October, 13
  • 57. Using the Protocol class MyActor extends EnvelopingActor { def derivedRecieve: Receive = { case Message(str) => someOtherActor emit Message(s”I got: $str”) } } Envelope( ComponentType(“SomeActor”), ComponentType(“MyActor”), ComponentId(“/user/myactor”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(0), Message(“SomeActor sent”)) Incoming Envelope( ComponentType(“MyActor”), ComponentType(“SomeOtherActor”), ComponentId(“/user/someother”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(1), Message(“I got: SomeActor sent”)) Outgoing Friday, 11 October, 13
  • 58. Using the Protocol class MyActor extends EnvelopingActor { def derivedRecieve: Receive = { case Message(str) => someOtherActor emit Message(s”I got: $str”) } } Envelope( ComponentType(“SomeActor”), ComponentType(“MyActor”), ComponentId(“/user/myactor”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(0), Message(“SomeActor sent”)) Incoming Envelope( ComponentType(“MyActor”), ComponentType(“SomeOtherActor”), ComponentId(“/user/someother”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(1), Message(“I got: SomeActor sent”)) Outgoing Chained Friday, 11 October, 13
  • 59. Using the Protocol class MyActor extends EnvelopingActor { def derivedRecieve: Receive = { case Message(str) => someOtherActor emit Message(s”I got: $str”) } } Envelope( ComponentType(“SomeActor”), ComponentType(“MyActor”), ComponentId(“/user/myactor”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(0), Message(“SomeActor sent”)) Incoming Envelope( ComponentType(“MyActor”), ComponentType(“SomeOtherActor”), ComponentId(“/user/someother”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(1), Message(“I got: SomeActor sent”)) Outgoing Maintained Friday, 11 October, 13
  • 60. Using the Protocol class MyActor extends EnvelopingActor { def derivedRecieve: Receive = { case Message(str) => someOtherActor emit Message(s”I got: $str”) } } Envelope( ComponentType(“SomeActor”), ComponentType(“MyActor”), ComponentId(“/user/myactor”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(0), Message(“SomeActor sent”)) Incoming Envelope( ComponentType(“MyActor”), ComponentType(“SomeOtherActor”), ComponentId(“/user/someother”), WorkId(“ad7e877e41ff32a2”), MsgType(“org.my.Message”), MsgNum(1), Message(“I got: SomeActor sent”)) Outgoing Incremented Friday, 11 October, 13
  • 61. All the Implicits Friday, 11 October, 13
  • 62. All the Implicits Pimp ActorRef with Emit Friday, 11 October, 13
  • 63. All the Implicits Pimp ActorRef with Emit Convert Any to envelope Friday, 11 October, 13
  • 64. All the Implicits Pimp ActorRef with Emit Convert Any to envelope Simplify the API Friday, 11 October, 13
  • 65. All the Implicits Pimp ActorRef with Emit Convert Any to envelope Simplify the API actor emit Message(”Here’s a message”) Just in case you forgot... Friday, 11 October, 13
  • 66. All the Implicits Pimp ActorRef with Emit Convert Any to envelope Simplify the API actor emit Message(”Here’s a message”) Just in case you forgot... SIMPLE Friday, 11 October, 13
  • 67. The Last Use Case Friday, 11 October, 13
  • 68. The Last Use Case Implicits help you put complexity where it belongs... In your libraries! &Away from your Users! Friday, 11 October, 13
  • 70. Pitfalls &Rules of Thumb Use very specific types ComponentType(s: String) String()NOT Friday, 11 October, 13
  • 71. Pitfalls &Rules of Thumb Use very specific types ComponentType(s: String) String()NOT Enable by import, not compiler switches Keeps libraries self-contained and avoids surprises Friday, 11 October, 13
  • 72. Pitfalls &Rules of Thumb Use very specific types ComponentType(s: String) String()NOT Enable by import, not compiler switches Keeps libraries self-contained and avoids surprises Push parameters to methods if you can This keeps implicit resolution more flexible Friday, 11 October, 13
  • 73. Pitfalls &Rules of Thumb Use very specific types ComponentType(s: String) String()NOT Enable by import, not compiler switches Keeps libraries self-contained and avoids surprises Push parameters to methods if you can This keeps implicit resolution more flexible Use the right tool for the right job!! Friday, 11 October, 13
  • 74. Implicits Scalain Derek Wyatt Twitter: @derekwyatt Email: derek@derekwyatt.org Thanks to @heathermiller for the presentation style Source code is available at: https://github.com/primal-github/implicit-messaging Friday, 11 October, 13