Skip to content

Commit

Permalink
additional code created during the meetup
Browse files Browse the repository at this point in the history
  • Loading branch information
gangstead committed Jan 9, 2015
1 parent 514c218 commit b567fd7
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 20 deletions.
72 changes: 55 additions & 17 deletions README.md
Expand Up @@ -3,8 +3,60 @@ implicitly-yours

Sample Code for Dallas Scala Enthusiasts presentation

## Building IDE files
### Eclipse
## The Slides
### TL;DR [Slides here](https://gangstead.github.io/implicitly-yours)

Since the default branch is gh-pages, go to http://gangstead.github.io/implicitly-yours to view the slides.

To view the slides locally start a [static http server](https://gist.github.com/willurd/5720255) from that directory. My preferred way:

```
# one time, to install the dependency
> npm install -g http-server
# start the server in the base directory. -o flag opens browser
> http-server -o
```

## The Code
### TL;DR `sbt run`
### Running

The sample code has multiple main classes. From the command line type `sbt run` and you will get prompted to choose one:
```
gangstead$ sbt run
[info] Loading global plugins from /Users/gangstead/.sbt/0.13/plugins
[info] Loading project definition from /Users/gangstead/scala/implicitly-yours/project
[info] Set current project to implicitly-yours (in build file:/Users/gangstead/scala/implicitly-yours/)
[info] Compiling 3 Scala sources to /Users/gangstead/scala/implicitly-yours/target/scala-2.11/classes...
[warn] Multiple main classes detected. Run 'show discoveredMainClasses' to see the list
Multiple main classes detected, select one to run:
[1] gangstead.akka.main
[2] gangstead.ImplicitlyImplicit
[3] gangstead.ImplicitClassUseCase
[4] gangstead.ImplicitParams
[5] gangstead.ImplicitConversionUseCase
Enter number: 2
```
If you want to make changes to the code and see compiler output in real time then use the command `sbt ~compile`

```
gangstead$ sbt ~compile
[info] Loading global plugins from /Users/gangstead/.sbt/0.13/plugins
[info] Loading project definition from /Users/gangstead/scala/implicitly-yours/project
[info] Set current project to implicitly-yours (in build file:/Users/gangstead/scala/implicitly-yours/)
[info] Compiling 3 Scala sources to /Users/gangstead/scala/implicitly-yours/target/scala-2.11/classes...
[success] Total time: 7 s, completed Jan 9, 2015 12:32:05 PM
1. Waiting for source changes... (press enter to interrupt)
_
```
Now whenever you save a file sbt will recompile and display any warnings or errors.

### Building IDE files
#### Eclipse
This project includes the plugin to generate Eclipse project files. From the console:
```
> sbt eclipse
Expand All @@ -19,19 +71,5 @@ Optionally if you want to include the sources of the dependencies:
```
This will take longer in big projects, but this project is small. I don't know why you can't just do `sbt eclipse with-source=true`. That's what the plugin docs say, but it won't work for me.

### IDEA
#### IDEA
Intellij IDEA can import SBT projects natively.


## The Slides
Since the default branch is gh-pages, go to http://gangstead.github.io/implicitly-yours to view the slides.

To view the slides locally start a [static http server](https://gist.github.com/willurd/5720255) from that directory. My preferred way:

```
# one time, to install the dependency
> npm install -g http-server
# start the server in the base directory. -o flag opens browser
> http-server -o
```
5 changes: 3 additions & 2 deletions slides/slides.md
Expand Up @@ -2,7 +2,8 @@ class: center, middle

# implicitly yours
### Steven Gangstead
### code and slides at https://github.com/gangstead/implicitly-yours
### slides https://gangstead.github.io/implicitly-yours
### code https://github.com/gangstead/implicitly-yours
@Gangstead
.footnote[.round[![:scale 20%](slides/credera.jpg)]]
---
Expand Down Expand Up @@ -145,7 +146,7 @@ implicit def toVeryEnthusiast(i : Int) = Enthusiast(i*10)

- Extend classes that you can't otherwise modify
- Reduce boilerplate code by having a bunch of conversions to one base class (aka [Magnet Pattern](http://spray.io/blog/2012-12-13-the-magnet-pattern/))
- `enhancement(thing)` becomes `thing.enhancement` (just preference?)
- `enhancement(thing)` becomes `thing.enhancement` (better encapsulation)
---
# Implicit Classes
~~Pimping~~ Bedazzling originally of the form
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/gangstead/ImplicitParams.scala
Expand Up @@ -6,7 +6,7 @@ object ImplicitParams {
//implicit val no: Int = -1 //can only have one implicit type match!

def add(x: Int)(implicit y: Int) = x + y

//def add2(x: Int, implicit y: Int) = x + y //can't have just one param implicit
def main(args: Array[String]) {
println( add(5) ) // takes n from the current scope
println( add(5) (1) ) //can always call explicitly
Expand Down
42 changes: 42 additions & 0 deletions src/main/scala/gangstead/ImplicitlyImplicit.scala
Expand Up @@ -3,6 +3,7 @@ package gangstead
object ImplicitlyImplicit extends App {

def basic() = {
println("\nbasic")
implicit val n: Int = 5

//def add(x: Int)(implicit y: Int) = x + y
Expand All @@ -13,17 +14,55 @@ object ImplicitlyImplicit extends App {
println(add(5))
}

/**
* From discussion in the meetup, there is a slight difference between
* using the implicit param and implicitly in the order of execution.
* The implicit parameter is evaluated when the method is called so
* if the implicit is a lazy val or a costly def the delay is incurred
* before the implicit is actually used.
*/
def cornerCase() = {
println("\ncorner case")

implicit def n = { println("a") ; 10}

def add(x: Int) = {
println("b")
x + implicitly[Int]
}

def add2(x: Int)(implicit y: Int) = {
println("b")
x + y
}

println(add(5)) //b a 15
println(add2(5))// a b 15
}

/**
* If your function takes an implicit type the compiler can and will use a subtype
* It is legal to have a type and subtype in scope, the compiler will use the subtype.
* In this case we need a List[Any] and have List[Any], List[AnyVal] and List[Int] available.
* The List[Int] is a subtype of the other two. If a List[Double] were available we'd get a compiler
* error because the compiler can't choose between the two.
*/
def subtypes() = {
println("\nsubtypes")
//Most specific subtype whens
def printList(implicit l: List[Any]) = l foreach println

implicit val emptyList: List[Any] = Nil
implicit val anyValList: List[AnyVal] = List(1,2.0)
implicit val intyList: List[Int] = List(1, 2, 3)

//implicit val doublyList: List[Double] = List(1.0,2.0,3.1) //ERROR. Double not a sub or parent type of Int.

printList //1 2 3
}

def typeParams() = {
println("\ntypeparams")
//type parameters implicitly
implicit def emptyList[T]: List[T] = Nil

Expand All @@ -33,8 +72,10 @@ object ImplicitlyImplicit extends App {

/**
* source: http://www.drmaciver.com/2008/03/an-introduction-to-implicit-arguments/
* Advanced: Implicit def with an implicit parameter.
*/
def doubleImplicit() = {
println("\ndouble implicit")
case class Foo[T](t: T)

implicit val hello = "Hello"
Expand All @@ -44,6 +85,7 @@ object ImplicitlyImplicit extends App {
}

basic()
cornerCase()
subtypes()
typeParams()
doubleImplicit()
Expand Down

0 comments on commit b567fd7

Please sign in to comment.