# Implied, Lisa, or Implode?

One of the worst fears a Scalaman may have is implicits: you don’t like them, you avoid them, they’re scary, they’re bloody hell.

And it’s a pitty that, being able to use that powerful tool, you might get in panic and forget about it, avoiding its use. Implicits may result a fancy solution for certain circumstances as we will enum you later.

To have a much better understanding, lets set up a theoretical framwork.

### Implicit values

Imagine you are defining ‘identity’ function over integer numbers’ operations (given an integer number and an operation, it should return the same number). Depending on operation type, the value to be used in the operation (add,product) is different. For example, for adding we use zero (0 + n = n) and for multiplying we use 1 (1 * n = n). If you want to avoid passing the neutral element in a explicit way, you can use implicit values as follows.

First of all, we declare an implicit integer that will represent adding neutral element:

```implicit val addNeutralElement: Int = 0
```

And now, we can declare identity function at adding:

```def addIdentity(n: Int)(implicit neutral: Int): Int =
n + neutral
```

Have a closer look and realize that implicit parameters in the method are declared in a different parameter group, and they are preceded by the reserverd word ‘implicit‘.

Another tip to have in mind is that, what really matters is the argument type instead of its name: compiler will look for an implicit integer within the set up scope.

This can be also applied to methods:

```implicit def generateAddIdentity():Int = 0
```

…and objects…

```abstract class NeutralElement(n: Int)
implicit case object AddNeutralElement extends NeutralElement(0)
```

### Implicit ambiguity / Scopes

So let’s say we want to define now the identity function for multiplying. At the same scope, we could define another implicit value for product neutral element:

```implicit val addNeutralElement: Int = 0
implicit val productNeutralElement: Int = 1
def addIdentity(n: Int)(implicit neutral: Int): Int =
n + neutral
def productIdentity(n: Int)(implicit neutral: Int): Int =
n * neutral
```

If we try to execute any of both methods…Woops! The compiler will complain about something nearly understandable:

```scala> addIdentity(2)
<console>:13: error: ambiguous implicit values:
both value addNeutralElement of type => Int
and value productNeutralElement of type => Int
match expected type Int
^
```

What it really means is it doesn’t know which of both implicit values is the needed one: there’s implicit ambiguity. To avoid this, you can define different scopes which are provided by context objects. Something like:

```object AddStuff {
implicit val addNeutralElement: Int = 0
def addIdentity(n: Int)(implicit neutral: Int): Int =
n + neutral
}

{
}
```

I know this is yelling: “I need type-classes!” but we’re not removing these gold minutes from implicits topc. We’re not that much cruel…

### Implicit classes

We can also define implicit classes in Scala. Their main target is to extend functionality of certain classes. For example, if we’re using some third parties’ framework, and one of its classes looks like this:

```class ThirdParties {
def method1(): Int = ???
def method2(n:Int): Boolean = ???
}
```

we cannot modify its source code, but if we want to add some extra methods to ThirdParties’ class, we can define an implicit class:

```implicit class ExtraThirdParties(tp: ThirdParties){
def method3(n: Int): Boolean =
!tp.method2(n)
def method4(): Int = ???
def method5(): Int =
tp.method1() * 2
}
```

This way, when we type down a ‘ThirdParties’ value and a method that doesn’t belong to its class, the compiler will look for implicit classes and/or methods that may fit in such signature. So we’ll be able to use, both originaly defined methods and the new ones (those we have just implemented in the implicit class):

```val myTp = new ThirdParties
myTp.method1()
myTp.method2(5)
myTp.method3(2)
myTp.method4()
myTp.method5()
```

### Use cases

So the million dollar question is, in which cases we can use this powerful swiss knife?

* Setting up execution contexts
* Generating DSLs
* Extending a class functionality (implicit classes)

Providing an example of all these cases would be really tough, so we will take a look at some of them in future posts.

Peace out! 🙂

Anuncios

## 3 respuestas a “Implied, Lisa, or Implode?”

• jpaniego dice:

Totally agree!
Indeed, we have a special post dedicated to context and view bounds 🙂