Data Oriented Programming, Beyond Records
Robbe Pincket
robbepincket at live.be
Thu Jan 15 01:28:42 UTC 2026
> We can take advantage of the simplification offered by there being _only_ the
> canonical deconstruction pattern, and allow uses of deconstruction patterns to
> supply nested patterns for any _prefix_ of the component list. So for the
> evolved record R:
>
> case R(P1, P2)
>
> would be interpreted as:
>
> case R(P1, P2, _, _)
>
> where `_` is the match-all pattern. This means that one can compatibly evolve a
> record by only adding new components at the end, and adding a suitable
> constructor for compatibility with existing constructor invocations.
Hi Brian
Love the stuff, except this one. To me I would expect
case R(P1, P2)
to be equivalent to
case R(P1, P2, DEFAULT_C, DEFAULT_D)
Now it does seem unlikely to me at the moment that we can figure out what DEFAULT_C
and DEFAULT_D are supposed to be. Even less so if they are not constants and depend
on other fields.
I also have a question about reconstructors. Given your `Point` and `Point3d`
example carrier classes, what would the following function do?
Point yPlane(Point p) {
return p with { y = 0;}
}
void main() {
System.out.println(yPlane(Point3d(15, 23, 70)));
}
Will this `with` expression always invoke the class inferred in the source code
`Point` and print `Point(x=15, y=0)` or will it depend on the actual type at
runtime `Point3d` and print `Point3d(x=15, y=0, z=70)`
Kind regards
Robbe Pincket
More information about the amber-spec-observers
mailing list