Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From A to L: Designing Scala Libraries

From A to L: Designing Scala Libraries

This is a talk I gave for the Dutch Scala Enthusiasts meetup on April 25th 2013. It describes some intermediate-level Scala tips and tricks that I learned while developing an open source Scala library.

Age Mooij

April 26, 2013
Tweet

More Decks by Age Mooij

Other Decks in Programming

Transcript

  1. 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

    View Slide

  2. View Slide

  3. 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

    View Slide

  4. My Library:

    View Slide

  5. 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

    View Slide

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

    View Slide

  7. 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

    View Slide

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

    View Slide

  9. Type Aliasing

    View Slide

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

    View Slide

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

    View Slide

  12. Everyone else is doing it:

    View Slide

  13. Type Classes

    View Slide

  14. 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...?

    View Slide

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

    View Slide

  16. 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?

    View Slide

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

    View Slide

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

    View Slide

  19. 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(...)

    View Slide

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

    View Slide

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

    View Slide

  22. @ImplicitNotFound
    * MINI TIP *

    View Slide

  23. Helps your users understand what the compiler is looking for

    View Slide

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

    View Slide

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

    View Slide

  26. 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

    View Slide

  27. 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!

    View Slide

  28. References:

    View Slide

  29. References:

    View Slide

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

    View Slide

  31. Meanwhile in Predef...

    View Slide

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

    View Slide

  33. Type Erasure Erased!
    No reflection required!

    View Slide

  34. Abstract Types
    Just another way to say [T]

    View Slide

  35. 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

    View Slide

  36. That’s all folks!

    View Slide

  37. SCALAPENOS
    Thank You
    WE ARE LOOKING FOR
    SCALA DEVELOPERS!!

    View Slide