User model stacking: current status
Brian Goetz
brian.goetz at oracle.com
Thu Jun 16 19:21:42 UTC 2022
Quick observation: the default value of `String!` is less dangerous to
allow free, because its "null", and the user can already freely make
nulls. Whereas the default value of `Instant` is not something the
user can get their hands on, if they can't observe fields of type
`Instant.val` during initialization. So the problem may be less severe
for B1.
On 6/16/2022 3:16 PM, Kevin Bourrillion wrote:
> On Wed, Jun 15, 2022 at 12:01 PM Brian Goetz <brian.goetz at oracle.com>
> wrote:
>
> OK, let's say for sake of argument that "well, that's what you
> opted into." Non-atomic means no one can count on cross-field
> integrity; don't select non-atomic if you have invariants to
> protect. OK fine. And let's flip over to what T! means.
>
> Let's say that T! is a restriction type; it can take on the values
> of T, except for those prohibited by the restriction "t != null".
> So, what is the default value of `String!`?
>
>
> I'd like to slightly rephrase your question to "What do we do when we
> need a default value /for/ `String!`", because I don't like the
> framing that suggests that a default value is an inherent property /of
> a type/ itself. (I've no idea what type theorists would say.)
>
> And we were talking about bucket 2, a "value class with no good
> default" so I'll substitute `Instant!` instead of `String!` for most
> of this.
>
> So, what to do when we need a default value for `Instant!`? I guess
> "just blow up" is a non-option because every field has to start off
> somewhere. So I guess we have to answer "it's `fromEpochMilli(0)`
> because it can't be anything else, but we're going to do what we can
> to prevent its users from depending on that fact." Definitely, making
> an explicit value type that's nonpublic is a way to do just that. Is
> there a more surgical way to do it?
>
> One easy way to get surgical is to have OpenJDK just stop worrying
> about the bad-default-values problem, and let aftermarket static
> analyzers like ours take up that mantle. We can have an annotation to
> mark classes like Instant, and we can issue warnings when we see bogus
> usages (some of which we warn on anyway). In fact, if you do exactly
> what you're planning (so flip back from Instant! to Instant.val, and
> give the val type an access modifier), I guess we might end up doing
> this in Error Prone anyway, so that people can make their value types
> public safely. That would feel actually totally fine to me. And in the
> `Instant!` world, there's not much to hang a modifier on, but we
> wouldn't care if we were doing this checking anyway.
>
> You don't need to explain that "we'd rather release language features
> that /don't/ need aftermarket tools to use safely", I know it. But it
> is just a platitude really. I think that any language design
> expressive enough to users do good things will inevitably be
> expressive enough to let them do bad things too; static analysis
> always has a crucial role to play imho. And of course it is always the
> trio of language/libraries/tools together that drives the user's
> ultimate experience.
>
> (Now changing back to `String`, a bucket-1 class, I've been expecting
> it will be much longer before we'd roll out !/? to those types, but
> when we do, I think your particular question comes out better. "What's
> the default for `String!` when we absolutely must have one?" Well,
> when we must we must, so we must commit null pollution. We try to
> issue enough of the right warnings to live with the fallout. If we
> ever make a transition like this, we have to level expectations; I'm
> convinced null pollution will be a part of all of our lives, more so
> than heap pollution of the generics kind ever was, but I'm also still
> optimistic that it will still be worth it. You could say that today we
> live with 100% null pollution...)
>
>
> For locals, it's pretty clear we don't have to answer, because
> locals cannot be accessed unless they are DA at the point of
> access. But for fields, we have a problem -- and for arrays, a
> bigger one. We can try to require that fields have initializers,
> but there are all sorts of situations in which a field can be read
> before its initializer runs.
>
>
> ... which situations already lead to bad behavior / puzzlers as it is.
> We might miss a warning we'd rather have been able to give, but life
> goes on?
>
> And arrays are much worse.
>
>
> Arrays in general, or just the one single construction path `new
> TheType![size]` (or `new TheType.val[size]`)? I would just say please
> give us new Arrays methods or syntax that create and fill at once, and
> we'll get busy clamping down on everything else.
>
>
>
> On 6/15/2022 2:10 PM, Kevin Bourrillion wrote:
>> On Wed, Jun 15, 2022 at 10:51 AM Brian Goetz
>> <brian.goetz at oracle.com> wrote:
>>
>> - If we spelled .val as !, then switching from P[] to P![]
>> not only prohibits null elements, but changes the layout and
>> _introduces tearing_. Hiding tearability behind "non-null"
>> is likely to be a lifetime subscription to Astonishment
>> Digest, since 99.9999 out of 100 Java developers will not be
>> able to say "non-null, oh, that also means I sacrifice
>> atomicity."
>>
>>
>> Well, that's what you opted into when you... wait a minute...
>>
>> The link you probably want to attack is this last one, where
>> you are likely to say "well, that's what you opted into when
>> you said `non-atomic`; you just happen to get atomicity for
>> free with references, but that's a bonus."
>>
>>
>> Your Kevin's Brain Emulator has gotten pretty decent over time...
>> check whether the next things it said were these (probably so):
>>
>> A good clean Basic Conceptual Model For Novices is allowed to
>> have a bunch of asterisks, of the form "well, in $circumstance,
>> this will be revealed to be totally false", and that's not always
>> a strike against the model. How do we discern the difference
>> between a good asterisk and a bad one? How common the
>> circumstance; how recognizable as /being/ a special circumstance;
>> how disproportionate a truth discrepancy we're talking about; etc.
>>
>> I know I've said this before. If I'm in a class being taught how
>> this stuff works, and the teacher says "Now unsafe concurrent
>> code can break this in horrible ways, and in $otherClass you will
>> learn what's really going on in the presence of data races" ... I
>> feel fully satisfied by that. I know I won't get away with
>> playing fast and loose with The Concurrency Rules; I'm not
>> advanced enough and might never be. (Many people aren't but
>> /don't /know it, and therein lies the problem, but do we really
>> have much power to protect such people from themselves?)
>>
>> I could be wrong, but I suspect this kind of viewpoint might be
>> more common and respected in the wider world than it is among the
>> rarefied kind of individuals who join expert groups, no offense
>> to anyone here meant. You're always going to see all the details,
>> and you're always going to /want/ to see all the details. The
>> general public just hopes the details stay out of their way. When
>> they don't, they have a bad day, but it doesn't mean they were
>> better served by a complex model that tried to account for
>> everything.
>>
>>
>> --
>> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com
>
>
>
> --
> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220616/d800ed7f/attachment-0001.htm>
More information about the valhalla-spec-observers
mailing list