How to keep your sanity working with Scala Implicit!

Posted on Oct 17, 2019

image Courtesy: https://www.pexels.com/

Intro

Scala Implicits provide a lot of power and flexibility to express the code in such beautiful ways that development sometimes feel like and art and are nothing short of a “Brahmastra” in the hand of a library developer.

And, as Spider-man’s uncle said,

“With great power, comes greater responsibility!”

The abuse of such a powerful feature has made working with them a nightmare sometimes for the end users. For example:

image

You will keep you head scratching over the above script until you find an implicit conversion (from Int to String) and an extension method (toHindiDigits) coming from just two imports!

image

image

Even Martin Odersky ( 🙌), the creator of Scala has admitted that he has made quite a few mistakes with the Implicits while designing the Scala language 😱!

While this can be really disheartening, this is not enough of a reason to move away from an amazing programming language, just because of a really abused feature! After all, there are other languages with much more horrible warts!

image Courtesy: https://me.me

And JS is the most popular language right now 😉So, coming onto our topic, keeping the sanity of our mind! For that, we can follow some tips:

Use an IDE

Personal choice, IntelliJ IDEA with Scala plugin.

Look at features from JetBrain’s Scala plugin blog:

You can show implicitly passed parameters in a function, using “show implicit hints” feature, so that there’ll be no surprises as what was passed:

image

Similar example,

image

image

Avoid implicit conversions/defs

This can become a complete nightmare if a String or any type gets converted to another on the fly without even telling us and we spend hours debugging the issue

Even Scala compiler will warn you if you use implicit conversion without a specific import ( scala.language.implicitConversions ):

image

So, the tip is, avoid implicit conversions at all costs. When you absolutely need a conversion in your code in a convenient manner, please use implicit classes with extension method like:

trait A
trait B

//avoid this:
//implicit def aToB(a: A): B = ???

//do this instead:
implicit class RichA(a: A) {
  def toB = ???
}

//use it like this:
val someA: A = ???
val someB: SomeB = someA.toB

//so that, this will be avoided:
//val someB: SomeB = someA

Ditch the type inference and annotate the required types

Simple logic: Avoid surprises 😅 and let compilation fail on mismatches!

Check the imports

Any underscore imports may contain implicit conversions, parameters and/or somewhat safe implicit classes.

Conclusion

So, these were my highly opinionated rules to avoid surprises and headaches while working with Scala Implicit! They are really powerful tools for writing really awesome code, please use them, don’t abuse them :)