Permalink
Browse files

11th hour update

  • Loading branch information...
gangstead committed Jan 8, 2015
1 parent 45947f9 commit 514c218168e0bba51f8d99f7bb64e2d6d83d1423
View
@@ -30,7 +30,7 @@ code {
background: #000;
border-radius: 5px;
}
-.logo img{
+.round img{
-moz-border-radius: 10px;
-web-border-radius: 10px;
border-radius: 10px;
View
@@ -4,7 +4,7 @@ class: center, middle
### Steven Gangstead
### code and slides at https://github.com/gangstead/implicitly-yours
@Gangstead
-.footnote[.logo[![:scale 20%](slides/credera.jpg)]]
+.footnote[.round[![:scale 20%](slides/credera.jpg)]]
---
# Overview
@@ -13,6 +13,7 @@ Implicit…
- Parameters
- Conversion
- Classes
+- Implicitly
- Context Bounds
- Where do they come from?
@@ -30,7 +31,9 @@ Implicit…
```scala
implicit val n: Int = 5
+
def add(x: Int)(implicit y: Int) = x + y
+
add(5) // takes n from the current scope
add(5) (1) //can always call explicitly
```
@@ -52,8 +55,8 @@ println( add(5) )
.smaller[
```
[error] /implicitly-yours/src/main/scala/gangstead/ImplicitParams.scala:11: ambiguous implicit values:
-[error] both value n in class HiParam of type => Int
-[error] and value no in class HiParam of type => Int
+[error] both value n in class ImplicitParams of type => Int
+[error] and value no in class ImplicitParams of type => Int
[error] match expected type Int
[error] println( add(5) )
[error] ^
@@ -105,7 +108,7 @@ String does not support the method map, but StringOps does, and there’s an imp
```scala
case class Enthusiast(level: Int)
-class HiConvert {
+class ImplicitConversionUseCase {
implicit def toEnthusiast(i : Int) = Enthusiast(i)
def takesAnEnthusiast(e : Enthusiast) = s"Received $e"
@@ -136,15 +139,6 @@ implicit def toVeryEnthusiast(i : Int) = Enthusiast(i*10)
```
]
----
-# Practical example:
-String does not support the method map, but StringOps does, and there’s an implicit conversion from String to StringOps available (see implicit def augmentString onPredef).
-
-We can make our own ScalaEnthusiastsStringOps...
-
----
-# Example: ScalaEnthusiastsStringOps
-
---
# Why Implicit Conversions?
@@ -187,6 +181,15 @@ val u = t.enhancement
[Example](https://github.com/gangstead/implicitly-yours/blob/gh-pages/src/main/scala/gangstead/ImplicitClass.scala) in code.
Some [Important Gotchas](http://docs.scala-lang.org/overviews/core/implicit-classes.html#restrictions)
+---
+# Practical example:
+- In the Coursera Scala course [Principles of Reactive Programming](https://www.coursera.org/course/reactive), week 3.
+- We learn how to add useful extensions to Futures via an implicit class FutureCompanionOps to add to the core Futures library
+- Example function: future that completes with the value of the first completed future from a list of futures. Future.
+
+
+.footnote[Code not included in case they run the course again]
+
---
# Bedazzling limitations
@@ -195,12 +198,45 @@ Some [Important Gotchas](http://docs.scala-lang.org/overviews/core/implicit-clas
- Requires explicit import that user might forget*
.footnote[[*source](http://jsuereth.com/scala/2011/02/18/2011-implicits-without-tax.html)]
+
+---
+# Implicitly
+- Want to grab an implicit value that's in scope?
+- `implicitly[T]` says "give me the implicit T that is in scope"
+
+```scala
+def add(x: Int)(implicit y: Int) = x + y
+```
+```scala
+def add(x: Int) = {
+ x + implicitly[Int]
+}
+```
+Useful when someone else is going to be putting an implicit in scope.
+.footnote[[More reading](http://www.drmaciver.com/2008/03/an-introduction-to-implicit-arguments/)]
---
# Implicit Context Bounds
+*type class pattern* * "For some type A, there is an implicit value of type B[A] available". B is a parameterized [type class](http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html)
+```scala
+def g[A : B](a: A) = h(a)
+//desugars into
+def g[A](a: A)(implicit ev: B[A]) = h(a)
+```
-Start here: http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html#context-bounds
-I think this is about `implicitly` views, might need to rename this section.
+Example from Scala Numeric:
+```scala
+def f[A : Ordering](a: A, b: A) =
+ if (implicitly[Ordering[A]].lt(a, b)) a else b
+```
+
+.footnote[[Source](http://docs.scala-lang.org/tutorials/FAQ/context-and-view-bounds.html#what-are-context-bounds-used-for) *as in Haskell's type classes]
+---
+# Context Bounds further reading
+## Because I'm not smart enough to explain it myself
+- http://docs.scala-lang.org/tutorials/FAQ/context-and-view-bounds.html
+- http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html#context-bounds
+- http://stackoverflow.com/a/2983376/1637003
---
@@ -248,7 +284,7 @@ I think this is about `implicitly` views, might need to rename this section.
---
# Removing those warnings
- Two Options:
-1. In build.sbt enable project wide
+1. Project wide, in build.sbt
```
scalacOptions += "-language:implicitConversions"
```
@@ -18,13 +18,13 @@ object Helper2 {
}
}
-class ImplicitClassUseCase {
+object ImplicitClassUseCase extends App{
import Helper1._
import Helper2._
val scalaHuman = Admirer(11)
- println("Esteem: " + scalaHuman.esteem)
+ println("Esteem: " + scalaHuman.esteem)
println("Boosted: " + scalaHuman.boosted)
- println("Bested:" + scalaHuman.bested)
+ println("Bested: " + scalaHuman.bested)
}
@@ -4,7 +4,7 @@ package gangstead
case class Enthusiast(level: Int)
-class ImplicitConversionUseCase {
+object ImplicitConversionUseCase extends App {
implicit def toEnthusiast(i : Int) = Enthusiast(i)
//implicit def toVeryEnthusiast(i : Int) = Enthusiast(i*10) //this would be ambiguous
@@ -19,4 +19,7 @@ class ImplicitConversionUseCase {
println(takesAnEnthusiast(scalaHuman))
println(takesAnEnthusiast(randomHuman))
+
+ implicit def enthusiasToInt(e : Enthusiast) = e.level
+ println( "Combined: " + (1 + scalaHuman))
}
@@ -1,6 +1,6 @@
package gangstead
-class HiParam {
+object ImplicitParams {
implicit val n: Int = 5
//implicit val no: Int = -1 //can only have one implicit type match!
@@ -0,0 +1,51 @@
+package gangstead
+
+object ImplicitlyImplicit extends App {
+
+ def basic() = {
+ implicit val n: Int = 5
+
+ //def add(x: Int)(implicit y: Int) = x + y
+ def add(x: Int) = {
+ x + implicitly[Int]
+ }
+
+ println(add(5))
+ }
+
+ def subtypes() = {
+ //Most specific subtype whens
+ def printList(implicit l: List[Any]) = l foreach println
+
+ implicit val emptyList: List[Any] = Nil
+ implicit val intyList: List[Int] = List(1, 2, 3)
+
+ printList //1 2 3
+ }
+
+ def typeParams() = {
+ //type parameters implicitly
+ implicit def emptyList[T]: List[T] = Nil
+
+ val x = implicitly[List[Int]] // x's type is List[Int], value is List()
+ println(x)
+ }
+
+ /**
+ * source: http://www.drmaciver.com/2008/03/an-introduction-to-implicit-arguments/
+ */
+ def doubleImplicit() = {
+ case class Foo[T](t: T)
+
+ implicit val hello = "Hello"
+ implicit def foo[T](implicit t: T) = Foo[T](t)
+
+ println(implicitly[Foo[String]]) //From REPL: res1: Foo[String] = Foo(Hello)
+ }
+
+ basic()
+ subtypes()
+ typeParams()
+ doubleImplicit()
+
+}
@@ -5,7 +5,7 @@ import akka.actor.Actor
class actorA extends Actor {
def receive = {
case Request =>
- Thread.sleep(1000)
+ Thread.sleep(300)
println("actorA responds")
sender ! 1
}
@@ -14,7 +14,7 @@ class actorA extends Actor {
class actorB extends Actor {
def receive = {
case Request =>
- Thread.sleep(2000)
+ Thread.sleep(600)
println("actorB responds")
sender ! "b"
}
@@ -23,7 +23,7 @@ class actorB extends Actor {
class actorC extends Actor {
def receive = {
case Request =>
- Thread.sleep(3000)
+ Thread.sleep(900)
println("actorC responds")
sender ! 3.0
}
@@ -32,14 +32,14 @@ object main extends App {
//other valid forms
//actorRef does not contain an ask method: https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/actor/ActorRef.scala
- ask(actorC,Request)(timeout)
- ask(actorC,Request)
- actorC.ask(Request) //actorRef is Bedazzled with ask pattern
+ ask(actorA,Request)(timeout)
+ ask(actorA,Request)
+ actorA.ask(Request) //actorRef is Bedazzled with ask pattern
//https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/pattern/AskSupport.scala#L46
- actorC.ask(Request)(timeout)
- actorC.ask(Request)(5 seconds) //implicit conversion to Timeout
+ actorA.ask(Request)(timeout)
+ actorA.ask(Request)(5 seconds) //implicit conversion to Timeout
//https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/util/Timeout.scala#L37
- actorC ask Request
+ actorA ask Request
f pipeTo actorD // .. or ..

0 comments on commit 514c218

Please sign in to comment.