Daniel Ciocîrlan
5 min read •

Share on:
This will be a short article. Here, I’ll demonstrate the use of given instances/using clauses combo, and how this can work with the existing implicits-based mechanism.
First, if you’re not familiar with given/using combos in Scala 3, I recommend you read these articles first:
The new given/using combos in Scala 3 were created to reduce some of the power of the implicit keyword, which may be easily misused. The main arguments for implicits include:
Even as the new given instances/using clauses in Scala 3 were designed to replace the existing implicit val/object + implicit argument combos, the implicit keyword has not disappeared from Scala 3. It will be slowly deprecated and eventually removed from the language.
However, this causes a confusion: are we supposed to continue using implicits? How are we going to work with existing codebases?
Short answers:
given/using combos for implicit values/objects + implicit arguments.But how can you use the new givens-based mechanism with existing codebases riddled with implicits?
The given mechanism works in the same way as the implicit mechanism, for the purpose of finding an instance to insert into a method which requires it. Namely, if you specify a using clause, the compiler will look for a given instance defined in the following places, in order:
I talk more in depth about this mechanism in the advanced Scala course, but it should suffice for this article.
For example, let’s consider a simple no-arg method which requires a given instance:
def aMethodWithGivenArg[T](using instance: T) = instance
This is pretty much the definition of the built-in summon[T] method in Scala 3. If you call aMethodWithGivenArg[Int], the compiler will look for a given value of type Int in the following places:
Int objectSo if we define
given meaningOfLife: Int = 42
we can call
val theAnswer = aMethodWithGivenArg[Int] // 42
The exact same mechanism works in the case of a method taking an implicit argument:
def aMethodWithImplicitArg[T](implicit instance: T) = instance
This is exactly the definition of the built-in implicitly[T] method in Scala 2 (also available in Scala 3 while implicits are still here). If you call aMethodWithImplicitArg[Int], the compiler will run the exact same search for an implicit Int:
Int objectSo as you can see, the mechanism is identical: if we define an implicit
implicit meaningOfLife: Int = 43
then we would be able to call the method as
val theAnswer = aMethodWithImplicitArg[Int] // 43
In order to be able to run a smooth transition between Scala 2 and Scala 3, the mechanism for finding given/implicit instances is identical, so you can keep assuming a similar mental model, with a slightly different syntax: given/using instead of implicit.
Now, in order to be able to interface with code written with implicits, you can simply define your new methods with given/using, and your existing implicit values will work fine:
// new method
def aMethodWithGivenArg[T](using instance: T) = instance
// old implicit
implicit val theOnlyInt: Int = 42
val theInt: Int = aMethodWithGivenArg[Int] // 42
It also works vice-versa: if you’re working with an old method with implicits, and you’re now defining given values, that’ll work too:
// old method
def aMethodWithImplicitArg[T](implicit instance: T) = instance
// new given
given meaningOfLife: Int = 42
val theAnswer = aMethodWithGivenArg[Int] // 42
At the same time, compiler will trigger ambiguities if it finds both an implicit val or a given in the same scope:
// old method
def aMethodWithImplicitArg[T](implicit instance: T) = instance
// confusion
given meaningOfLife: Int = 42
implicit val theOnlyInt: Int = 42
This will happen regardless if your method takes an implicit argument or has a using clause.
In this article, we learned that the new given/using mechanism works in the same way as the old implicit val/object + implicit argument, and we can interoperate between them without any problems. This capability was created for our peace of mind as we move to Scala 3.
That said, going forward, we should all be using the new given/using structures from now on.
Share on: