Back2Basics: The Magic of Implicits


Implicit System is one of Scala’s language greatest feature with the help of which we can write concise code. The implicit system in Scala allows the compiler to adjust code using a well-defined lookup mechanism.

In this post, we will try to understand how Scala’s implicit work magically.

Scala provides an implicit keyword that can be used in two ways: method or variable definitions, and method parameter lists.

Let us define a method.

scala> def findAnInt(implicit x : Int) = x
findAnInt: (implicit x: Int)Int

the findAnInt method will return any Int value which is passed to it. Notice that it’s parameter is implicitly defined. Marking it implicitly means that we don’t need to provide it. So, where will the compiler look for this implicit variable? If it’s left off, the compiler will look for a variable of type Int in the implicit scope, if the compiler finds the value, the method call will be executed otherwise, an error will be thrown. Let us call the defined method.

scala> findAnInt
:13: error: could not find implicit value for parameter x: Int
findAnInt
^

As you can see, compiler shows an error stating that it can’t find any implicit value for the parameter x which is of type Int. So, what makes compiler so unhappy that it throws an error? As the parameter of findAnInt method is implicit, so when the method is called without any parameter, the compiler will look for a value of type Int in its implicit scope, but when it does not find any value, it will throw an error.

Let us now quickly define an implicit value of type Int and then call our method.

scala> implicit val value = 5
value: Int = 5

scala> findAnInt
res1: Int = 5

We can clearly see that compiler was able to execute method call successfully. However, we can still provide the parameter if desired.

One can also compare implicit parameters with default parameters.

scala> class Package
defined class Package

scala> def mail(thePackage: Package, mode: String = "Air") = {
| println(s"Sending package by mode: $mode")
| }
mail: (thePackage: Package, mode: String)Unit

scala> mail(new Package)
Sending package by mode: Air

So, we have defined a method mail which accepts two parameters, one is the object of type Package, another one is default parameter of type String. We can skip providing the second parameter while calling the method mail as it is a default parameter.
But the questions is who decides what the default value is? It is decided by the author of the function and is not decided by the caller of the function.

Implicit values are the opposite of the default ones. Here, the caller of the function decides what the value is rather than the definer of the function.

We can even mix both of them according to our use case. Let us understand this with the help of an example.

scala> def speaker(name: String)(implicit language: String= "French") = {
| println(s"$name can speak $language")
| }
speaker: (name: String)(implicit language: String)Unit

scala> def speakerOne(){
| implicit val english = "English"
| speaker("John")
| }
speakerOne: ()Unit

scala> def speakerTwo(){
| implicit val hindi = "Hindi"
| speaker("Henry")
| }
speakerTwo: ()Unit

scala> def speakerThree(){
| speaker("Shivangi")
| }
speakerThree: ()Unit

In this way, we can mixin both default and implicit parameter. We have used implicit value in method speakerOne and speakerTwo, but in speakerThree we have used the default value for the parameter language. Scala does not stop us from using both of them together. It gives us the flexibility to choose according to our needs.

In the next blog, we are going to see how we can use implicit with methods and type classes. Happy reading.

Reference:

  • Scala in Depth by Joshua D Suereth

knoldus-advt-sticker


 

This entry was posted in knoldus, Knoldus Chrome Exntesion, Scala, Tutorial and tagged , , , , , , , . Bookmark the permalink.

2 Responses to Back2Basics: The Magic of Implicits

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s