Possibility to spread sealed trait to different files

Would it be technically feasible for sealed[packagename] to mean the sealing was scoped to packagename within the current compilation context?

So you could still do something like this:

src/main/scala/com/foo/models/SealedTrait.scala
src/main/scala/com/foo/models/SealedTraitCommon.scala
src/main/scala-2/com/foo/models/SealedTraitImpl.scala
src/main/scala-3/com/foo/models/SealedTraitImpl.scala

But it would still reject extending it from outside the library or in a different project in a multi-project build?

1 Like

Given that we have incremental compilation, it is not technically feasible. When incrementally recompiling, the compiler only sees a subset of the files comprising a project.

1 Like

I don’t understand why, but I trust your judgment that it’s harder than for private and protected.

“Technically infeasible” seems a bit hard to believe, however. In fact, it is almost possible to simulate package-level sealing within Scala 3, which seems to imply that it is not fundamentally incompatible with incremental compilation.

Sealing itself (preventing extension) is not the issue. But we can’t list the children, which we need for exhaustivity checking.

(If you don’t need/want exhaustivity checking, making the constructor private[pkg] is enough).

2 Likes

Oh, so it’s about the exhaustivity checking that sealed is supposed to provide. Sorry, I should have read the previous comments more thoroughly.

So it wouldn’t be an issue if sealed[packageName] simply did not provide that added benefit in those cases.

When a match on such a sealed type could not be checked to be exhaustive, a warning could be issued at the site of the match expression, explaining that, unfortunately, that sealed type cannot be checked for exhaustivity due to its scope.

But I see how providing weaker semantics for sealed in these cases might be controversial, even though such a weaker sealed would still be very useful to avoid unwanted extensions (complementarily to private and protected).

Something to consider: the Java implementation of sealed has a corresponding permits clause that lists the permissible extensions.

IIUC Java still doesn’t allow multiple top-level classes/interfaces in the same file, so this was an understandable choice on their part, but if we chose to follow suit, we could relax the same-file restriction as well.

2 Likes

It sort of would be an issue, because exhaustivity checking is one of the major benefits of sealed hierarchies. Otherwise, as @sjrd pointed out, it’d would be enough to just make the constructor package private.

1 Like