Yes, I would frame this one as a "lucky near miss", where there's a
removable discontinuity in Rational that permits it to work with a small
amount of extra effort. The author will likely do the appropriate input
checking (and possibly GCD reduction) in the explicit ctor, but the key
is that because of the implicit ctor, the author has to do some
additional checking elsewhere too.
Because it can all be factored through a `denom` accessor *in this
case*, it is not very intrusive, but I am not positioning this as a
general property, as much as "we got lucky with Rational and might get
lucky with other similar cases that are at the boundary."
I think much of the value of the Rational example is not "building a
better Rational", as much as a cookbook example of something that
_almost_ fits the implicitly-constructible mold, and a how-to guide for
how to deal with this flavor of "almost." If we had a few others, we'd
have a cookbook cooking, and that would be a good thing.
On 6/1/2023 1:46 PM, Kevin Bourrillion wrote:
On Thu, Jun 1, 2023 at 10:35 AM Brian Goetz <[email protected]>
wrote:
Rational is unfortunate because the default representation (when
used improperly) can lead to DBZE, but has a sensible default of
zero -- except for that pesky denominator. However, I think this
is a removable discontinuity, where the author can make up for
this with some careful coding:
It helps a bit that you want to canonicalize all 0/n to
/something/ anyway, and rational operations are already busy taking
the gcd and ensuring positive denominator as it is. The need to
internally represent zero as 0/0 probably adds little incremental pain
in *this* case, but there will be others where it does. Still, overall
it seems like a very fine trade-off.
--
Kevin Bourrillion | Java/Kotlin Ecosystem Team | Google,
Inc. |[email protected]