Cool new experiments in Type Classes

Mark "Justin" Waks
2 min readJan 8, 2024

Howdy, all — been a while since the roving Dotty Reporter has had much to say. Now that Dotty is long since Scala 3, most of the work has moved from “invent new features” to “refine the details”. (Of which there is a lot: anyone who thinks the Scala project has gone quiet should take a look at the number of PRs per day in the repo.)

But I’m still watching that repo, looking for anything interesting that comes across, and today I noticed this PR, and particularly this associated document that goes with it.

It’s well worth a read — it’s basically Martin taking a bunch of the feedback that’s been coming in about the expressivity of type classes, stepping back, and seeing how things could be improved.

This one is not just looking at small, conservative tweaks: it’s major changes to the surface syntax of type classes, on both the given and using sides as well as the declaration of the type classes themselves, to wind up with something considerably more ergonomic.

Just calling out one or two of the highlights —

The biggest deal is a new variation of how you declare a type classes, so that you can do so with a magic Self member instead of just type parameters. So instead of this:

  trait SemiGroup[T]:
extension (x: T) def combine(y: T): T

you could also say this:

  trait SemiGroup:
type Self
extension (x: Self) def combine(y: Self): Self

That’s a big deal, and the document goes into some of the implications. I adore this idea, since it is likely to produce clearer syntax in a lot of places. But it’s a big change in what type classes look like.

There are also new is and as soft keyword usages, so that you could write given like

given Int is Monoid as intMonoid:
...

and the ability to use type names as synthesized terms for their context bounds, like:

 def reduce[M: Monoid](xs: List[M] =
xs.foldLeft(M.unit)(_ `combine` _)

(I have slight qualms about the latter being a little misleading to novices, since it conflates the type M and the type class instance at the call site, but I have to admit that it’s nicely concise and clear.)

Anyway, the document is well worth a read, if you’re interested in possible future directions — I think that, by and large, these ideas look great.

Usual caveats: this isn’t stuff that’s coming imminently; it isn’t even a SIP yet. This is just experiments that Martin is messing around with, to see how the language might be improved. But these go on my “I hope they happen” list — if they don’t turn out to have sharp corners, and can be done in a decently backward-compatible way, they generally look like wins.

--

--

Mark "Justin" Waks

Lifelong programmer and software architect, specializing in online social tools and (nowadays) Scala. Architect of Querki (“leading the small data revolution”).