Published 2013-09-18.
Last modified 2019-10-09.
Time to read: 10 minutes.
Implicit values simplify API usage. Value classes are also introduced, which can provide type safety without incurring runtime overhead.
Git Clone the Course Notes
The sample code for this lecture can be found in
courseNotes/
.
The quickest way to get a copy of the git repository with the course notes for this project is to type the following in a console with the current directory set to where you want to work with this course.
$ git clone https://github.com/mslinn/course_scala_intermediate_code_new
This creates a subdirectory called course_scala_intermediate_code_new.
You can update your copy of the course notes at any time by typing the following into a shell prompt in the same course_scala_intermediate_code
directory:
$ git pull origin master
As with the previous course, I show code throughout this course that can be pasted into the REPL, and that code is also provided in the courseNotes
directory.
You can choose to run the sample code as standalone programs, or you can paste it into the REPL to play with, or you can paste it into a Scala worksheet.
Refer to Lecture Transcripts
When this course is updated, the transcripts are updated first, and then the videos are updated. Sometimes an appreciable amount of time might pass between updating a transcript and updating the corresponding video, or both might be updated simultaneously, depending on the material.
This Lecture Introduces Two Concepts

The two concepts introduced in this lecture are distinct and are completely independent. Here is a high-level description of this lecture’s two main points; do not worry if the description of concept #2 does not make sense yet, it will be fully explored in this lecture.
It is a common object-oriented (OO) design error to just use raw types like Strin
s
and g
Int
s for lesser domain objects like record ids, map keys, counters, etc.
Java, Ruby and Python programmers have been taught to use primitive types and low-level classes because in those languages, classes incur a runtime penalty.
Scala 2.11 introduced value classes, which if properly used provide type safety without incurring OO overhead at runtime for many common scenarios.
Scala value classes encourage better OO designs because there is no longer any reason to use raw types.
Implicit values become much more useful when they are strongly typed instead of being defined as just Int
s or String
s.
That is because implicit values match on types; the more specific the implicit value’s type, the more robust the design will be.
Combining both concepts: Implicit values that are also value objects also do not incur a runtime overhead in many / most circumstances.
What is an Implicit Value?
Implicit values allow missing method parameters to be found in the runtime context.
This means implicit values are useful for simplifying APIs.
Both the object being supplied as an implicit parameter and the method signature must be decorated with the word implicit
.
implicit val defaultMultiplier = 2
def multiply(value: Int)(implicit multiplier: Int): Int = value * multiplier
Note that multiply
has two parameter lists, and that the second is prefaced with the word implicit
.
This is because if a parameter in a list is implicit
, all parameters in that list become implicit
.
Only the last parameter list may be implicit
.
Let’s see how to use the above definitions.
scala> multiply(2)(3) res0: Int = 6
scala> multiply(5) res1: Int = 10
The above code can be run like this, as discussed in the SBT Project Setup and SBT Tasks and Settings lectures of the Introduction to Scala course.
$ sbt "runMain ImplicitValues"
Following the uniform access principle (discussed in the
Setters, Getters and the Uniform Access Principle lecture of the
Introduction to Scala course),
val
s, var
s and def
s may all be marked implicit
,
however implicit methods have a special use, as we shall learn in the next lecture
(Implicit Conversions).
If multiple implicitly defined objects are available, the first matching object found in the following search order will be used: local scope, enclosing class, parent class, and companion object. The companion object was discussed in the Objects lecture of the Introduction to Scala course.
Note that implicit values can only exist within a specific scope, and cannot be top-level entities; they must be members of a trait, class or object.
Managing Implicit Values
The above example shows an implicit of type Int
being used in a code fragment.
This works fine for small programs, however imagine a much larger program that has many implicits of type Int
, used for various purposes.
It would be difficult to identify which implicit that should be used because the Scala compiler matches implicits based on type.
Let’s rewrite the above so it uses a wrapper class to allow us to identify the Int
values we wish to target to implicit parameters.
This writing style is more appropriate for a large-scale program.
To drive the point home, we introduce another operation, division, which also requires an implicit Int
.
The Divider
wrapper class clarifies the Int
that should be used when resolving implicits.
Using the REPL.
case class Multiplier(value: Int)
case class Divider(value: Int)
implicit val defaultMultiplier = Multiplier(2)
implicit val defaultDivider = Divider(3)
def multiply(value: Int)(implicit multiplier: Multiplier): Int = value * multiplier.value
def divide(value: Int)(implicit divider: Divider): Int = value / divider.value
Now we can use the above just the same as before.
scala> multiply(2)(Multiplier(3)) res2: Int = 6
scala> multiply(5) res3: Int = 10
scala> divide(12)(Divider(4)) res4: Int = 3
scala> divide(9) res5: Int = 3
The rules for where implicits may be defined and how they are resolved are bent a bit by the REPL. The only way to find out what is actually legal is to write a real Scala program. Let’s recast the above as an actual Scala program.
object ImplicitValues2 extends App { implicit val defaultMultiplier = Multiplier(2)
implicit val defaultDivider = Divider(3)
def multiply(value: Int)(implicit multiplier: Multiplier): Int = value * multiplier.value
def divide(value: Int)(implicit divider: Divider): Int = value / divider.value
println(s"multiply(2)(Multiplier(3))=${multiply(2)(Multiplier(3))}") println(s"multiply(5)=${multiply(5)}") println(s"divide(12)(Divider(4))=${divide(12)(Divider(4))}") println(s"divide(9)=${divide(9)}") }
You can run this code as follows:
$ sbt "runMain ImplicitValues2" multiply(2)(Multiplier(3))=6 multiply(5)=10 divide(12)(Divider(4))=3 divide(9)=3
The next lecture will show how we can rewrite the above so Int
s get converted to Multiplier
s and Divider
s automatically, as required.
Accessing the Implicit Value in Scope
Sometimes you need to obtain the implicit
value selected by the compiler for a given type.
The implicitly
function can provide that implicit value to you.
We can use implicitly
to search for an implicit value of type Multiplier
and assign it to a variable called m
.
scala> val m = implicitly[Multiplier] m: Multiplier = Multiplier(2)
Now lets look for an implicit value that does not exist.
For example, let’s search for an implicit
value of type Int
and attempt to assign it to c
.
scala> val c = implicitly[Int] <console>:6: error: could not find implicit value for parameter e: Int val c = implicitly[Int]
The error is confusing.
In the code shown there is no parameter called e
.
Using implicitly To Resolve Implicit Parameters
If multiple implicit parameters are passed to a method, they must co-exist in the same parameter list, and that parameter list must be the last.
For example, here is a case class that accepts two parameter lists.
The first parameter list accepts an Int
called a
, and a String
called b
.
The implicit parameter list follows the first parameter list, and it accepts an instance of a java.util.Date
and a Multiplier
.
case class ImplicitDemo(a: Int, b: String)(implicit date: java.util.Date, multiplier: Multiplier)
Let’s say that an implicit Multiplier
instance is in scope, but no implicit Date
instance is available.
In order to create an instance of ImplicitDemo
an instance of Date
will have to be provided explicitly.
However, if one value of an implicit parameter list is provided than all of the other values in the parameter list must also be explicitly provided.
The way to do this is to use implicitly
to obtain the other implicit values in scope.
ImplicitDemo(1, "two")(new Date, implicitly[Multiplier])

