uot;see" that there is only one implementation, so why
shouldn't they be able to auto-cast it.
On Fri, Oct 23, 2020 at 11:25 AM Brian Goetz <mailto:brian.go...@oracle.com>> wrote:
No one bit on this, but let me just point out a connection that
may help motivate this: s
umption is later invalidated, the compiler can catch save us from
ourselves. A cast would push assumption failures to runtime, where they
are harder to detect and potentially more costly.
On 10/9/2020 11:16 AM, Brian Goetz wrote:
Here's an idea that I've been thinking about for a few
FTR: this was largely a "for consistency" decision, because nestmates
does it the same way. (Which is to say, it was a deliberate suboptimal
choice aimed at minimizing the number of API idioms that users of
reflection had to deal with.)
On 10/23/2020 11:27 AM, Gavin Bierman wrote:
Just to fo
This seems to cleverly sidestep the issue of pattern totality (by
outlawing the total type pattern on the RHS of instanceof for now) and
leave us room to go either way in the future. So, +1.
I think you can drop
If the value of the/RelationalExpression/is the null reference, then the
result
Here's an idea that I've been thinking about for a few days, it's not
urgent to decide on now, but I think it is worth considering in the
background.
When we did expression switch, we had an interesting discussion about
what is the point of not writing a default clause on an optimistically
to
There's a simple (though unsatisfying) answer to your student's
question: because catch is special. (But this answer belies an
important point: ad-hoc syntactic "patches" like multi-catch may be
satisfying in the short term, but they always beget a flurry of "for
consistency" arguments, which
From a user perspective, will the new terms encourage the right mental
model for when value types get flattened (or not)? As an EG, early on
we spent a lot of time discussing "flattened" vs "flattenable" and
trying to guide users to the view that this is a VM-level decision and
not a guarante
how it behaves on stack, it behavse like a primitive type ,the "pass by
value" Dan is talking about
- how it behaves on heap, it behaves by inlining itdelf in its container.
So they are a primitive inlining class :)
Rémi
De: "Brian Goetz"
À: &
There's always been a duality between whether inline classes are "faster
objects" or "user-programmable primitives." Until now, we're been
erring on the "faster objects" side of the line, but after some thought,
we think that flipping the perspective will better frame what these new
features a
Overall I really like the simplification of merging pattern variables
into locals, just with more complex scopes. The revised definition of
effective finality is very natural. This will all pay off further when
we add pattern assignment statements.
The obvious caveat is that you have to sear
I think we're reaching diminishing returns here. Here's how I would
think about this:
- We do an applicability check to see if the annotation _could apply_
to any of the things we are going to generate. If the target isn't one
of param/method/field/component, we issue an error.
- If there
Received on the -comments list.
A similar comment was made in the comments of this SO issue:
https://stackoverflow.com/questions/64131753/why-is-the-variable-arity-record-component-not-inferred-with-custom-constructor
Forwarded Message
Subject:Records feedback
Date:
Secondarily, perhaps totality isn't the right term; maybe we need a
word for "good enough to satisfy the checker", where the checker is
generous in letting us be sloppy regarding silly values.
In searching for names for "total enough to satisfy the type checker",
it briefly occurred to me t
In 6.1, you allude to implicitly declared fields of a record, but not
implicitly declared accessor methods or constructors. Is this an omission?
In 8.1.1, I see local records and enums (and they are static), but I
don't see local interfaces. I assume we are saving those for a future
pass (al
Minor nit:
Appendable foo(Appendable bar)
should be
A foo(A bar)
That way, if you say
hex.formatHex(aStringBuilder, bytes)
.foo()
where foo() is a method on StringBuilder but not on Appendable, it will
still work as expected.
On 9/28/2020 11:32 AM, Roger Riggs wrote:
A
with the possible temporary exception of the three primitive types not
currently permitted
I believe, there are four of them: boolean, long, double, and float
RIght.
#2 Disallowing switch expressions inside guards
And worse if we allow switch expressions inside guards, which we shouldn
Thanks Eddie. Indeed, I think these could be clarified.
We should start by putting out the motivation for why the "totality
checker" is satisfied with less than full coverage -- this is because we
want to be nice, and not pedantically ask users to write case clauses
for "silly" cases that pro
ong-term battle against old
syntax - note that at some point in Java 7 we dropped support for
C-style array syntax on varargs decl - e.g.:
void m(int n, String... args[])
See:
https://bugs.openjdk.java.net/browse/JDK-6569633
Maurizio
On 24/07/2020 13:43, Brian Goetz wrote:
As we've added n
think that would be a very bad idea.
On 9/13/2020 3:10 PM, fo...@univ-mlv.fr wrote:
*De: *"Brian Goetz"
*À: *"Remi Forax"
*Cc: *"amber-spec-experts"
*Envoyé: *Diman
I don’t quite get the leap from “no constant patterns” to changing
the syntax of deconstruction patterns, but in any case, we
definitely don’t want this (and in fact, for the same reasons
cited in the section on constant patterns, and others.)
if case Point(x, y) can not mean i
So I’m not sure how much we can learn from this particular
example. Maybe you have a better one?
No a better one, just another one, you want to be able to declare a
deconstructor abstract by example on an interface
interface Map {
interface Entry {
public abstract deconstru
> if we don't have constant pattern, it may also means that the type of a bound
> variables can be implicit too.
> i.e. case Point(x, y) having the same meaning as case Point(var x, var y)
> like with lambdas.
I don’t quite get the leap from “no constant patterns” to changing the syntax
of deco
> The sentence "Guarded patterns should be ignored entirely for purposes of
> computing totality." implies that if two patterns that only differ from one
> having a where and the other have not it's not valif to have them both in a
> switch seems wrong for me.
I suspect you have drawn the wrong
>> - While instance members, they are not inherited (just like constructors)
>
> At least you want a deconstructor to be overrideable (which is not fully
> equivalent to being inherited).
> A deconstructor is for allowing encapsulation so the world projected by a
> deconstructor may have a littl
> I think that Pattern matching for `instanceof` should stay in the preview
> feature state because as we discuss about how pattern matching works,
> there is a strong feeling that both features should be aligned, so i see
> Pattern matching for `instanceof` being promoted as a non-preview featu
Sure, and what I want to avoid is having a requirement of the JVMS (not
even the JVM!) turn into a user-visible artifact. Having a public class
whose spec says "I exist entirely for the implementation of X" seems
likely to be distracting.
Does it have to be nominal? Can we say "`new j/l/Obje
Remi points out that the System class (or, say, Objects) is a place we could
put a factory method if we want one but don't want to risk adding it to Object.
Looking at it from the other direction, I am not sure having a nominal
SimpleIdentityObject class adds much value. You can of course wri
actually occurs in real code
On 8/26/2020 11:00 AM, Brian Goetz wrote:
Proposed: An `instanceof` expression must be able to evaluate to both
true and false, otherwise it is invalid. This rules out strongly
total patterns on the RHS. If you have a strongly total pattern, use
pattern assignment instead.
I have updated
https://github.com/openjdk/amber-docs/blob/master/site/design-notes/type-patterns-in-switch.md
based on our discussions.
> - Is either total or partial. Deconstruction patterns are total; other
> patterns we'll be able to express later, such as `Optional.of(var x)`, are
> partial.
While I don’t want to get into a deep dive on declared patterns now, let’s just
say that they’ll exist and they’re important (Opti
The deconstruction pattern is a special case of type pattern
No, it isn't. I think you want it to be, but it isn't.
, both starts by doing a typecheck (an instanceof), what is different
is how they bind variables after the typecheck.
So having the type inference on the type used by the typ
> I disagree with that rational because a deconstructor is an instance method,
> so you need to do an instanceof first,
> said differently P(...) is a deconstruction pattern which is equivalent to
> instanceof P p && var values = p.__name_of_the_deconstructor()
At root, I think a lot of your fr
I agree with Alan. While I believe that Rémi is correct insofar as you
can write “var” in place of a type in any type pattern “T x”, in a
deconstruction pattern “P(...) [d]” the occurrence of P is not a type;
rather, it names a deconstructor.
Exactly right.
It does so happen that right no
No. Definitely not.
I don’t even know what you would propose that to mean! I have a guess, but I’m
order for that guess to even make sense, it would assume a model for how
patterns are declared that is very different from what we have now.
There are about a zillion places where you can
So I appreciate the brainstorming, but personally don't really see a problem
that needs solving here. (Other than the syntax bikeshed.)
Agreed, it was worth poking around the corners with a flashlight, but
the exploration brought me back to this point too. (If we even need it
at all.)
Some
rn statement switches won't be common, but I'll have to think
about it. It is definitely a bigger mental shift for users about what
switch means.
On 9/3/2020 2:16 PM, Brian Goetz wrote:
That came up in the expression switch exploration. The thinking then,
which I thin
sn't total any more, but
your remainder rejection goes away. I don't like it, but this reframing
might point to a slightly different way to say "I'm assuming totality,
tell me if I'm wrong."
On 9/4/2020 2:06 PM, Brian Goetz wrote:
I bring this up again not to defe
I bring this up again not to defend the syntax, but to underscore a
more important point: that we thought at first that “sealing” switches
was about asserting totality and enlisting the compiler’s aid in
verifying same, but as we worked through the cases, and discovered
there were more cases
I agree with the “unpleasant asymmetry” part, but I’m not sure its fair to call
it arbitrary. The original design of switch statements deliberately embraced
partiality, for non-arbitrary reasons; the design of expression switches
deliberately embraced totality, again for non-arbitrary reasons (
, or never.
On 9/3/2020 3:30 PM, fo...@univ-mlv.fr wrote:
----
*De: *"Brian Goetz"
*À: *"Remi Forax"
*Cc: *"amber-spec-experts"
*Envoyé: *Jeudi 3 Septembre 2020 20:16:10
*Objet: *Re: [pattern-switch] Opting into totality
That came up
Indeed, after serialization, statements probably go next on the list of
"gifts that keep on giving." Languages that avoided this mistake have a
leg up on languages that didn't.
On Sep 3, 2020, at 2:16 PM, Brian Goetz <mailto:brian.go...@oracle.com>> wrote:
That c
{}".
This is an incompatible change with the codes written since Java 14 so
it's a limited incompatible change.
Perhaps the main blocker is admitting that we were wrong.
Rémi
----
*De: *"Brian Goe
The "lacks a no-arg ctor" is new and interesting. I think what you're
saying is that having an explicit no-arg ctor with an empty body is a
more stable signal of intent than an implicit one? I can see that.
Shouldn't the non-empty body one be "declares any constructor with a
non-empty body",
This sounds mostly in line with what I was expecting. Some minor
comments inline.
API changes
- Add a java.lang.IdentityObject interface. The interface has no members (don't
want to disrupt method resolution, etc., in any way). The javadoc, for
information purposes, describes the behaviors
Sorry, I got my examples mixed up. I'll try to reconstruct what I was
saying.
On 9/1/2020 1:27 PM, Dan Smith wrote:
On Sep 1, 2020, at 8:22 AM, Brian Goetz wrote:
But, there is a subtle difference between
switch (x) {
case FOO: ...
}
and
sealed swit
On 8/31/2020 9:56 PM, Dan Smith wrote:
A competent programmer will definitely need to be able to answer the question
"should I add 'sealed' to this switch?" I'll take a stab at enumerating all the
cases:
- A switch statement with a 'default' case: doesn't matter. The language
already supp
Anyway, what I think you're really after is a way for the programmer to assert
that silently falling out of this switch is unexpected. And 'sealed switch'
(however expressed syntactically) is the tool you need to do that. (Let's not
dive into aspects of that feature here, though, there's ano
It's unclear whether your "some remainder" is allowed to be empty. (There was
some discussion earlier about outlawing 'default' in the equivalent of a sealed switch.)
I hope full totality is fine—an expression switch, implicitly 'sealed', of course permits
a 'default' clause.
Yes, remaind
Given that if there is a default it's already a sealed switch and that
i can add a default to make it a sealed switch,
i struggle to see where to use a classical statement switch and where
to use a sealed switch ?
It feels like we're going in circles :)
One point here is that total switches
I'm still thinking it's worthwhile to change the behavior of enum switches to
throw the same thing as sealed class switches.
I don't necessarily think this is terrible, but see inline.
- ICCE is arguably just wrong. It's not an incompatible change to add an enum
constant to an enum decl
ults after 25 years often makes things worse. The benefit has to be
super-huge to justify the next few years of confusion. Here, I don't
see it.
On 8/31/2020 3:57 PM, fo...@univ-mlv.fr wrote:
--------
*De: *"Brian
The answer is twofold; one is a correctness argument, and the other is a
practical one.
1. Box(null) is part of the remainder of `case Box(Bag(var x))`, and
should be thrown on if the switch is total. But ICCE is not an accurate
description of what happened here; there has not been an incomp
ception for all the
existing idioms, and not confuse the users too much", I think that would
be taking it too far.
On 8/31/2020 11:17 AM, Remi Forax wrote:
*De: *"Brian Goetz"
*À: *&
on unhandled null remainder;
- Throw UnexpectedFrogException on any other unhandled remainder.
On 8/28/2020 9:18 PM, Brian Goetz wrote:
And for all this complex analysis we get... some different exception
types? Doesn't seem like a worthwhile trade.
As I've mentioned already, I
remainder; synthetic throwing cases are inserted for the remainder.”
> On Aug 31, 2020, at 9:25 AM, Brian Goetz wrote:
>
> I think this is the main open question at this point.
>
> We now have a deeper understanding of what this means, and the shape of the
> remainder.
I think this is the main open question at this point.
We now have a deeper understanding of what this means, and the shape of the
remainder. Totality means not only “spot check me that I’m right”, but also “I
know there might be some remainder, please deal with it.” So totality is not
mere
languages that have similar features) before we start to make claims about what
is “natural” or “confusing.” Otherwise, we’re just starting the race with
bricks tied to our feet.
> On Aug 30, 2020, at 11:07 AM, Brian Goetz wrote:
>
> Sorry, but I don’t find this example that compelli
Yes, this looks very much like a PoC I did once too. The upshot of that
experiment is that operators like AND, OR, nesting, and guarding are amenable
to implementation as combinators, which is nice.
> To deal with the deconstruction, i need 3 primitives
> - deconstruct(Object value) that call
teresting!
>
> How about
>
> try {...}
> catch(Ex1 | Ex2 e) {
> switch (e) {
> case Ex1 -> ...
> case Ex2 -> ...
> }
> }
>
> ?
>
> With best regards,
> Tagir Valeev.
>
> вс, 30 авг. 2020 г., 21:38 Brian Goetz <mailto:bria
there are no perfect answers.
> On Aug 30, 2020, at 7:37 AM, fo...@univ-mlv.fr wrote:
>
> - Mail original -
>> De: "Brian Goetz"
>> À: "Remi Forax" , "amber-spec-experts"
>>
>> Envoyé: Lundi 24 Août 2020 20:57:03
>> Ob
,
> i've hinted that there is an issue with intersection type and totality, but
> we did not follow up.
>
> Here is the issue
> var value = flag? "foo": 42;
> switch(value) {
> case String s -> ...
> case Integer i -> ...
> case Serializable s ->
> case Comparable c ->
> }
>
> given that t
> 2. Mutability of binding variables.
>
> I agree,
> but in that case, does it also mean that "final" as modifier should be
> allowed ?
> if (foo instanceof final Bar b) { … }
It means it’s a valid question, but a separate one; we could consider allowing
final as a modifier on binding vari
And for all this complex analysis we get... some different exception types?
Doesn't seem like a worthwhile trade.
As I've mentioned already, I think the exception-type thing is mostly a
red herring. We have some existing precendent, which is pretty hard to
extrapolate from:
- Existing
It's not rare to add components to a sum type, by example a MouseEvent
is upgraded to add the number of mouse wheel scroll knobs.
(later corrected to "product")
To do that, you can't just blindly add a new component, because existing
ctor calls will no longer link. If yesterday you had
I don't recall agreeing to anything like this, so perhaps you can
dig up a reference, and I can try to reconstruct what I thought I
was agreeing to?
https://cr.openjdk.java.net/~briangoetz/amber/pattern-match-translation.html
section Migration Compat
Haha, OK. Yes, that was a
While i agree with the general idea, i disagree with the fact that the
compiler should handle the null and total cases, it can not handle the
total case, it has to be handled by the by the runtime, not the compiler.
I will use '?' for the total type, by example this switch is "total
enough"
.
On Fri, Aug 14, 2020 at 10:21 AM Brian Goetz <mailto:brian.go...@oracle.com>> wrote:
- Guards. (John, Tagir) There is acknowledgement that some sort
of "whoops, not this case" support is needed in order to maintain
switch as a useful construct in the face o
- Let S be a sealed abstract type or interface, with permitted
direct subtypes C*, and P* be a set of patterns applicable to S. If
for each C in C*, there exists a subset Pc of P* that is total on C
with remainder Rc, then P* is total on S with remainder { null }
union \forall{c \in C}{ R
han by being an
expression switch?
- Guards: there's a bikeshed to be painted, what's stopping you guys?
- Restrictions on instanceof: proposed, under discussion.
On 8/14/2020 1:19 PM, Brian Goetz wrote:
Here's a summary of the issues raised in the reviews of the
patterns-in-
We can easily generalize the definition of totality to a set of
patterns. In this case, we can handle sealed types and enums:
- Let E be an enum type. The set of patterns { C1 .. Cn } is total
on E with remainder { null, E e } if C1 .. Cn contains all the
constants of E.
Observation:
Proposed: An `instanceof` expression must be able to evaluate to both
true and false, otherwise it is invalid. This rules out strongly
total patterns on the RHS. If you have a strongly total pattern, use
pattern assignment instead.
Makes sense to me, but one question: would this restrict
than "be
an expression switch."
On 8/21/2020 4:18 PM, Brian Goetz wrote:
On 8/21/2020 11:14 AM, Brian Goetz wrote:
Next up (separate topic): letting statement switches opt into totality.
Assuming the discussion on Exhaustiveness is good, let's talk about
totality.
Exp
I have been thinking about this and I have two refinements I would like
to suggest for Pattern Matching in instanceof. Both have come out of
the further work on the next phases of pattern matching.
1. Instanceof expressions must express conditionality.
One of the uncomfortable collisions be
Note that this:
On 8/25/2020 7:53 PM, Brian Goetz wrote:
`default ` means the same thing as `case
`
but it is a static error if the is
not_weakly_ total on the type of the selector
when combined with
I’ll add that in the last case, it is as if there is an
>
>> Which leaves:
>>
>> { statement, expression } x { arrow, colon } x { switch, total-switch }
>>
>> where an expression switch of any stripe is automatically upgraded to a
>> total-switch of that type.
>
> This description actually does not quite describe the current behavior: for
> an e
>> We can still ponder whether “default ” should issue a static error
>> if the is not total. We can furthermore ponder whether “default
>> ” should require the to be strongly total or just weakly
>> total.
>
> On reflection, I believe that in addition to having a choice of `switch` or
> `t
I have thought about what you have just said; (a) I agree, and (b) have made me
realize that I have unnecessarily and unreasonably conflated the o.t. issue
with the fallthrough issue. So let me try once more. For context, here are
the three important paragraphs again, and the only changes
Should this patch be a workaround to existing releases rather than
the main line? As Brian mentions, lambda proxy class may become
inline class in valhalla repo (Roger has a patch already). The
earlier fixing those programs the better.
Indeed if we know this is landing in this cycle i
One question I have is that optimistic totality can apply in switches that are
not on sealed types, or where sealed types show up in nested contexts. For
example:
switch (box) {
case Box(var x): ...
}
Here, I think we want to say that Box(var x) is o.t. on Box, but it do
I am going to argue here that, just as fear of letting nulls flow
stemmed from a early design that conflated multiple design issues as a
result of extrapolating from too few data points (enums and strings),
we have been boxed into another corner because we conflated
expression-ness and the n
2/ using an explicit type for a total type is a footgun because the semantics
will change if the hierarchy or the return type of a method switched upon
change.
Sorry, I think this argument is a pure red herring. I get why this is
one of those "scary the first time you see it" issues, but
The previous mail, on optimistic totality, only applied to switches that
were already total. Currently that includes only expression switches;
we want a non-too-invasive way to mark a statement switch as total as well.
First, I'd like to rule out the variants of "automatically make XYZ
statem
As I mentioned yesterday, I think our ideas about totality and null
handling were getting polluted by our desire to support intuitive,
optimistic totality. So let's try to separate them, by outlining some
goals for optimistic totality.
First, I'll posit that we're now able to stand on a more
I also have reason to believe that, if we do generalized patterns
property, we won't need to do this as a language feature, we can
do it as a library feature. So, let's come back to this later.
Exhaustiveness is hard to emulate in a library.
Understood, but I would happily tr
Note that if we keep "default", it has to accept null because fundamentally, "default" is
like "else".
I agree on default, and I also agree on the comparison to `else`. Which
underscores the importance of totality here; a switch:
case Frog f:
case Tadpole t:
default / case var
re the same behavior.
Whatever we decide for "default", a syntax that let append null to an
existing case seems better ?
Something along "case Foo, null: ... "
Rémi
----
*De: *"Brian Goetz"
From the -comments list.
Forwarded Message
Subject:Re: IdentityObject & abstract superclasses
Date: Fri, 21 Aug 2020 03:12:49 +0200
From: TheMrMilchmann
To: valhalla-spec-comme...@openjdk.java.net
Hi,
to me, the current issue of how to "declare" inline-frie
turing
pattern with minimal distortion;
- We need to have a longer conversation about optimistic totality.
I think that's good progress for the week, as it checks off 3 of the
items on this list.
On 8/14/2020 1:19 PM, Brian Goetz wrote:
Here's a summary of the issues raised in the review
often null
branch is the same as default branch (or some other non-null branch).
With best regards,
Tagir Valeev
On Sun, Aug 23, 2020 at 12:14 AM Brian Goetz wrote:
Breaking into a separate thread. I hope we can put this one to bed
once and for all.
I'm not hostile to that view, but may
It has indeed come up before. There is some overlap with pattern
switch, and some non-overlap, but it's pretty clear the impact of
pattern switch is much larger.
I would much prefer to finish the discussions on the fundamentals first,
which are actually blocking progress on a much-higher-prio
This might be stretching it a tad too far, but I like that we can
given `default` useful new jobs to do in `switch` rather than just
giving him a gold watch.
This is a pretty good story, but I am sufficiently distressed over the
asymmetry of having to treat specially the last one of several
Breaking into a separate thread. I hope we can put this one to bed
once and for all.
I'm not hostile to that view, but may i ask an honest question, why
this semantics is better ?
Do you have examples where it makes sense to let the null to slip
through the statement switch ? Because as i ca
On 8/21/2020 11:14 AM, Brian Goetz wrote:
Next up (separate topic): letting statement switches opt into totality.
Assuming the discussion on Exhaustiveness is good, let's talk about
totality.
Expression switches must be total; we totalize them by throwing when we
encounter any re
(separate topic): letting statement switches opt into totality.
Assuming that we're on the right track, and drilling into the next
level, we now have to bring this back to totality.
On 8/20/2020 9:02 PM, Guy Steele wrote:
On Aug 20, 2020, at 6:14 PM, Brian Goetz wrote:
I suspect
One degree of freedom that you've omitted, which might help you wiggle
out of some of the uncomfortable corners, is warning-now-error-later.
Your "I like, but might be disruptive" approach is to error on the cases
where it is not super clear. But by starting with a warning, errors
like the ~1
I suspect there are other orderings too, such as "any nulls beat any
novels" or vice versa, which would also be deterministic and potentially
more natural to the user. But before we go there, I want to make sure
we have something where users can understand the exceptions that are
thrown withou
but it doesn't mean that in term of translation strategy we need all
those cases as synthetic cases, installing some null checks upfront
(of a pattern deconstruction) and a default should be enough, or am i
missing something.
They don't have to be implemented as individual synthetic cases,
lity specification for new language features only? Ok, ok,
sorry, my imagination drove me too far away from reality. Forget it.
With best regards,
Tagir Valeev.
On Thu, Aug 20, 2020 at 10:57 PM Brian Goetz wrote:
Tagir's question about exhaustiveness in switches points to some technical de
r)
case Box(Circle c)
case Bag(Rect r)
case Bag(Circle c)
default
then Box(Pentagon|null) and Bag(Pentagon|null) clearly fall into the
default case, so no special handling is needed there.
Are we in agreement on what _should_ happen in these cases? If so, I
can put a m
In theory, there is benefit to having local sealed interfaces, in that
they would provide a source of exhaustiveness information for switches
inside the method. On the other hand, we don't really want to encourage
methods to be enormous. So at least for now, this fix seems fine.
On 8/18/2020
801 - 900 of 2342 matches
Mail list logo