Slide 1

Slide 1 text

From A to L Designing Scala Libraries Scala features, patterns, idioms, tips and tricks I picked up while reading other people’s library source code and writing my own SCALAPENOS

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Where do I get these skillz? Writing lots of application code Making lots of mistakes Reading LOTS of Scala library source code Mostly: Spray source code

Slide 4

Slide 4 text

My Library:

Slide 5

Slide 5 text

Why? Most of the existing Scala Riak client libraries were dead projects None of them were compatible with Scala 2.10 or Akka 2.1.x None of them were non-blocking The official Java client library has a very (ugly) Java-ish API The official Java client library is blocking It was the Christmas holidays and I needed a new hobby project

Slide 6

Slide 6 text

“A scalable, highly-available, fault-tolerant, Dynamo-style distributed open-source key/value store” Riak in One Slide:

Slide 7

Slide 7 text

Design Goals: It should be completely non-blocking It should integrate well with Akka It should be simple and easy to use It should be easy to extend The API should be idiomatic Scala

Slide 8

Slide 8 text

Agenda: Type Aliasing Type Classes Context Bounds Manipulating Implicit Resolution Abstract Types vs Type Parameters

Slide 9

Slide 9 text

Type Aliasing

Slide 10

Slide 10 text

Using types external to your library will force you and your users to import those types whenever they need to be instantiated... The Problem:

Slide 11

Slide 11 text

The Solution: Now you and your users only need one import to rule them all!

Slide 12

Slide 12 text

Everyone else is doing it:

Slide 13

Slide 13 text

Type Classes

Slide 14

Slide 14 text

Wikipedia Definition: "... a type system construct that supports ad-hoc polymorphism. This is achieved by adding constraints to type variables in parametrically polymorphic types" Ehm...?

Slide 15

Slide 15 text

Other Definition: "A type of Adapter that uses Scala’s implicits to add some extra capabilities to an existing type without direct coupling" Ehm...?

Slide 16

Slide 16 text

The Problem: It would be nice if there were an easy way to constrain T to something that can be serialized and indexed without forcing users to extend their domain classes from my traits How do I turn a T into a RiakValue?

Slide 17

Slide 17 text

The Solution: Add a Serializer[T] implicit parameter Making the parameter implicit is the big trick that turns RiakSerializer into a type class

Slide 18

Slide 18 text

Not a very pretty solution... There must be a prettier way to specify this?!

Slide 19

Slide 19 text

Context Bounds: Can also be written using a Context Bound: And if you do need a reference to the unnamed implicit parameter, you can get one using implicitly(...)

Slide 20

Slide 20 text

A Nicer Solution: Use implicitly(...) to get a reference to any unnamed implicit value or parameter

Slide 21

Slide 21 text

Some Type Classes They are regular traits. It’s how you use them that makes them type classes.

Slide 22

Slide 22 text

@ImplicitNotFound * MINI TIP *

Slide 23

Slide 23 text

Helps your users understand what the compiler is looking for

Slide 24

Slide 24 text

“But how do I provide default implementations of these type classes without preventing custom implementations?” - Me, two months ago

Slide 25

Slide 25 text

Manipulating Implicit Resolution Implicits Without the Import Tax AND Without Blocking Your Users

Slide 26

Slide 26 text

The Problem: error: ambiguous implicit values: both ... and ... match expected ... When the Scala compiler tells you: When two implicits get resolved at the same level the compiler cannot choose between them

Slide 27

Slide 27 text

Implicit Resolution Rules: Implicits Defined in Current Scope Explicit Imports Wildcard Imports Same Scope in Other Files Companion Objects of a Type Implicit scope of an argument’s type Implicit scope of type arguments Outer Objects for Nested Types Other Dimensions Don’t worry, it’s easier than it sounds!

Slide 28

Slide 28 text


Slide 29

Slide 29 text


Slide 30

Slide 30 text

The Solution: Make sure your default implementations have the lowest possible implicit resolution priority

Slide 31

Slide 31 text

Meanwhile in Predef...

Slide 32

Slide 32 text

ClassTag & TypeTag Manifests 2.0 * MINI TIP * Yet more builtin type classes

Slide 33

Slide 33 text

Type Erasure Erased! No reflection required!

Slide 34

Slide 34 text

Abstract Types Just another way to say [T]

Slide 35

Slide 35 text

When [T] doesn’t make sense: When information about a type is only useful on the inside, don’t bother your users with a type parameter and use abstract types instead

Slide 36

Slide 36 text

That’s all folks!

Slide 37

Slide 37 text