Scala Implicits

The good, the bad and the ugly

Agenda

  • Implicit values and parameters
  • Implicit conversions
  • Implicit classes
  • Typeclasses
  • Where to put implicit values

Implicit values and parameters

Note: The keyword is applied to the whole argument list, so we use two lists two differentiate what's explicit and implicit

Implicit values and parameters

Works the same for constructor parameters:

Typical Use-Cases

Passing runtime environments like ExecutionContext, ActorSystem or FlowMaterializer into methods and function of a certain type.

For example, calling ".map" on a Future without providing an implicit ExecutionContext will fail at compile-time:

Typical Use-Cases

Providing configuration for DSLs

For example, overriding Scalatest's property check config...

...or changing the circe json Printer for akka-http-circe:

Implicit Conversions

Automatically convert one type into another.

In newer Scala versions this is considered an advanced language feature and needs to be enabled (for good reason).

Implicit Conversions

Hidden conversions like that can be frustrating to debug, so please don't use them. There are better options in most cases (e.g. extension methods and typeclasses)

Implicit Classes

Implicit classes automatically subclass a type to make new methods available.

This is especially useful for types you cannot change (primitives or library classes)

(a.k.a. Extension Methods)

Implicit Classes

When you write extension methods for "foreign" types it is a good idea to have a dedicated "syntax" import. As usual cats and circe libs are a good example:

Note: IntelliJ will usually underline code that uses implicits, and there are actions

to display "Implicit conversions" and "Implicit parameters" (search for "Implicit" using cmd+shift+A)

Typeclasses

Typeclasses are a pattern, which is often a language feature (e. g. in Haskell, Purescript, Idris), but is possible to use in Scala thanks to normal implicits.

For example you can use circe's Encoder typeclass to convert types to json as long as they have an implicit Encoder in scope:

Typeclasses

There is syntactic sugar for requiring a typeclass called "context bound":

Where to put implicit values?

If they belong to a specific type, put them in the companion object of the type:

Where to put implicit values?

If they belong to types you don't "own" (types from libraries) or are very generic:

Either put them in a package or object and import them...

...or put them in a mixin trait

Scala Implicits

By Felix Bruckmeier

Scala Implicits

A short rundown on the various "implicit" features in Scala.

  • 148