@implicitNotFound
This is another reason to use a strongly typed implicit: because you can specify a custom error message when an implicit is not found.
Let’s do that with Multiplier2
and Divider2
: by using the @implicitNotFound
annotation.
import annotation.implicitNotFound
@implicitNotFound("Cannot find implicit of type Multiplier2 in scope") case class Multiplier2(value: Int)
@implicitNotFound("Cannot find implicit of type Divider2 in scope") case class Divider2(value: Int)
@implicitNotFound
can be applied to all kinds of classes and traits.
Here is how it works.
scala> implicitly[Multiplier2] <console>:16: error: Cannot find implicit of type Multiplier2 in scope implicitly[Multiplier2] ^
Value Classes
Multiplier
and Divider
require a new object allocation each time an instance is created; this is known as "boxing".
Referencing the wrapped value requires "unboxing".
The boxing and unboxing can be avoided by deriving the wrapper classes from AnyVal
, which is the parent of all value classes.
Recall that a value class simply contains a single value.
Examples of value classes include Int
and String
.
Value class constructors can only accept one val
parameter, which is the underlying runtime representation.
We can modify Multiplier
and Divider
to become value classes by having them extend AnyVal
, like this.
case class Multiplier3(value: Int) extends AnyVal
case class Divider3(value: Int) extends AnyVal
Now Int
s can be converted to Multiplier3
and Divider3
instances without boxing and unboxing,
because the runtime representation of value classes is actually the primitive type (Int
).
Once the references to Multiplier
and Divider
are changed to Multiplier3
and Divider3
,
no other changes are required to the rest of the program.
You can run the version of the sample code which uses value classes like this.
$ sbt "run-main ImplicitValues3"
By the way, you can define value classes as regular classes, if you prefer.
Just be sure to make the value a property by decorating it with val
.
object ImplicitValues4 extends App { @implicitNotFound("Cannot find implicit of type Multiplier4 in scope") class Multiplier4(val value: Int) extends AnyVal
@implicitNotFound("Cannot find implicit of type Divider4 in scope") class Divider4(val value: Int) extends AnyVal
implicit val defaultMultiplier = new Multiplier4(2)
implicit val defaultDivider = new Divider4(3)
def multiply(value: Int)(implicit multiplier: Multiplier4): Int = value * multiplier.value
def divide(value: Int)(implicit divider: Divider4): Int = value / divider.value
println(s"multiply(2)(3)=${multiply(2)(new Multiplier4(3))}") println(s"multiply(5)=${multiply(5)}") println(s"divide(12)(4)=${divide(12)(new Divider4(4))}") println(s"divide(9)=${divide(9)}") }
You can run the version of the sample code which uses value classes that are not case classes like this.
$ sbt "run-main ImplicitValues4"
Finally, value classes may not contain internally defined variables. For example, this generates a compiler error:
class Multiplier4(val value: Int) extends AnyVal { val x = 1 }
Value classes have numerous limitations, and may require allocation (leading to boxing/unboxing) in many circumstances. This means that benchmarking your application may reveal that value classes provide no benefit while imposing awkward limitations. The use case presented here, typesafe default values delivered via implicits, without any further manipulation of those values, is a good use of value classes.
Value classes may improve if SIP-35 (Opaque Types) is accepted.
Exercise: Implicit Single Parameter List
This exercise will show you an implementation quirk of Scala’s implicit values.
Modify the ImplicitValues4
program above and add a new operation called square
.
This new method only accepts one parameter, which is implicit, that is the value to square.
The method signature should be:
def square(implicit squarer: Squarer): Int
Hint
- The quirk is this: to call the new
square
method such that it picks up the implicit value currently in scope, simply type the name of the method without using any parentheses, like this:Scala codesquare
Solution
package solutions
import scala.annotation.implicitNotFound
object ImplicitValues extends App { @implicitNotFound("Cannot find implicit of type Multiplier4 in scope") class Multiplier4(val value: Int) extends AnyVal
@implicitNotFound("Cannot find implicit of type Divider4 in scope") class Divider4(val value: Int) extends AnyVal
@implicitNotFound("Cannot find implicit of type Squarer in scope") class Squarer(val value: Int) extends AnyVal
implicit val defaultMultiplier = new Multiplier4(2)
implicit val defaultDivider = new Divider4(3)
implicit val defaultSquarer = new Squarer(4)
def multiply(value: Int)(implicit multiplier: Multiplier4): Int = value * multiplier.value
def divide(value: Int)(implicit divider: Divider4): Int = value / divider.value
def square(implicit squarer: Squarer): Int = squarer.value * squarer.value
println(s"multiply(2)(3)=${multiply(2)(new Multiplier4(3))}") println(s"multiply(5)=${multiply(5)}") println(s"divide(12)(4)=${divide(12)(new Divider4(4))}") println(s"divide(9)=${divide(9)}") println(s"square(5)=${square(new Squarer(5))}") println(s"square=${square}") }
To run this solution, type.
$ sbt "runMain solutions.ImplicitValues"

