Repository navigation
Data-oriented programming: sealed + records + pattern matching switch - #102
Merged
Merged
Conversation
Test Results276 tests +2 273 ✅ +2 6s ⏱️ ±0s Results for commit f486fcb. ± Comparison against base commit e635139. This pull request skips 1 and un-skips 1 tests. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What you'll learn
sealed interfaceplus a closed set ofrecordimplementations models data without inheritance tricksswitchwith record patternswhenguard lets you special-case a pattern before falling back to the general oneswitchexhaustiveness a compile-time guarantee instead of a runtime hopeWhy it matters
This combination (sealed types + records + pattern-matching switch) is the core of "data-oriented programming" in modern Java: it replaces
instanceof/cast chains and the visitor pattern with exhaustive, compiler-checked switches, so adding a new case in the data model is caught immediately everywhere it's handled.Read more
Quiz
Given
and
evalswitching withcase Mul(Const c, Expr right) when c.value() == 0 -> 0;before the genericcase Mul(Expr left, Expr right) -> eval(left) * eval(right);— doeseval(new Mul(new Const(0), new Add(new Const(1), new Const(1))))evaluate theAddbranch?Answer
No. The guarded `Mul(Const c, Expr right) when c.value() == 0` pattern matches first and returns `0` immediately, so `eval` is never called on the `Add` subexpression — multiplying by a constant zero short-circuits without evaluating the other operand.Note: this sandbox only has JDK 21 installed, and its network policy blocks both the Gradle toolchain auto-provisioner (foojay) and a direct JDK 25 download, so
./gradlew :FirstSteps:testcould not be run locally for this PR. The code was reviewed carefully against the language spec; CI (which has JDK 25) will verify it compiles and passes. Marking as draft until that's confirmed.Closes #89