The opposite of opaque types - transparent type aliases

I very often use type aliases as I would local variables/values: to shorten a type name, simplify/shorten the signature of a complex higher type, extract a commonly used type term, or to guide the type inferer/create curried type aliases. In most cases, I view them as implementation artifacts: I do not want to be commited to supporting them and would rather client code does not use them. For example:

class Witness[A, B, C]
given w = new Witness[Alpha, Beta, Gamma]
type Alpha
type Beta
type Gamma //only here to expand the type name and somewhat justify the example:

trait Demo {
   type MyWitness = Witness[Alpha, Beta, Gamma]
   def a(using MyWitness) = ???
   def b(using MyWitness) = ???
   ...
}

If a type is used often enough, and reduces a type at its usage place considerably, there is a good reason for an alias such as MyWitness. In fact, if a type signature begins to reach or exceed a line character limit, it is arguably necessary. Still, given choice, especially in case of givens (and other types I do not expect users to refer to often), I would rather avoid introducing it to the public namespace. We already have a precedent of ‘invisible but visible’ in implementation inheritance, i.e. private[pckg] traits, which might be extended by public traits, exposing the inherited interface, but not the base type symbol.

This seems like a very small change to the language, without a serious impact on anything. The question is, do others see it as something genuinly helpful?

2 Likes