Real-World Scala Design Patterns

Preview:

Citation preview

Between&

ZEROHEROTips & Tricks for the

Intermediate-Level Scala Developer

@agemooij!age@scalapenos.com✉

November 6th 2013

Formerly known as “Real-World Scala Design Patterns"

The Scala Skillz Gap

ZeroAbsolute beginners

heroMartin Odersky

Miles Sabin Viktor Klang

Daniel Spiewak Etc.

Target Audience

???Me

You?

> 50% ?

AgendaType Aliases Classtags Auto-lifted Partial Functions NoStackTrace !Type Classes Context Bounds & implicitly @implicitnotfound low priority default implicits

Tips{Tricks{

“Pattern” is such a big word

Type AliasesTip:

Creating an alternate name for a type, and sometimes for its companion object

“What would that be good for?”You:

Definition:Type Aliases

Type Aliases

When your API refers to external types...

...you force your users (and yourself) to always

have to import those types

Use Case: api usability

Type Aliases

By defining some type aliases in your base

package...

Use Case: api usability

...you give your users (and yourself) these dependencies for free

Use Case: simplificationType Aliases

Sometimes type signatures get in the way of understanding

A few well-placed type aliases can hide that complexity

And it saves a lot of typing too

Use Case: the standard library!Type Aliases

Tip:

ClassTagReflection without the Performance Tax

Mini

ClassTag

Easy access to erased class and type information without the runtime performance overhead

Explanation:

Auto-lifted Partial FunctionsTip:

You’re Probably Already Using This...

Mini

Explanation:Auto-lifted Partial Functions

When reading method signatures such as these:

You would think that you need to do this:

But in fact Scala allows you to do this:

Example:Auto-lifted Partial Functions

Don’t do this:

Auto-lifted Partial FunctionsExample:

Do this:

But watch out for MatchErrors if your partial function is not complete!

NoStackTraceTip:

Exceptions without the Performance Tax

Mini

The NoStackTrace TraitExplanation:

Remember this?

Huh?

For use in scala.util.Failure and other places that require Throwables without necessarily needing stack traces

Type ClassesTrick:

Demystified

Mystic

Type ClassesDefinition:

"A type of Adapter that uses Scala’s implicits to add some extra capabilities to an existing type

without direct coupling"

“Sort of like @Autowire for types...”

- Some guy on the internet

- Me

Type ClassesProblem:

It would be nice if there were an easy way to constrain T to something that can be

(de)serialized without forcing users to extend their domain classes from my traits

How do I turn a T into a RiakValue?

Type Classes

These are just regular Scala traits!

Step 1: define some useful traits

Type Classes

Making the parameter implicit is (most of) the big trick that turns RiakSerializer into a type class

Step 2: use them as implicit parameters

Context Bounds & ImplicitlyTrick:

Mini

Making Type Classes a little Prettier

Context Bounds & ImplicitlyExplanation:

Implicit parameters that look like this:

Can also be written like this:

You can always get a reference to any implicit value or parameter using the implicitly[T] function

Context Bounds & ImplicitlyExplanation:

You can add multiple context bounds to a type

@ImplicitNotFoundTrick:

Think of Your Users!

Mini

@ImplicitNotFoundExplanation:

Remember this?

When the compiler can’t find an implementation in implicit scope, it will complain in vague terms...

@ImplicitNotFoundExplanation:

The compiler errors can sometimes be a little confusing to unsuspecting developers...

@ImplicitNotFoundExplanation:

Ah, much better!

@ImplicitNotFoundExplanation:

Happier, less confused users

Low Priority Default ImplicitsTrick:

Making Type Classes Actually Useful

Final

Why?Low Priority Default Implicits

You want to provide some default implementations of your type classes so your users don’t have to do all the work.

The companion object for your type class is the perfect place for this, but....

Problem:Low Priority Default Implicits

You don't want your users to run into these kinds of problems when they want to override your defaults

Solution:Use the Scala rules for resolving implicits to your advantage

by making sure your defaults have the lowest possible implicit resolution priority

This is a very common trick in Scala libraries

Low Priority Default Implicits

Low Priority Default ImplicitsEven Predef.scala has them!

http://www.slideshare.net/DerekWyatt1/scala-implicits-not-to-be-feared http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html

Type ClassesFurther Reading:

http://eed3si9n.com/revisiting-implicits-without-import-tax http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

Low Priority Default ImplicitsFurther Reading:

Thank You!QUESTIONS?

@agemooij!age@scalapenos.com✉

Recommended