To make scala.collection.immutable.List accessible without import, package object scala defines both a type alias and “term alias”:
type List[+A] = scala.collection.immutable.List[A] // Transparent
val List = scala.collection.immutable.List // Opaque
This is a commonly used technique – in scala, scala.Predef, and in many libraries. So far so good. However, the former alias is de jure, whereas the latter - only de facto. The type is transparent, the val is opaque - you shouldn’t look at the right-hand side, and even if you do, there’s no (formal) guarantee that it will stay the same.
This is not a problem for compiling and running the code, but is a problem for editing the code - how an IDE would know that the List term is actually scala.collection.immutable.List? And vice versa: if you look for usages of scala.collection.immutable.List, you probably also want to see usages of List. We may add heuristics, but that’s hardly elegant.
While we now have both transparent and opaque type alias members (in Scala 3), there’s no way to define a transparent term alias. Although imports (inlcuding ones with renaming) are transparent (if you navigate to an imported name, you navigate to the defintion, not to the import statement), they are not members, and so are not “exportable” outside the scope:
import scala.collection.immutable.List // Not exported
exports are “exportable”, but they are not transparent (?):
package object scala {
export scala.collection.immutable.List // Opaque
}
Interestingly, a val is effectively transparent if it’s a constant value definition – a final val without a type annotation and with a constant expression as the RHS. However, constant expressions don’t seem to include objects (?), which is strange, given how this works in the literal-based singleton types. Even though object is effectively lazy val, it’s transparent, because the RHS is synthesized by the compiler.
Can, in principle, the language treat a reference to an object as a constant expression (at least for top-evel objects), and the standard library make scala.List, as well as other wanna-be-transparent term aliases, final? Then Scala code can have transparent term aliases, which can be correctly handled by IDEs. (The key here is the semantics; whether the compiler replaces LHS with RHS in the bytecode, as it does with literals, is an implementation detail.)
