As the topic has turned to how Valhalla will extend into the language syntax, we've had a significant uptick of postings on the valhalla-spec-comments list.

As a public service announcement, let me remind people of the role of the -comments list:

 - Postings should be self-contained; think "suggestion box."
 - The most helpful sort of comments center around providing information that is genuinely new to the EG ("you missed this case".)  The least helpful are those that are entirely subjective reactions ("I don't like the .val syntax".)  - When there is an active discussion, it is usually best to let it play out before commenting.  EG discussions often operate on a longer time scale, and take a more meandering path, than the design discussions you may be used to, but there is a method to the madness.  - It is not a general mechanism for "I would like to inject a reply into the EG discussion."


On to the mail bag.

 - https://mail.openjdk.java.net/pipermail/valhalla-spec-comments/2022-April/000028.html (Quan Anh)  - https://mail.openjdk.java.net/pipermail/valhalla-spec-comments/2022-May/000032.html (Tim Feuerbach)  - https://mail.openjdk.java.net/pipermail/valhalla-spec-comments/2022-April/000030.html (Mateusz Romanowski)  - https://mail.openjdk.java.net/pipermail/valhalla-spec-comments/2022-April/000031.html (Izz Rainy)

Quan raises two questions / observations:

 - Could primitives explictly choose the name of their "box"?
 - Isn't the atomicity question overblown?

We considered the "choose both names" approach early in the process (in fact, in a much earlier version, there were two declared classes.)  But since naming things is hard, asking the user to name two things is harder, and it also asks readers to carry around the mapping of "X is the box of Y."  (It is bad enough that the existing primitives have this problem, and that the box of `int` is called `Integer`, not `Int`.)

It is very tempting to reach this conclusion about atomicity, but IMNSHO this is a siren song.  Since bad things can only happen when the program is broken (data races), it seems reasonable initially to blame the user for their broken program.  But unfortunately, I think this is too easy (though I still understand the temptation.)  Users are used to the idea that constructors establish objects with their invariants intact; seeing instances that don't obey invariants enforced by constructors would be astonishing.  (This is the biggest criticism of serialization; that it allows the integrity model of the language to be undermined in ways that are not visible in the source code.  More of that would not be good.)  Further, people have internalized the notion that "immutable objects are thread-safe" (and this is a really good thing for the ecosystem to have learned); we break this at our peril.  (Further, evil actors can maliciously create torn values through deliberate races, and then inject them into innocent victim code.)


Tim asks whether the non-nullability of the .val projection is the same feature as the non-nullable `String!` that people have been asking for for years.  Indeed, this is a question that has been at the back of our mind for most of this project.  While we are unsure that we can spell `.val` with a bang, we also are apprehensive about painting ourselves into a future where we are tempted to have both.

The unfortunate answer is that they are not the same (though this doesn't mean they can't be unified.)  For Point.val, null is *unrepresentable*; for `String!`, this would surely erase to `String`, so the possibility of null pollution is still present.  (As a side note, this means that migrating `Point` to `Point.ref` is binary-incompatible, while `String` to `String!` is binary compatible (though may be source incompatible.))  It is still an open question whether the natural interpretation of `String!` is to erase null checks at compile time, or to reify runtime checks at each assignment.  I plan to have some more in-depth discussions about this, but having them now would divert us from solving the more immediate problems.

(Tim also observes that, to the degree that primitives are the only way to get truly non-nullable types, people will abuse them as a way of "sticking it to the stupid compiler" for not giving them general non-nullable types, shooting other people's feet in the process.  Sadly true; developers are their most dangerous when they think they are being clever.  But this only underscores the importance of making surprising properties (like non-atomicity) explicit, rather than having them come for the ride with other things.)

Reply via email to