# Implicits

## The Implicit Modifier

Template members and parameters labeled with an implicit modifier can be passed to implicit parameters and can be used as implicit conversions called views. The implicit modifier is illegal for all type members, as well as for top-level objects.

###### Example Monoid

The following code defines an abstract class of monoids and two concrete implementations, StringMonoid and IntMonoid. The two implementations are marked implicit.

## Implicit Parameters

An implicit parameter list (implicit $p_1$,$\ldots$,$p_n$) of a method marks the parameters $p_1 , \ldots , p_n$ as implicit. A method or constructor can have only one implicit parameter list, and it must be the last parameter list given.

A method with implicit parameters can be applied to arguments just like a normal method. In this case the implicit label has no effect. However, if such a method misses arguments for its implicit parameters, such arguments will be automatically provided.

The actual arguments that are eligible to be passed to an implicit parameter of type $T$ fall into two categories. First, eligible are all identifiers $x$ that can be accessed at the point of the method call without a prefix and that denote an implicit definition or an implicit parameter. An eligible identifier may thus be a local name, or a member of an enclosing template, or it may be have been made accessible without a prefix through an import clause. If there are no eligible identifiers under this rule, then, second, eligible are also all implicit members of some object that belongs to the implicit scope of the implicit parameter's type, $T$.

The implicit scope of a type $T$ consists of all companion modules of classes that are associated with the implicit parameter's type. Here, we say a class $C$ is associated with a type $T$ if it is a base class of some part of $T$.

The parts of a type $T$ are:

• if $T$ is a compound type $T_1$ with $\ldots$ with $T_n$, the union of the parts of $T_1 , \ldots , T_n$, as well as $T$ itself;
• if $T$ is a parameterized type $S$[$T_1 , \ldots , T_n$], the union of the parts of $S$ and $T_1 , \ldots , T_n$;
• if $T$ is a singleton type $p$.type, the parts of the type of $p$;
• if $T$ is a type projection $S$#$U$, the parts of $S$ as well as $T$ itself;
• if $T$ is a type alias, the parts of its expansion;
• if $T$ is an abstract type, the parts of its upper bound;
• if $T$ denotes an implicit conversion to a type with a method with argument types $T_1 , \ldots , T_n$ and result type $U$, the union of the parts of $T_1 , \ldots , T_n$ and $U$;
• the parts of quantified (existential or universal) and annotated types are defined as the parts of the underlying types (e.g., the parts of T forSome { ... } are the parts of T);
• in all other cases, just $T$ itself.

Note that packages are internally represented as classes with companion modules to hold the package members. Thus, implicits defined in a package object are part of the implicit scope of a type prefixed by that package.

If there are several eligible arguments which match the implicit parameter's type, a most specific one will be chosen using the rules of static overloading resolution. If the parameter has a default argument and no implicit argument can be found the default argument is used.

###### Example

Assuming the classes from the Monoid example, here is a method which computes the sum of a list of elements using the monoid's add and unit operations.

The monoid in question is marked as an implicit parameter, and can therefore be inferred based on the type of the list. Consider for instance the call sum(List(1, 2, 3)) in a context where stringMonoid and intMonoid are visible. We know that the formal type parameter a of sum needs to be instantiated to Int. The only eligible object which matches the implicit formal parameter type Monoid[Int] is intMonoid so this object will be passed as implicit parameter.

This discussion also shows that implicit parameters are inferred after any type arguments are inferred.

Implicit methods can themselves have implicit parameters. An example is the following method from module scala.List, which injects lists into the scala.Ordered class, provided the element type of the list is also convertible to this type.

Assume in addition a method

that injects integers into the Ordered class. We can now define a sort method over ordered lists:

We can apply sort to a list of lists of integers yss: List[List[Int]] as follows:

The call above will be completed by passing two nested implicit arguments:

The possibility of passing implicit arguments to implicit arguments raises the possibility of an infinite recursion. For instance, one might try to define the following method, which injects every type into the Ordered class:

Now, if one tried to apply sort to an argument arg of a type that did not have another injection into the Ordered class, one would obtain an infinite expansion:

Such infinite expansions should be detected and reported as errors, however to support the deliberate implicit construction of recursive values we allow implicit arguments to be marked as by-name. At call sites recursive uses of implicit values are permitted if they occur in an implicit by-name argument.

Consider the following example,

As with the magic case above this diverges due to the recursive implicit argument rec of method foo. If we mark the implicit argument as by-name,

the example compiles with the assertion successful.

When compiled, recursive by-name implicit arguments of this sort are extracted out as val members of a local synthetic object at call sites as follows,