Strongly Typed Method Parameters
This code example mirrors the structure of database access from Scala, without actually using a database.
The sample code for this lecture can be found in
courseNotes/
.
Imagine you need to define a method that grants permissions to a User
.
Let’s use the following Java enum for the permission levels.
We discussed various options for defining enumerated values in the
Enumerations lecture of the
Introduction to Scala course.
public enum Permission { GUEST, CHILD, PARENT }
Assuming that there is a User
type defined, here is a Users
object that resembles how we might access a database.
Notice the private mutable collection, and the two methods: add
(which returns the Users
object so method calls can be chained) and findByName
.
object Users { private val users = ListBuffer.empty[User]
def add(user: User) = { users += user this }
def findByName(name: String): Option[User] = users.find(_.name==name).headOption }
Weakly Typed Code Example
User
could be defined like this:
case class User(name: String, permissions: Seq[Permission], id: Option[Int]=None)
Here is a weakly typed method authorize
definition.
It is weakly typed because granteeName
is a String
.
implicit class RichUser(user: User) { def authorize(granteeName: String, permission: Permission): Option[User] = for { grantor <- Some(user) if user.permissions.contains(PARENT) grantee <- Users.findByName(granteeName).headOption } yield grantee.copy(permissions = grantee.permissions :+ permission) }
Now we can create two User
instances and add them to the Users
collection.
Note that User
wilma
has the PARENT
permission, but User
pebbles
has no permissions.
val wilma = User("Wilma Flintstone", List(PARENT), Some(1)) val pebbles = User("Pebbles Flintstone", Nil, Some(2)) Users.add(wilma).add(pebbles)
User
wilma
can now grant the CHILD
permission to pebbles
.
wilma.authorize(pebbles.name, CHILD) match { case Some(child) => println(s"${child.name} got upgraded permissions")
case None => println("Authorization failed") }
However, there is nothing to prevent someone from getting confused and writing code that attempts to have
pebbles
grant CHILD
permission to wilma
instead.
pebbles.authorize(wilma.name, CHILD) match { case Some(child) => println(s"${child.name} got upgraded permissions")
case None => println("Authorization failed") }
You can run this program by typing:
$ sbt "runMain WeaklyTypedParameters" Pebbles Flintstone got upgraded permissions Authorization failed
Strongly Typed Code Example
Let’s define User
wrapper value types for Grantor
and Grantee
,
and add methods to User
that wraps the User
instance in the desired value type.
import collection.mutable.ListBuffer import Permission._
case class User(name: String, permissions: Seq[Permission], id: Option[Int]=None) { def asGrantee: Grantee = Grantee(this)
def asGrantor: Grantor = Grantor(this) }
case class Grantor(user: User) extends AnyVal { def authorize(grantee: Grantee, permission: Permission): Option[Grantee] = { if (user.permissions.contains(PARENT)) Some(grantee.withPermission(permission)) else None } }
case class Grantee(user: User) extends AnyVal { def withPermission(permission: Permission): Grantee = { val newUser = User(user.name, user.permissions :+ permission, user.id) Grantee(newUser) } }
Now we can create mother Wilma and daughter Pebbles, and add them to the Users
collection as before.
val wilma = User("Wilma Flintstone", List(PARENT), Some(1)) val pebbles = User("Pebbles Flintstone", Nil, Some(2)) Users.add(wilma).add(pebbles)
Here is where we explicitly state the role that we want each user to take on (Grantor
or Grantee
).
wilma.asGrantor.authorize(pebbles.asGrantee, CHILD) match { case Some(Grantee(child)) => println(s"${child.name} now has permissions ${child.permissions.mkString(", ")}")
case None => println("Authorization failed") }
This means that the following logic error will not compile:
pebbles.asGrantee.authorize(wilma.asGrantor, CHILD) match { case Some(child) => println((s"${child.name} now has permissions ${child.permissions.mkString(", ")}")
case None => println("Authorization failed") }
You can run this program by typing:
$ sbt "runMain StronglyTypedParameters" Pebbles Flintstone now has permissions CHILD
’With’ Pattern Using Implicits
As we saw in the More Fun With Functions lecture of the Introduction to Scala course, the With Pattern is common used in Scala; again, this is my name for the pattern – that name is not widely recognized. Let’s modify the example we used to include implicit values.
case class Blarg(i: Int, s: String)
def withBlarg(blarg: Blarg)(operation: Blarg => Unit): Unit = operation(blarg)
def double(implicit blarg: Blarg): Blarg = blarg.copy(i=blarg.i*2, s=blarg.s*2)
def triple(implicit blarg: Blarg): Blarg = blarg.copy(i=blarg.i*3, s=blarg.s*3)
The above code looks very much like what we saw in the previous course.
This code does not yet take advantage of the implicit
parameters defined for the double
and triple
methods.
scala> withBlarg(Blarg(1, "asdf")) { blarg => | println(double(blarg)) | println(triple(blarg)) | } Blarg(2,asdf asdf) Blarg(3,asdf asdf asdf)
If we decorate the blarg
reference passed into the closure with implicit
,
we can rewrite as follows (see the Closures lecture of the
Introduction to Scala course to refresh your memory of what a closure is).
scala> withBlarg(Blarg(1, "qwer")) { implicit blarg => | println(double) | println(triple) | } Blarg(2,qwer qwer) Blarg(3,qwer qwer qwer)
You can arbitrarily decorate the incoming parameter(s) with implicit
any time you see a With Pattern being used.
The author of withBlarg
does not know or care if you decorate the incoming Blarg
instance with implicit
.
The above is provided in the same source file. To run the code:
$ sbt "run-main With2" Blarg(2,asdf asdf ) Blarg(3,asdf asdf asdf ) Blarg(2,qwer qwer ) Blarg(3,qwer qwer qwer )
The Structural Types With Parametrics section of the Structural Types lecture extends the With Pattern by adding parametrics for type safety and uses compiler-assisted introspection to provide duck typing to ensure that resources are closed even when exceptions are thrown.
Exercise – Understanding Implicits by Reading Code
The ability to read someone else’s code is a skill that only comes with practice. What does this program do.
import java.util.{Date, Locale} import java.text.{NumberFormat, DateFormat}
object WithLocale extends App { def formatDateTime(date: Date)(implicit dateFormat: DateFormat): String = dateFormat.format(date)
def formatNumber(number: BigDecimal)(implicit numberFormat: NumberFormat): String = numberFormat.format(number)
def withLocale(locale: Locale)(body: Locale => String): String = body(locale)
def result(date: Date, number: BigDecimal)(implicit locale: Locale): String = { implicit val dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale) implicit val numberFormat = NumberFormat.getNumberInstance(locale) val currencyCode = numberFormat.getCurrency.getCurrencyCode s"""${locale.getDisplayCountry}; currency: $currencyCode; """ + s"""date/time: ${formatDateTime(date)}; large number: ${formatNumber(number)}""" }
val resultUS = withLocale(Locale.US) { implicit locale => result(new Date, 123456789) }
val resultFrance = withLocale(Locale.FRANCE) { implicit locale => result(new Date, 987654321) }
println(resultUS) println(resultFrance) }
Solution
You can run the program like this.
$ sbt "runMain WithLocale" United States; currency: USD; date/time: Mar 1, 2014 3:04:24 PM; large number: 123,456,789 France; currency: EUR; date/time: 1 mars 2014 15:04:24; large number: 987 654 321
SLS §7.1
As a reminder, the syntax for Scala value implicits discussed so far can do two things.
- Retrieve values for method parameters from the current scope
- Provide values to other methods contained within the same scope
Section 7.2 of the Scala Language Specification (SLS) discusses this syntax in a formal manner. This reference is often written as SLS §7.2, because the § character means "section".
SLS §7.1 seems to discuss a lesser-known syntax for specifying implicit values to methods (I find §7.1 obtuse). I don’t like this syntax: it is not very useful and has an undesirable side effect. However, I am showing this to you because if you see this syntax you should know what you are looking at.
This syntax only supports the second capability just described: it can only implicitly provide a value within a class
or method body, and it cannot receive implicit values.
As usual, we will explore this by way of an example.
First, some setup; you have seen similar code before.
The difference with this code is the second parameter to the Sls71
class is an implicit val
.
case class Blarg(i: Int, s: String) { override def toString = s"$i $s" }
class Sls71(a: Int, implicit val blarg: Blarg) { def double(implicit blarg: Blarg): Blarg = blarg.copy(i=blarg.i*2, s=blarg.s*2) def triple(implicit blarg: Blarg): Blarg = blarg.copy(i=blarg.i*3, s=blarg.s*3)
val bigBlarg = if (a<10) double else triple }
Notice that all the SLS §7.1 implicit
does is simplify the method invocations for double
and triple
,
so arguments do not need to be explicitly supplied.
This syntax has the side effect of causing the implicit parameter to be a public property of the class.
If you don’t want that, you could mark the property as private
.
class Sls71(a: Int, private implicit val blarg: Blarg)
Now we can use the Sls71
class in an input/eval/output loop.
The Immutable Collections lecture will describe how the loop works.
print("> ") Iterator.continually(io.StdIn.readLine()) .takeWhile(_ != null) .foreach { line => try { val i = line.toInt val blarg = Blarg(i, "nom ") val sls71 = new Sls71(i, blarg) println(sls71.bigBlarg.s) print("> ") } catch { case ignored: Exception => sys.exit } }
Here is what happened when I ran the above code. When prompted, I entered the values "3" and "13", followed by Enter. The loop terminates when the user either types Enter by itself or ^D.
$ sbt "runMain SLS7_1" ... output not shown ... scala> 3Enter nom nom
scala> 13Enter nom nom nom > ^D
SLS §7.1 Syntax Degrades Into §7.2 Syntax
Here is the same class constructor signature again.
class Sls71(a: Int, implicit val blarg: Blarg)
Notice what happens if we reverse the order of the parameters:
class Sls71(implicit val blarg: Blarg, a: Int)
This is SLS §7.2 syntax!
Both parameters of the one and only parameter list are now implicit.
If you do not need the Blarg
parameter to be a public property of the class,
the SLS §7.2 syntax does not require the val
.
class Sls71(implicit blarg: Blarg, a: Int)
© Copyright 1994-2024 Michael Slinn. All rights reserved.
If you would like to request to use this copyright-protected work in any manner,
please send an email.
This website was made using Jekyll and Mike Slinn’s Jekyll Plugins.