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