Updated Proposal: Revisiting Implicits

I believe we are on the home stretch. given/using is the clear winner as far as I can see.

There’s one detail that we should still discuss. We currently use given/as for instances everywhere. I.e.:

given intOrd as Ordering[Int] ...
given t as Table
given ctx as Context = ForkJoinContext()

One reason to do so was that the form

given t: Table

looks like an abstract definition, which it is not. In fact,

given t as Table

is analogous to

implicit object t extends Table

A body is not required in either case. This analogy of as with extends is a good reason for keeping it for regular instance definitions.

But for aliases we do have a choice. Maybe it should be

given ctx: Context = ForkJoinContext()

instead? This would introduce an irregularity wrt regular instance definitions, but would align given aliases with using clauses and also with given in patterns. Indeed I can already write

val (given ctx: Context, n) = (ForkJoinContext(), 42)

Here, the given prefix marks the pattern-bound variable ctx as a given.

So far, the compiler supports both : and as for given aliases, but we will have to drop one of them. So, which one should it be?

[EDIT] Another reason for : in aliases is the special case of expressing a given whitebox inline function. I.e., the equivalent of

implicit inline def f(using A) <: B = ${...}

With : this would be

inline given f(using A) <: B = ${...}

But with as, we have instead

inline given f(using A) as _ <: B = ${...}

The latter needs another piece of specialized syntax.

3 Likes