Revisiting default values

Kevin Bourrillion kevinb at
Fri Jul 10 18:46:55 UTC 2020

This response is not to the main topic; not trying to send us down a
rabbit-hole but this point is very important to me (as will be clear :-)).

On Fri, Jul 10, 2020 at 11:23 AM Dan Smith <daniel.smith at> wrote:

Bucket #1: Have a reasonable default, as declared.
> - wrapper classes (the primitive zeros)
> - Optional & friends (empty)
> - From java.time: Instant (start of 1970-01-01), LocalTime (midnight),
> Duration (0s), Period (0d), Year (1 BC, if that's acceptable)

Duration and Period: sure.

Instant and the others: please, please put these in a separate bucket. They
can have a *default*, but it is absolutely *not* a "reasonable" default. In
fact many tens (hundreds?) of thousands of bug reports in the last 50 years
of computing have been "why in the world did 1970-01-01 or 1969-12-31 show
up on this screen??"

(Source: my team at Google has invested literally multiple person-years in
an effort to stamp out bugs with how users use java.time, which I kicked
off and have stayed peripherally involved in. I feel this should make our
perspective worth listening to.)

Realize that primitive types having default values *already* causes some
number of bugs today even though we know they are the least-bad category
and that risk is acceptable.

My reason for complaining here is not just about the java.time types
themselves, but to argue that this is an important 4th bucket we should be
concerned about. In some ways it is a bigger problem that Bucket #3 "no
good default", since it is an *actively harmful* default.

For all of these types, there is one really fantastic default value that
does everything you would want it to do: null. That is why these types
should not become inline types, or *certainly* not val-default inline
types, and why Error Prone will have to ban usage of `.val` if they do.

(Tangent of tangent: midnight is an interesting choice of default value for
LocalTime, since I think there are some LocalTimes that so far have *always
happened* in every date and location in history and that's not one of them.
That's not to say any other choice would work, but just to highlight how
wrong it is to have any default value at all.)

> Bucket #2: Could have a reasonable default after re-interpreting fields.
> - From java.time: LocalDate, YearMonth, MonthDay, LocalDateTime,
> ZonedDateTime, OffsetTime, OffsetDateTime, ZoneOffset, ZoneRegion,
> MinguoDate, HijrahDate, JapaneseDate, ThaiBuddhistDate (months and days
> should be nonzero; null Strings, ZoneIds, HijrahChronologies, and
> JapaneseEras require special handling)

Echoing... default seems harmful in every one of these.

Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at

More information about the valhalla-spec-observers mailing list