Hi Scala community!

This is a request for comments for the proposal to add top-level definitions in Scala 3 as a simpler replacement for package objects. Dotty implementation is described here.

Summary

Any source file may contain top-level definitions that go into the enclosing package:

package p type Labelled[T] = (String, T) val a: Labelled[Int] = ("count", 1) def b = a._2 case class C() implicit object Cops { def (x: C) pair (y: C) = (x, y) }

The compiler generates synthetic objects that wrap top-level definitions falling into one of the following categories:

all pattern, value, method, and type definitions,

implicit classes and objects,

companion objects of opaque types.

If a source file src.scala contains such toplevel definitions, they will be put in a synthetic object named src$package . The wrapping is transparent, however. The definitions in src can still be accessed as members of the enclosing package.

Motivation

Package objects have proven fragile and have several downsides:

only one package object definition per package, even though some top-level definitions would make sense to live in different files

a trait or class defined inside a package object is different from one defined inside the package itself and can lead to surprising behavior

unclear semantics w.r.t to the scope of what can be inherited (see #441)

Top-level definitions solve these downsides, but they don’t have the ability to inherit definitions from another trait or class. That can be easily worked around by using a regular object and importing all it’s members.