SlideShare ist ein Scribd-Unternehmen logo
1 von 74
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Andere mochten auch

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
 

Andere mochten auch (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
 

Ähnlich wie Implicits in Scala: Understanding implicit scopes and use cases

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
 

Ähnlich wie Implicits in Scala: Understanding implicit scopes and use cases (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
 

Kürzlich hochgeladen

ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4MiaBumagat1
 
Global Lehigh Strategic Initiatives (without descriptions)
Global Lehigh Strategic Initiatives (without descriptions)Global Lehigh Strategic Initiatives (without descriptions)
Global Lehigh Strategic Initiatives (without descriptions)cama23
 
4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptxmary850239
 
Culture Uniformity or Diversity IN SOCIOLOGY.pptx
Culture Uniformity or Diversity IN SOCIOLOGY.pptxCulture Uniformity or Diversity IN SOCIOLOGY.pptx
Culture Uniformity or Diversity IN SOCIOLOGY.pptxPoojaSen20
 
GRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTS
GRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTSGRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTS
GRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTSJoshuaGantuangco2
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parentsnavabharathschool99
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatYousafMalik24
 
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxMULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxAnupkumar Sharma
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPCeline George
 
AUDIENCE THEORY -CULTIVATION THEORY - GERBNER.pptx
AUDIENCE THEORY -CULTIVATION THEORY -  GERBNER.pptxAUDIENCE THEORY -CULTIVATION THEORY -  GERBNER.pptx
AUDIENCE THEORY -CULTIVATION THEORY - GERBNER.pptxiammrhaywood
 
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...Nguyen Thanh Tu Collection
 
ENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomnelietumpap1
 
Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)Mark Reed
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptxmary850239
 
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfTechSoup
 
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfAMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfphamnguyenenglishnb
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxHumphrey A Beña
 
Barangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptxBarangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptxCarlos105
 
Transaction Management in Database Management System
Transaction Management in Database Management SystemTransaction Management in Database Management System
Transaction Management in Database Management SystemChristalin Nelson
 

Kürzlich hochgeladen (20)

YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptxYOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
 
ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4
 
Global Lehigh Strategic Initiatives (without descriptions)
Global Lehigh Strategic Initiatives (without descriptions)Global Lehigh Strategic Initiatives (without descriptions)
Global Lehigh Strategic Initiatives (without descriptions)
 
4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx
 
Culture Uniformity or Diversity IN SOCIOLOGY.pptx
Culture Uniformity or Diversity IN SOCIOLOGY.pptxCulture Uniformity or Diversity IN SOCIOLOGY.pptx
Culture Uniformity or Diversity IN SOCIOLOGY.pptx
 
GRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTS
GRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTSGRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTS
GRADE 4 - SUMMATIVE TEST QUARTER 4 ALL SUBJECTS
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parents
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice great
 
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxMULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERP
 
AUDIENCE THEORY -CULTIVATION THEORY - GERBNER.pptx
AUDIENCE THEORY -CULTIVATION THEORY -  GERBNER.pptxAUDIENCE THEORY -CULTIVATION THEORY -  GERBNER.pptx
AUDIENCE THEORY -CULTIVATION THEORY - GERBNER.pptx
 
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
HỌC TỐT TIẾNG ANH 11 THEO CHƯƠNG TRÌNH GLOBAL SUCCESS ĐÁP ÁN CHI TIẾT - CẢ NĂ...
 
ENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choom
 
Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx
 
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
 
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfAMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
 
Barangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptxBarangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptx
 
Transaction Management in Database Management System
Transaction Management in Database Management SystemTransaction Management in Database Management System
Transaction Management in Database Management System
 

Implicits in Scala: Understanding implicit scopes and use cases

  • 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