Syllabus · A3
Sealed hierarchy for a closed set of variants — when to close the set
The idea
Closing a set is a promise, and the compiler holds you to it
corpus/logger has an Appender: one destination for one finished line. Curveball 03 adds a rolling-file destination, and curveballs/03-rolling-appender/budget.json reads reference_diff: 0. A new variant, and no existing file opened.
Now corpus/snake-and-ladder, where SquareEffect is sealed permits Plain, Snake, Ladder. Curveball 01 adds a power-up square and the same instrument reads 6. Four of the six are the seal: one forced case in each of the two switches over the type, and two rows of board data.
Six against zero, so why close a set at all? Because javac named those two switches, by line, before a test ran. Appender gets no such list and needs none, since nothing in the logger asks which destination it holds. Code that asks which variant it has changes the answer. An open set then gives a wrong answer per dispatch site, silently. A closed set gives a build failure per site.
So the question is not whether the list is finite. Finish this instead:
A
<Thing>is an A, or a B, or a C, and nothing else. The next kind gets written by ______.
If the blank is "me, in this file", seal it. If it names another team, a plugin, or a config row, leave the set open even though the list finishes today. A sealed type is the one thing in Java nobody outside its own file can extend.
J11 owns the syntax. This is the commitment, and worked/ shows the arm that throws it away.
Worked walkthrough
NOTES — one word in permits, three compiler errors, and the arm that hides all three
Two trees here, and the difference between them is one word.
src/iscorpus/trip-state-machinecondensed: a sealedTripEventof five records, three dispatch sites over it, and the same three sites written with adefaultarm.src-with-sixth-event/is the same code aftercurveballs/01-driver-cancels, which adds a sixth event.
Run both
From each directory in turn: