Feedback on reconstruction: Hierarchy problems

Reinier Zwitserloot reinier at zwitserloot.com
Fri Aug 14 23:59:43 UTC 2020


If you fully embrace immutable types, and you fully embrace hierarchies,
withers are extremely unwieldy. Imagine the following setup:

record Movie {
    int releaseYear;
    String name;
    Director director;
}

record Director {
    String name;
    LocalDate dateOfBirth;
}

record LocalDate {
    int year, month, day;
}

and a movie:

Movie minorityReport = Movie.of("Minority Report", 2002,
Director.of("Steven Spielberg", LocalDate.of(1946, 12, 18)));

With those examples in place, on to the problem: Let's say for some reason
I need to modify Steven's birth year to 1956 instead. This utter disaster
is the only way:

minorityReport.withDirector(minorityReport.getDirector().withDateOfBirth(minorityReport.getDirector().getDateOfBirth().withYear(1956)));

Oof. I don't immediately see anything in the strawman `with` syntaxes that
would make this any better.

Lombok has recently introduced `@WithBy`, which tries to solve this by
using lambdas. Here's how it would be done with lombok's @WithBy setup:

minorityReport.withDirectorBy(d -> d.withDateOfBirthBy(dob ->
dob.withYear(1956)));

That is one of a number of ways to tackle the problem; one could also
imagine solving this issue purely with syntax. Some strawman syntax could
be:

minorityReport with { minorityReport.director.dateOfBirth.year = 1956 };

which arguably wins the readability syntax, and is the shortest snippet of
them all.

I would like to see some solution (better than the disaster I started out
with) to tackle wanting to make a change to a deeply nested element in an
immutable hierarchy of types.

 --Reinier Zwitserloot


More information about the amber-dev mailing list