(((•)))
tech.interfluidity.com
a notebook by steve randy waldman
→ See also top, archive, subscribe, drafts blog, interfluidity main
2024-02-06 ⇒

# What does private mean at package level in Scala 3?

TL; DR:

- `private` declarations at a top-level scope of a package in Scala 3 are equivalent to a `private[pkg]` in other contexts.
- They are accessible to everything within the package and its subpackages, but nothing else.

In Scala 2, to place a declaration at the "package" level, one would define a "package object":

    package top

    package object pkg {
      private val Hush = 0
      val Loud = Int.MaxValue
    }

Given this

- one might refer to `Loud` from anywhere with fully-qualified name `top.pkg.Loud`
- `import top.pkg._` would pick it up
- inside the package `top.pkg` one coul refer to it simply as `Loud`

So far, so intuitive.

In Scala 2, the semantics of `private val Loud` was also intuitive. A `package object` is just an `object`. A `private` member of an `object` is only visible within that `object`'s scope. While the Scala compiler does some magic to make nonprivate declarations more broadly visible, access to `private` members of the `package object` was restricted to the `object` in the ordinary way.

But Scala 3 introduces "naked" top-level declarations, which I find I use constantly.

So the declarations above might translate to:

    package top.pkg

    private val Hush = 0
    val Loud = Int.MaxValue

There is no `object` scope! So what does private even mean in this context.

I could imagine four possibilities:

1. `private` to a virtual object scope constituted of all top-level declaraions
2. `private` to the top-level of the current compilation unit (i.e. file)
3. `private` to the current compilation unit (including nested scopes)
4. `private` to the package as a whole, i.e. the same as `private[pkg]`

Playing around, it looks like #4 is the winner.

A `private` top-level declaration seems visible to any code in the package, even if defined in other files or directories. It is visible from anywhere in the `pkg` or subpackages of `pkg`.

So now I know! And so do you!

← Style-by-mail in feedletter
↑↑↑
c3p0 and loom →