# The variant set the compiler keeps checking

`corpus/file-system` has two kinds of thing that can sit at a path, and one method that asks which
kind it got. Written the way you would write it first:

```java
if (node instanceof FileNode) {
    return EntryKind.FILE;
}
return EntryKind.DIRECTORY;
```

That works for exactly as long as there are two kinds. Then curveball 01 arrives: add shortcuts.
Now there are three, and the code above still compiles clean and reports a shortcut as a
`DIRECTORY`. Nothing warns you, in that file or any other.

`std::variant` with `std::visit` is the tool you already have for this, and it does check. Java's
version drops the visitor and keeps the check. The set is named once:

```java
sealed interface Node permits FileNode, DirectoryNode {}
```

Add `SymlinkNode` to that `permits` list and change nothing else:

```
Nodes.java:14: error: the switch expression does not cover all possible input values
        return switch (node) {
               ^
1 error
```

One error, at the file and line that now has a decision to make.

The third piece is `record`. A shortcut is nothing but the path it points at, so its declaration is
`record SymlinkNode(String target) implements Node {}`, with `equals` and `hashCode` arriving
inside it. Eight lines in the corpus become one.

So the three features are one technique. The seal closes the set, records make its members cheap to
write, and the switch is where the compiler cashes the promise in.

Reach for it when you can name every member today and want to be told the day that stops being
true. `var`, `Optional` and text blocks are in `from-cpp.md`.
