What is so-called term inference

This is the only mention of term inference in Programming in Scala 5th Edition (why doesn’t anyone read the book, but keep reading docs instead? :sob: )

21.3 Anonymous givens

Although you can think of a given declaration as a special kind of lazy val
or def, givens differ from these in an important aspect. When declaring a
val, for example, you provide a term that refers to that val’s value:

val age = 42

In this expression, the compiler must infer the type of age. Because age is
initialized with 42, which the compiler knows is an Int, the compiler will
decide the type of age is Int. In effect, you provide a term, age, and the compiler inferred the type of that term, Int.

With context parameters, it goes the other way: You provide a type, and
the compiler synthesizes a term for you to represent that type, based on the available givens, and uses that term implicitly when the type is required. That is referred to as term inference, to distinguish it from type inference. Because the compiler looks for givens by type, and you often don’t need to refer to a given’s term at all, you can declare your given value anonymously. Instead of:

given revIntOrd: Ord[Int] with
  def compare(x: Int, y: Int) =
    if x == y then 0 else if x > y then -1 else 1

given revStringOrd: Ord[String] with
  def compare(s: String, t: String) = -s.compareTo(t)

You can write:

given Ord[Int] with
  def compare(x: Int, y: Int) =
    if x == y then 0 else if x > y then -1 else 1

given Ord[String] with
  def compare(s: String, t: String) = -s.compareTo(t)

For these anonymous givens, the compiler would synthesize a name for
you. In the isort function, the second parameter would be filled in with that synthesized value, which would then become available inside the function. Thus if all you care about is that a given will be provided implicitly as context parameters, you need not declare a term for it.

2 Likes