Re: JEP325: Switch expressions spec

2018-05-17 Thread Gavin Bierman

> On 16 May 2018, at 23:17, Dan Smith  wrote:
> 
>> On May 8, 2018, at 5:08 PM, Dan Smith > > wrote:
>> 
>> Missing stuff (not necessarily a comprehensive list):
>> 
>> - 15.6, evaluation of a switch expression may throw (I hate maintaining 
>> these lists, but it's here, so we must maintain it)
>> - 15.12.2.1, define "potentially compatible"
>> - 15.12.2.5, define "more specific"
>> - 15.25, categorization of conditionals with switch expression operands 
>> (ugh, one more motivation to abandon the categorization scheme)
>> - 16, definite assignment (including how does a boolean selector/result get 
>> treated?)
>> - 18.2.1, inference reduction
>> - 18.5.2.2, searching for additional inference constraints
>> - 18.5.4, "more specific" inference
> 
> Add 15.2, switch expressions don't fall into any of the previous categories 
> of expressions (unless we're willing to call them very verbose unary 
> expressions).
> 

That *was* the proposal; in the draft spec there is a revised 15.15, where 
switch expressions are added in the production for UnaryExpressionNotPlusMinus. 

Gavin

Re: JEP325: Switch expressions spec

2018-05-16 Thread Dan Smith
> On May 8, 2018, at 5:08 PM, Dan Smith  wrote:
> 
> Missing stuff (not necessarily a comprehensive list):
> 
> - 15.6, evaluation of a switch expression may throw (I hate maintaining these 
> lists, but it's here, so we must maintain it)
> - 15.12.2.1, define "potentially compatible"
> - 15.12.2.5, define "more specific"
> - 15.25, categorization of conditionals with switch expression operands (ugh, 
> one more motivation to abandon the categorization scheme)
> - 16, definite assignment (including how does a boolean selector/result get 
> treated?)
> - 18.2.1, inference reduction
> - 18.5.2.2, searching for additional inference constraints
> - 18.5.4, "more specific" inference

Add 15.2, switch expressions don't fall into any of the previous categories of 
expressions (unless we're willing to call them very verbose unary expressions).



Re: JEP325: Switch expressions spec

2018-05-11 Thread Gavin Bierman
You make the point very well Guy. This is what makes non-clean-room language 
design so hard! I think the question is where we put our weight. Clearly we 
could say we worry more about people migrating existing code, in which case we 
would elect to support migrating from : to -> and the simplest rule is to 
support case p1 -> case p2 -> …. 

The other view, and the one we had when designing this, was that once we ship 
the -> form, everyone will immediate use this all the time. Moreover, this is 
the one that will be in taught in all the Java 101 classes. In these courses, 
at the end of the switch lecture, the teacher will say: if you really need fall 
through. then change all your -> to :, insert some breaks etc. In this scenario 
the requirement is different: it’s to support case p1, p2: 

So the design decision is to either put our weight behind people migrating old 
switches to new with a simple rule, or behind people writing new switches and 
discovering in a handful of cases they need fall through and having to move to 
: form with a simple rule.

Gavin


> On 10 May 2018, at 03:43, Guy Steele  wrote:
> 
> I completely agree with John’s careful analysis, including the more 
> speculative parts about symbol connotations.
> 
> I too find "case B -> case L -> S” distasteful.  But on the other hand I also 
> find ”case B: case L: S” distasteful.
> 
> What I find acceptable is either
> 
>   case B ->
>   case L -> S
> 
> or
> 
>   case B:
>   case L: S
> 
> As a matter of style I strongly prefer the keyword “case” to appear only at 
> the start of a line.
> This makes them easier to spot when reading code.
> 
> What I am arguing for is to have a choice: when you want to put more than one 
> pattern on a line, by all means use the keyword “case” just once and separate 
> the patterns with commas.  But if you want to string them out vertically, I 
> would like to have the option of repeating the “case” keyword once per line, 
> whether using colons or arrows.
> 
> And I argue that the latter style leads to more readable code in the “case 
> null / default” situation; I prefer
> 
>   case null ->
>   default -> E
> 
> to
> 
>   case null, default -> E
> 
> because I don’t like to bury that “default” keyword—I think it merits the 
> same start-of-line visibility as the “case” keyword.  In addition, it really 
> bugs me to treat “default” as if it were syntactically a pattern—it isn’t.
> 
> However, if others prefer "case null, default -> E”, I would be okay with 
> supporting that also.   But I would not want to write it.
> 
> There is a tension or tradeoff between (a) the difference in connotations of 
> arrow and colon, and (b) the simplicity of the theory that in principle they 
> are more or less interchangeable syntactically, and we should make conversion 
> from one to the other as easy as possible.  I may value (b) more than other 
> people do.
> 
> And now, having laid out my complete case (so to speak), I think I am done 
> with arguing this, and am perfectly prepared to be outvoted or overruled.
> 
> —Guy
> 
> 
>> On May 9, 2018, at 10:20 PM, John Rose  wrote:
>> 
>> A quick $0.02 on one bit of the switch syntax-alooza:
>> 
>> I tried hard to like Guy's theory that -> and : are two flavors
>> of the same SwitchLabel syntax.  It is the most economical
>> way to spread the good parts from colonform to arrowform,
>> including the need (on occasion) to label one of the switch
>> clauses as the "default", even while it *also* has a "case N".
>> But I agree with others who find it too strange looking.
>> 
>> If we can't buy Guy's clean syntax idea, we *do* need an
>> ad hoc way to combine multiple cases in arrowform and
>> an *even more* ad hoc way to fold in "default".
>> And of all the possibilities, I think Brian's (below) is
>> the least surprising and most acceptable.  Please,
>> let's not drop the ball and damage arrowform clauses
>> by forbidding multiple ClauseLabel inputs for them.
>> 
>> Here's my take on formalizing Brian's suggestion:
>> 
>> CasePattern:
>> case Pattern { , Pattern } [ , default ]
>> default
>> 
>> (Note that default comes last in the CasePattern, no
>> matter what.)
>> 
>> That's $0.0199.  The rest of it is why I think I can't like
>> Guy's proposal.  The colonform and arrowform just look
>> too different; colons and arrows have drastically different
>> connotations.  Arrow says "go from here to there" (e.g.,
>> from lambda parameter to lambda result).  Colon says,
>> "I'm telling you something about the following thing."
>> Chained arrows seem to say something like "I'm going
>> to breakfast, then to lunch, then to supper", not
>> "red and blue are the colors of this shoe", as colons
>> would.
>> 
>> I know that's really subjective, but I think *something* like
>> that, some folk model or perception, is behind people's
>> distaste for "case B -> case L -> S" when the same people
>> are content with "case R: case B: S".  It's not that arrow
>> is

Re: JEP325: Switch expressions spec

2018-05-10 Thread Alex Buckley

On 5/10/2018 10:36 AM, Dan Smith wrote:

On May 10, 2018, at 6:28 AM, Gavin Bierman
 wrote:

15.29 "the switch expression completes normally": More
conventionally, "the value of the switch expression is …"


That phrase occurs in several places, so you’ll have to tell me
which one you don’t like.


"If execution of the Statement completes abruptly for the reason of a
break with a value, then the switch expression completes normally
with that value."

I'd suggest changing to "for the reason of a break with a value _V_,
then the value of the switch expression is _V_."

For comparison, in all of Chapter 15, I only find four usages of the
phrase "complete[s] normally". Lots of usages of "complete[s]
abruptly", though. Switch _bodies_ are special, because they contain
statements, so it makes sense to say "completes normally" here. But
once we've left the body and we're talking about the switch
expression as a whole, it's better to use the expression-oriented
terminology.


I agree that expressions completing normally has rarely been spelled out 
in Ch.15, and that the value resulting from evaluation of the expression 
is usually more interesting.


However, JEP 325 is the first time that the JLS will explicitly pend an 
expression's evalation on a statement's completion. Usually it's the 
other way round, per 14.1: "If a statement evaluates an expression, 
abrupt completion of the expression always causes ...". And lambda 
expressions, with bodies containing statements, didn't need to do it 
explicitly in 15.27.2 or 15.27.4.


So, since a value-break statement is a common way out of a switch 
expression, I would like the JLS to put the completes-abruptly side by 
side with a completes-normally. The abrupt completion of `break e;` is 
"swallowed" by the normal completion of the enclosing switch expression. 
(This appeals to the disrupted completion that `catch` and `finally` 
clauses arrange.)


AND, the JLS should specify the value of the switch expression, based on 
evaluating the argument of the value-break statement, as you have proposed.


Alex


Re: JEP325: Switch expressions spec

2018-05-10 Thread Dan Smith
> On May 10, 2018, at 6:28 AM, Gavin Bierman  wrote:
> 
>> SwitchStatementClause is probably too general. I don't think we want to 
>> allow arbitrary statements to occur on the RHS without braces. It's unweildy 
>> (think about a chain of if-else, for example), inconsistent with others uses 
>> of "->", and ambiguous: does "case foo -> switch (expr) { ... }" describe a 
>> switch statement or a switch expression?
> 
> Actually the opposite was argued for - that requiring braces would be too 
> much clutter. It is inconsistent with statement lambda though, as you point 
> out.

Here's a roughly-prioritized list of reasons I think allowing an arbitrary 
statement after '->' is bad:

- There's a grammatical ambiguity between "-> SwitchStatement" and "-> 
SwitchExpression"
- It's inconsistent with SwitchExpression (which does not allow a statement 
after the arrow)
- It allows lots of confusing constructs, like "case Foo -> bar: if (cond) m();"
- It's inconsistent with LambdaExpression

The last three are subjective complaints, YMMV.

>> I also have concerns about the heavy duplication between the specs for 
>> switch statements and switch expressions. Wasn't this design motivated by 
>> wanting to have a single, unified construct packaged in expression and 
>> statement forms?
> 
> At the time it was felt that the symmetry was not what was wanted. The new 
> forms of case labels would strongly push the user to the comma separated 
> form, rather than the multiple case label form. Allowing both forms seems 
> messy. But I think it’s a matter of taste. [You will have read Guy’s emails 
> on this elsewhere also.]

Wrong dimension.

I endorse separate arrow and colon switch body productions.

I'm saying I'd like to avoid separate expression and statement switch body 
productions.

>> With or without 'null', there's a good argument that the arrow clauses need 
>> a way to syntactically combine specific cases and 'default'. Where are we at 
>> on this?
> 
> We’ve dropped null patterns for now. 

That's why I said "with or without 'null'". :-)

I think people will miss "case 3, 4, default ->" (or the equivalent) if we 
don't give it to them, and maybe end up shifting to the colon body syntax as a 
workaround.

It's not crucial, though.

>> Throughout: for other specs, people have expressed interest in seeing a 
>> complete before-and-after diff. No shortcuts. (And they're probably 
>> right—it's a lot easier to see what's going on that way.) So any words that 
>> have been removed should be indicated explicitly as deletions, rather than 
>> just leaving the old words out and highlighting the new words as additions.
> 
> I started with doing just the diff, but as so many changes were being made it 
> started looking rather unhelpful, so I went with the “here’s what the section 
> will look like” with the additions and deletions there. I tried to flag all 
> deletions - but sounds like I might have missed a few. 

Not clear to me what you mean by "just the diff" (maybe output from an 
automated tool?). What I'm describing is that while it's sometimes a helpful 
shortcut to do this:

A **widget** is a kind of expression

Readers want to see the removal, too:

A ~~wingding~~ **widget** is a kind of expression

Sometimes this gets fiddly, and I find it easiest to strikeout a whole sentence 
or paragraph, then insert the new and improved version, even though there are 
some shared words. So, yes, exercise editorial discretion in deciding how to 
present things. But a reader should be able to reconstruct the original section 
text using only what you've given them.

>> 14.11: somewhat arbitrarily, '->' is considered an "operator" while ':' is 
>> considered a "separator". Should match that terminology.
> 
> Where is ‘:’ called a separator? I used the word ‘operator’ which is the 
> terminology from JLS§3.12. I’d be happy to use other terminology (I wanted to 
> avoid saying token.)

My mistake, I misread section 3.11.

>> 14.11: Use of the term "pattern" is premature. These are really just 
>> ConstantExpressions (plus, maybe, null). As is, we have lots of undefined 
>> concepts: When is a pattern "assignment compatible with" a type? When does a 
>> pattern "have the same value" as another?
> 
> Yes, I wanted to start weaving in pattern terminology ahead of time. On 
> reflection maybe it’s not the right thing to do. [As an aside, I think it’s 
> pretty obvious what the definition of the “undefined” concepts are. Don’t we 
> do a similar pun with constant expressions and expressions? For example, do 
> we define a notion of value for constant expressions distinct from 
> expressions?]

Okay, fair. As long as "pattern" refers to a subset of "expression", maybe you 
can get away with that.

>> 14.11 "A Java compiler is encouraged": after much discussion about 
>> exhaustiveness, I think the consensus is that we would very much not like 
>> for a Java compiler to do this. Silently doing nothing for some inputs is a 
>> featu

Re: JEP325: Switch expressions spec

2018-05-10 Thread Brian Goetz

> On May 10, 2018, at 11:03 AM, Guy Steele  wrote:
> 
> 
>> On May 10, 2018, at 10:11 AM, Brian Goetz  wrote:
>> 
>> This was the thinking behind UA1; that sometimes you were going to want to 
>> "fall into" an arrow case
> 
> "What I propose IS NOT FALLTHROUGH!” he continues to howl into the darkness 
> (but otherwise keeps his mouth zipped, because he is done arguing** :-).

Didn’t mean to step on that landmine; my comment was merely syntactic.  

> The introduction of patterns may disrupt that model.  If so, so be it, but 
> that is a big-deal change, and it will need to be explained carefully.

It does in at least one degree.  Once you have nested patterns, or guards, or 
explicit `continue`, you need a way to “re-run” the switch starting somewhere 
other than the beginning.  



Re: JEP325: Switch expressions spec

2018-05-10 Thread Guy Steele

> On May 10, 2018, at 10:11 AM, Brian Goetz  wrote:
> 
> This was the thinking behind UA1; that sometimes you were going to want to 
> "fall into" an arrow case

"What I propose IS NOT FALLTHROUGH!” he continues to howl into the darkness 
(but otherwise keeps his mouth zipped, because he is done arguing** :-).

—Guy

** As promised, I will offer no further argument as to what syntax should be 
adopted (that's policy); but I will continue to proclaim firmly that multiple 
labels in a SwitchBlockStatementGroup are not, and never have been, an example 
of fallthrough (that’s a fact, supported by textual evidence in the JLS from 
the very beginning).

Here’s why we (Bill Joy and I) did that: If you look at the underlying 
implementation in the JVM, when you use a “lookupswitch” instruction, if two 
int values happen to take you to the code for the same statement, then for 
either int value the lookup table takes you straight there; there is no 
“fallthrough” at the JVM level, and the terminology used in the source language 
documentation reflects that intent, the better to convey the intended execution 
and cost model.  When you write “case 3: case 4: S” it means EXACTLY the same 
thing as “case 4: case 3: S” and ought to have exactly the same cost, no matter 
what the run-time distribution of occurrences of “3” and “4” as actual dispatch 
values.  The labels “case 3:” and “case 4:” are co-equal labels of S.  There is 
no extra execution step of any kind when the dispatch value equals the case 
label that happened to be written first, compared to what happens when the 
dispatch value equals the case label that happened to be written second.  And 
of course the intent was that the same thing would be going on at the machine 
level: there would simply be a jump instruction to an address pulled from a 
table.

The introduction of patterns may disrupt that model.  If so, so be it, but that 
is a big-deal change, and it will need to be explained carefully.



Re: JEP325: Switch expressions spec

2018-05-10 Thread Guy Steele

> On May 10, 2018, at 8:28 AM, Gavin Bierman  wrote:
> 
> 
>> On 9 May 2018, at 00:08, Dan Smith  wrote:
>> . . .
>> 14.11: somewhat arbitrarily, '->' is considered an "operator" while ':' is 
>> considered a "separator". Should match that terminology.
> 
> Where is ‘:’ called a separator? I used the word ‘operator’ which is the 
> terminology from JLS§3.12. I’d be happy to use other terminology (I wanted to 
> avoid saying token.)

Section 3.11 lists the separators, which include ; and :: but NOT :.  As Gavin 
points out, plain : is listed as an operator in Section 3.12.

(It must be admitted that this distinction was originally somewhat arbitrary.  
Back in 1995, we listed plain : as an operator because it is part of the 
ternary operator ? :, even though it also functions more as a separator in 
constructions such as statement labels and case labels.)

—Guy



Re: JEP325: Switch expressions spec

2018-05-10 Thread Brian Goetz
This was the thinking behind UA1; that sometimes you were going to want 
to "fall into" an arrow case, and one of the reasons that UA1 allowed 
mixing:


    case B:
    case L -> S;

But, people hated that, so we went another way.

As John points out, the one place where it gets ugly is "case null, 
default".  Which we don't have to deal with yet, now that we've pushed 
case null onto the next switch bus.


On 5/9/2018 10:43 PM, Guy Steele wrote:

I completely agree with John’s careful analysis, including the more speculative 
parts about symbol connotations.

I too find "case B -> case L -> S” distasteful.  But on the other hand I also 
find ”case B: case L: S” distasteful.

What I find acceptable is either

case B ->
case L -> S

or

case B:
case L: S

As a matter of style I strongly prefer the keyword “case” to appear only at the 
start of a line.
This makes them easier to spot when reading code.

What I am arguing for is to have a choice: when you want to put more than one 
pattern on a line, by all means use the keyword “case” just once and separate 
the patterns with commas.  But if you want to string them out vertically, I 
would like to have the option of repeating the “case” keyword once per line, 
whether using colons or arrows.

And I argue that the latter style leads to more readable code in the “case null 
/ default” situation; I prefer

case null ->
default -> E

to

case null, default -> E

because I don’t like to bury that “default” keyword—I think it merits the same 
start-of-line visibility as the “case” keyword.  In addition, it really bugs me 
to treat “default” as if it were syntactically a pattern—it isn’t.

However, if others prefer "case null, default -> E”, I would be okay with 
supporting that also.   But I would not want to write it.

There is a tension or tradeoff between (a) the difference in connotations of 
arrow and colon, and (b) the simplicity of the theory that in principle they 
are more or less interchangeable syntactically, and we should make conversion 
from one to the other as easy as possible.  I may value (b) more than other 
people do.

And now, having laid out my complete case (so to speak), I think I am done with 
arguing this, and am perfectly prepared to be outvoted or overruled.

—Guy



On May 9, 2018, at 10:20 PM, John Rose  wrote:

A quick $0.02 on one bit of the switch syntax-alooza:

I tried hard to like Guy's theory that -> and : are two flavors
of the same SwitchLabel syntax.  It is the most economical
way to spread the good parts from colonform to arrowform,
including the need (on occasion) to label one of the switch
clauses as the "default", even while it *also* has a "case N".
But I agree with others who find it too strange looking.

If we can't buy Guy's clean syntax idea, we *do* need an
ad hoc way to combine multiple cases in arrowform and
an *even more* ad hoc way to fold in "default".
And of all the possibilities, I think Brian's (below) is
the least surprising and most acceptable.  Please,
let's not drop the ball and damage arrowform clauses
by forbidding multiple ClauseLabel inputs for them.

Here's my take on formalizing Brian's suggestion:

CasePattern:
  case Pattern { , Pattern } [ , default ]
  default

(Note that default comes last in the CasePattern, no
matter what.)

That's $0.0199.  The rest of it is why I think I can't like
Guy's proposal.  The colonform and arrowform just look
too different; colons and arrows have drastically different
connotations.  Arrow says "go from here to there" (e.g.,
from lambda parameter to lambda result).  Colon says,
"I'm telling you something about the following thing."
Chained arrows seem to say something like "I'm going
to breakfast, then to lunch, then to supper", not
"red and blue are the colors of this shoe", as colons
would.

I know that's really subjective, but I think *something* like
that, some folk model or perception, is behind people's
distaste for "case B -> case L -> S" when the same people
are content with "case R: case B: S".  It's not that arrow
is heavier than colon, exactly; it's that arrow really means
something different than colon.

At least, arrow and colon differ in the context of Java.
In some parts of some languages "a:b" does mean
"from a to b".  But in those places "a:b:c" doesn't mean
"from a or b to c" as in Java.  In any case, "a -> b -> c"
never means "from either a or b to c", as Guy's syntactic
deductions would lead us to try in Java.

— John

On Apr 23, 2018, at 11:20 AM, Guy Steele  wrote:

I argue that there is no need to make the special-case exception for `default`. 
 When you need to play that game (usually because null needs to be addressed), 
you cannot use the comma-separation syntax.  Instead, just say either

case null: default: s;  (or, if you prefer, `default: 
case null: s;`)

or

case null -> default -> s;(or, if you prefer, `default -> 
case null -> s

Re: JEP325: Switch expressions spec

2018-05-10 Thread Gavin Bierman

> On 9 May 2018, at 00:08, Dan Smith  wrote:
> 
> Here are my notes from a pass over the spec.
> 
> Significant items:
> 
> ---
> 
> SwitchStatementClause is probably too general. I don't think we want to allow 
> arbitrary statements to occur on the RHS without braces. It's unweildy (think 
> about a chain of if-else, for example), inconsistent with others uses of 
> "->", and ambiguous: does "case foo -> switch (expr) { ... }" describe a 
> switch statement or a switch expression?

Actually the opposite was argued for - that requiring braces would be too much 
clutter. It is inconsistent with statement lambda though, as you point out.

> 
> I also have concerns about the heavy duplication between the specs for switch 
> statements and switch expressions. Wasn't this design motivated by wanting to 
> have a single, unified construct packaged in expression and statement forms?

At the time it was felt that the symmetry was not what was wanted. The new 
forms of case labels would strongly push the user to the comma separated form, 
rather than the multiple case label form. Allowing both forms seems messy. But 
I think it’s a matter of taste. [You will have read Guy’s emails on this 
elsewhere also.]

> 
> Proposed fix: rename SwitchStatementBlock and SwitchExpressionBlock to a 
> single SwitchBlock. Merge the two grammars, with SwitchClause being defined 
> like SwitchExpressionClause, not SwitchStatementClause. Follow lambda 
> expressions in stating a semantic rule that, in the statement form, the 
> Expression be a StatementExpression.
> 
> Discuss switch blocks in a subsection of 14.11 (maybe two subsections, for 
> arrow and colon bodies, with a certain amount of sharing). Define matching, 
> compile-time checks, and runtime behavior. (Like lambda expressions, the 
> treatment of Expression clauses will be context-dependent.) The remaining 
> spec for switch statements and switch expressions should be small.

This makes sense if we go for the symmetry approach. 


> While we're at it, add 'throw' to the set of legal bodies for lambda 
> expressions. (Or we can spin this off into a separate RFE, but I'd like to 
> ship it in parallel.)

I’ll ask about this. At least to me it seems a little odd to throw in a tweak 
to lambdas in a JEP concerning switch. But maybe it’s acceptable; I’ll find out.

> 
> ---
> 
> After previous discussion about enum names, I think we should relax the 
> requirement that an enum-typed switch must use (unqualified) enum constant 
> names. The behavior I'd like is: if the type of the selector expression is an 
> enum type, and the pattern is an unqualified name, resolve it as a member of 
> the enum type; otherwise, handle a ConstantExpression pattern just like any 
> other.
> 
> (I might also drop the grammar's distinction between EnumConstantName and 
> ConstantExpression, which is ambiguous. And I might also push this 
> special-case logic about name resolution into Chapter 6.)
> 
> ---
> 
> I have concerns about the 'break' rules; see separate thread.


ok

> 
> With or without 'null', there's a good argument that the arrow clauses need a 
> way to syntactically combine specific cases and 'default'. Where are we at on 
> this?

We’ve dropped null patterns for now. 

> 
> ---
> 
> Missing stuff (not necessarily a comprehensive list):
> 
> - 15.6, evaluation of a switch expression may throw (I hate maintaining these 
> lists, but it's here, so we must maintain it)
> - 15.12.2.1, define "potentially compatible"
> - 15.12.2.5, define "more specific"
> - 15.25, categorization of conditionals with switch expression operands (ugh, 
> one more motivation to abandon the categorization scheme)
> - 16, definite assignment (including how does a boolean selector/result get 
> treated?)
> - 18.2.1, inference reduction
> - 18.5.2.2, searching for additional inference constraints
> - 18.5.4, "more specific” inference
> 

Thanks. (Amazing how big this small feature is!)

> ---
> 
> And some notes about presentational issues:
> 
> Throughout: for other specs, people have expressed interest in seeing a 
> complete before-and-after diff. No shortcuts. (And they're probably 
> right—it's a lot easier to see what's going on that way.) So any words that 
> have been removed should be indicated explicitly as deletions, rather than 
> just leaving the old words out and highlighting the new words as additions.

I started with doing just the diff, but as so many changes were being made it 
started looking rather unhelpful, so I went with the “here’s what the section 
will look like” with the additions and deletions there. I tried to flag all 
deletions - but sounds like I might have missed a few. 

> 
> 5.6.3 needs a better title than "numeric promotion", which is a broad term 
> introduced in 5.6; and it needs to be properly introduced in 5.6.
> 
> The conditional expression spec should be updated to re-use the new flavor of 
> numeric promotion.

Agreed.

> 
> 14.11: somewhat arbitrarily, '->' is 

Re: JEP325: Switch expressions spec

2018-05-10 Thread Gavin Bierman
Hah! Yes, good catch. Let me think about this one.

Thanks,
Gavin

> On 30 Apr 2018, at 17:13, Éamonn McManus  wrote:
> 
> I believe the grammar is ambiguous regarding `->`. If you have
> case a -> b -> c
> then in principle it could mean (1) when the selector expression equals `a`
> the value is `b -> c`, or (2) when the selector expression equals  `a -> b`
> the value is `c`. Of course (2) is excluded semantically but I think it
> could be excluded syntactically just by changing the definition of
> ConstantExpression from
> 
> ConstantExpression:
>   Expression
> 
> to
> 
> ConstantExpression:
>   AssignmentExpression
> 
> On Fri, 27 Apr 2018 at 08:14, Gavin Bierman 
> wrote:
> 
>> I have uploaded the latest draft of the spec for JEP 325 at
> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
> 
>> Changes from the last version:
>> * Supports new -> label form in both switch expressions and switch
> statements
>> * Added typing rules for switch expression
>> * Restrict the type of a selector expression to not include long, double
> and float as previously proposed
>> * Misc smaller changes from community feedback (thanks!)
> 
>> Comments welcomed!
>> Gavin
> 
>>> On 12 Apr 2018, at 22:27, Gavin Bierman 
> wrote:
>>> 
>>> I have uploaded a draft spec for JEP 325: Switch expressions at
> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
>>> 
>>> Note there are still three things missing:
>>> 
>>> * There is no text about typing a switch expression, as this is still
> being discussed on this list.
>>> * There is no name given for the exception raised at runtime when a
> switch expression fails to find a matching pattern label, as this is still
> being discussed on this list.
>>> * The spec currently permits fall through from a "case pattern:”
> statement group into a "case pattern ->" clause. We are still working
> through the consequences of removing this possibility.
>>> 
>>> Comments welcomed!
>>> Gavin



Re: JEP325: Switch expressions spec

2018-05-10 Thread Gavin Bierman
[Apologies for slow reply. Now going through the latest batch of feedback.]

Ack. Thanks.

Gavin


> On 27 Apr 2018, at 22:55, Alex Buckley  wrote:
> 
> On 4/27/2018 8:03 AM, Gavin Bierman wrote:
>> I have uploaded the latest draft of the spec for JEP 325 at 
>> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
> 
> 14.16 is right to say that:
> 
>  A break statement with value Expression ***attempts to cause the
>  evaluation of the immediately enclosing switch expression***
>  to complete normally ...
> 
> because the following is legal (x will become 200) :
> 
>  int x = switch (e) {
>case 1  -> {
>  try { break 100; } finally { break 200; }
>}
>default -> 0;
>  };
> 
> Therefore, in the discussion section, please say that:
> 
>  The preceding descriptions say "attempts to transfer control"
>  ***and "attempts to cause evaluation to complete normally",***
>  rather than just "transfers control" ***and "causes evaluation
>  to complete normally",*** because if there are any try statements ...
> 
>  ... innermost to outermost, before control is transferred to the
>  break target ***or evaluation of the break target completes***.
> 
>  [Notice we don't yet know if evaluation of the break target
>   will complete normally or abruptly. If the finally clause above
>   was to throw an exception instead of break-200, then the
>   switch expression would complete abruptly by reason of the
>   exception, rather than completing normally with the value 100.]
> 
> (Separately: Please flag the new text in 15.15's opening line.)
> 
> Alex



Re: JEP325: Switch expressions spec

2018-05-09 Thread Guy Steele
I completely agree with John’s careful analysis, including the more speculative 
parts about symbol connotations.

I too find "case B -> case L -> S” distasteful.  But on the other hand I also 
find ”case B: case L: S” distasteful.

What I find acceptable is either

case B ->
case L -> S

or

case B:
case L: S

As a matter of style I strongly prefer the keyword “case” to appear only at the 
start of a line.
This makes them easier to spot when reading code.

What I am arguing for is to have a choice: when you want to put more than one 
pattern on a line, by all means use the keyword “case” just once and separate 
the patterns with commas.  But if you want to string them out vertically, I 
would like to have the option of repeating the “case” keyword once per line, 
whether using colons or arrows.

And I argue that the latter style leads to more readable code in the “case null 
/ default” situation; I prefer

case null ->
default -> E

to

case null, default -> E

because I don’t like to bury that “default” keyword—I think it merits the same 
start-of-line visibility as the “case” keyword.  In addition, it really bugs me 
to treat “default” as if it were syntactically a pattern—it isn’t.

However, if others prefer "case null, default -> E”, I would be okay with 
supporting that also.   But I would not want to write it.

There is a tension or tradeoff between (a) the difference in connotations of 
arrow and colon, and (b) the simplicity of the theory that in principle they 
are more or less interchangeable syntactically, and we should make conversion 
from one to the other as easy as possible.  I may value (b) more than other 
people do.

And now, having laid out my complete case (so to speak), I think I am done with 
arguing this, and am perfectly prepared to be outvoted or overruled.

—Guy


> On May 9, 2018, at 10:20 PM, John Rose  wrote:
> 
> A quick $0.02 on one bit of the switch syntax-alooza:
> 
> I tried hard to like Guy's theory that -> and : are two flavors
> of the same SwitchLabel syntax.  It is the most economical
> way to spread the good parts from colonform to arrowform,
> including the need (on occasion) to label one of the switch
> clauses as the "default", even while it *also* has a "case N".
> But I agree with others who find it too strange looking.
> 
> If we can't buy Guy's clean syntax idea, we *do* need an
> ad hoc way to combine multiple cases in arrowform and
> an *even more* ad hoc way to fold in "default".
> And of all the possibilities, I think Brian's (below) is
> the least surprising and most acceptable.  Please,
> let's not drop the ball and damage arrowform clauses
> by forbidding multiple ClauseLabel inputs for them.
> 
> Here's my take on formalizing Brian's suggestion:
> 
> CasePattern:
>  case Pattern { , Pattern } [ , default ]
>  default
> 
> (Note that default comes last in the CasePattern, no
> matter what.)
> 
> That's $0.0199.  The rest of it is why I think I can't like
> Guy's proposal.  The colonform and arrowform just look
> too different; colons and arrows have drastically different
> connotations.  Arrow says "go from here to there" (e.g.,
> from lambda parameter to lambda result).  Colon says,
> "I'm telling you something about the following thing."
> Chained arrows seem to say something like "I'm going
> to breakfast, then to lunch, then to supper", not
> "red and blue are the colors of this shoe", as colons
> would.
> 
> I know that's really subjective, but I think *something* like
> that, some folk model or perception, is behind people's
> distaste for "case B -> case L -> S" when the same people
> are content with "case R: case B: S".  It's not that arrow
> is heavier than colon, exactly; it's that arrow really means
> something different than colon.
> 
> At least, arrow and colon differ in the context of Java.
> In some parts of some languages "a:b" does mean
> "from a to b".  But in those places "a:b:c" doesn't mean
> "from a or b to c" as in Java.  In any case, "a -> b -> c"
> never means "from either a or b to c", as Guy's syntactic
> deductions would lead us to try in Java.
> 
> — John
> 
> On Apr 23, 2018, at 11:20 AM, Guy Steele  wrote:
>> 
>> I argue that there is no need to make the special-case exception for 
>> `default`.  When you need to play that game (usually because null needs to 
>> be addressed), you cannot use the comma-separation syntax.  Instead, just 
>> say either
>> 
>>  case null: default: s;  (or, if you prefer, `default: 
>> case null: s;`)
>> 
>> or
>> 
>>  case null -> default -> s;  (or, if you prefer, `default -> 
>> case null -> s;`)
> 
> On Apr 20, 2018, at 11:40 AM, Brian Goetz  wrote:
>> 
>> One thing that is relevant to the short term is that now that we killed 
>> mixed labels, we'd have to have a way to say "case null or default" in arrow 
>> world.  The least stupid thing seems to be to allow default to be tacked on 
>> to a comm

Re: JEP325: Switch expressions spec

2018-05-09 Thread John Rose
A quick $0.02 on one bit of the switch syntax-alooza:

I tried hard to like Guy's theory that -> and : are two flavors
of the same SwitchLabel syntax.  It is the most economical
way to spread the good parts from colonform to arrowform,
including the need (on occasion) to label one of the switch
clauses as the "default", even while it *also* has a "case N".
But I agree with others who find it too strange looking.

If we can't buy Guy's clean syntax idea, we *do* need an
ad hoc way to combine multiple cases in arrowform and
an *even more* ad hoc way to fold in "default".
And of all the possibilities, I think Brian's (below) is
the least surprising and most acceptable.  Please,
let's not drop the ball and damage arrowform clauses
by forbidding multiple ClauseLabel inputs for them.

Here's my take on formalizing Brian's suggestion:

CasePattern:
  case Pattern { , Pattern } [ , default ]
  default

(Note that default comes last in the CasePattern, no
matter what.)

That's $0.0199.  The rest of it is why I think I can't like
Guy's proposal.  The colonform and arrowform just look
too different; colons and arrows have drastically different
connotations.  Arrow says "go from here to there" (e.g.,
from lambda parameter to lambda result).  Colon says,
"I'm telling you something about the following thing."
Chained arrows seem to say something like "I'm going
to breakfast, then to lunch, then to supper", not
"red and blue are the colors of this shoe", as colons
would.

I know that's really subjective, but I think *something* like
that, some folk model or perception, is behind people's
distaste for "case B -> case L -> S" when the same people
are content with "case R: case B: S".  It's not that arrow
is heavier than colon, exactly; it's that arrow really means
something different than colon.

At least, arrow and colon differ in the context of Java.
In some parts of some languages "a:b" does mean
"from a to b".  But in those places "a:b:c" doesn't mean
"from a or b to c" as in Java.  In any case, "a -> b -> c"
never means "from either a or b to c", as Guy's syntactic
deductions would lead us to try in Java.

— John

On Apr 23, 2018, at 11:20 AM, Guy Steele  wrote:
> 
> I argue that there is no need to make the special-case exception for 
> `default`.  When you need to play that game (usually because null needs to be 
> addressed), you cannot use the comma-separation syntax.  Instead, just say 
> either
> 
>   case null: default: s;  (or, if you prefer, `default: 
> case null: s;`)
> 
> or
> 
>   case null -> default -> s;  (or, if you prefer, `default -> 
> case null -> s;`)

On Apr 20, 2018, at 11:40 AM, Brian Goetz  wrote:
> 
> One thing that is relevant to the short term is that now that we killed mixed 
> labels, we'd have to have a way to say "case null or default" in arrow world. 
>  The least stupid thing seems to be to allow default to be tacked on to a 
> comma-separated case list as if it were a pattern: 
> 
> case A -> s1;
> case null, default -> s2;
> 
> since you can no longer say:
> 
> case A -> s1;
> case null:
> default:
> s2;
> 




Re: JEP325: Switch expressions spec

2018-05-08 Thread Dan Smith
Here are my notes from a pass over the spec.

Significant items:

---

SwitchStatementClause is probably too general. I don't think we want to allow 
arbitrary statements to occur on the RHS without braces. It's unweildy (think 
about a chain of if-else, for example), inconsistent with others uses of "->", 
and ambiguous: does "case foo -> switch (expr) { ... }" describe a switch 
statement or a switch expression?

I also have concerns about the heavy duplication between the specs for switch 
statements and switch expressions. Wasn't this design motivated by wanting to 
have a single, unified construct packaged in expression and statement forms?

Proposed fix: rename SwitchStatementBlock and SwitchExpressionBlock to a single 
SwitchBlock. Merge the two grammars, with SwitchClause being defined like 
SwitchExpressionClause, not SwitchStatementClause. Follow lambda expressions in 
stating a semantic rule that, in the statement form, the Expression be a 
StatementExpression.

Discuss switch blocks in a subsection of 14.11 (maybe two subsections, for 
arrow and colon bodies, with a certain amount of sharing). Define matching, 
compile-time checks, and runtime behavior. (Like lambda expressions, the 
treatment of Expression clauses will be context-dependent.) The remaining spec 
for switch statements and switch expressions should be small.

While we're at it, add 'throw' to the set of legal bodies for lambda 
expressions. (Or we can spin this off into a separate RFE, but I'd like to ship 
it in parallel.)

---

After previous discussion about enum names, I think we should relax the 
requirement that an enum-typed switch must use (unqualified) enum constant 
names. The behavior I'd like is: if the type of the selector expression is an 
enum type, and the pattern is an unqualified name, resolve it as a member of 
the enum type; otherwise, handle a ConstantExpression pattern just like any 
other.

(I might also drop the grammar's distinction between EnumConstantName and 
ConstantExpression, which is ambiguous. And I might also push this special-case 
logic about name resolution into Chapter 6.)

---

I have concerns about the 'break' rules; see separate thread.

---

With or without 'null', there's a good argument that the arrow clauses need a 
way to syntactically combine specific cases and 'default'. Where are we at on 
this?

---

Missing stuff (not necessarily a comprehensive list):

- 15.6, evaluation of a switch expression may throw (I hate maintaining these 
lists, but it's here, so we must maintain it)
- 15.12.2.1, define "potentially compatible"
- 15.12.2.5, define "more specific"
- 15.25, categorization of conditionals with switch expression operands (ugh, 
one more motivation to abandon the categorization scheme)
- 16, definite assignment (including how does a boolean selector/result get 
treated?)
- 18.2.1, inference reduction
- 18.5.2.2, searching for additional inference constraints
- 18.5.4, "more specific" inference

---

And some notes about presentational issues:

Throughout: for other specs, people have expressed interest in seeing a 
complete before-and-after diff. No shortcuts. (And they're probably right—it's 
a lot easier to see what's going on that way.) So any words that have been 
removed should be indicated explicitly as deletions, rather than just leaving 
the old words out and highlighting the new words as additions.

5.6.3 needs a better title than "numeric promotion", which is a broad term 
introduced in 5.6; and it needs to be properly introduced in 5.6.

The conditional expression spec should be updated to re-use the new flavor of 
numeric promotion.

14.11: somewhat arbitrarily, '->' is considered an "operator" while ':' is 
considered a "separator". Should match that terminology.

14.11: "consists of zero or more statements" is not quite right in either case. 
A clause block consists of clauses, which are pattern/clause body pairs. A 
group block consists of statement groups, which are lists of statements 
prefixed by a list of labels.

14.11: "It should be clear from that grammar ..." should be green

14.11: Use of the term "pattern" is premature. These are really just 
ConstantExpressions (plus, maybe, null). As is, we have lots of undefined 
concepts: When is a pattern "assignment compatible with" a type? When does a 
pattern "have the same value" as another?

14.11: The discussion explaining why we don't silently complete a switch when 
the selector is null is worth keeping, as an explanation for why, in the 
absense of an explicit 'case null', the statement will throw. (Better than just 
saying "historical reasons" or "compatibility".)

14.11 "A Java compiler is encouraged": after much discussion about 
exhaustiveness, I think the consensus is that we would very much not like for a 
Java compiler to do this. Silently doing nothing for some inputs is a feature 
of switch statements.

14.11: I'm pretty down on explaining features via translation to other 
features. It's often 

Re: JEP325: Switch expressions spec

2018-04-30 Thread Guy Steele

> On Apr 27, 2018, at 11:03 AM, Gavin Bierman  wrote:
> 
> I have uploaded the latest draft of the spec for JEP 325 at 
> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
> 
> Changes from the last version:
> * Supports new -> label form in both switch expressions and switch statements
> * Added typing rules for switch expression
> * Restrict the type of a selector expression to not include long, double and 
> float as previously proposed
> * Misc smaller changes from community feedback (thanks!)
> 
> Comments welcomed!

Note the (certainly currently intentional) lack of structural parallelism in 
these two parts of the BNF in Section 4.11:
__

SwitchStatementClause:

ClauseLabel Statement

ClauseLabel:

CasePattern ->
__

SwitchBlockStatementGroup:

GroupLabels BlockStatements

GroupLabels:

GroupLabel {GroupLabel}

GroupLabel:

CasePattern :
__

They can easily be made structurally parallel by changing the first two cited 
rules to:
__

SwitchStatementClause:

ClauseLabels Statement

ClauseLabels:

ClauseLabel {ClauseLabel}

ClauseLabel:

CasePattern ->
__

which of course results in precisely my earlier proposal to allow multiple 
clause labels on a single statement—this note is merely to point out that it is 
an easy and unsurprising change to the BNF.

Then in Section 15.29 one need only change
__

SwitchExpressionClause:

ClauseLabel Expression ;
ClauseLabel Block
ClauseLabel ThrowStatement
__

to
__

SwitchExpressionClause:

ClauseLabels Expression ;
ClauseLabels Block
ClauseLabels ThrowStatement
__

“It’s not fallthrough—it’s multiple labels.”

—Guy





Re: JEP325: Switch expressions spec

2018-04-30 Thread Kevin Bourrillion
On Sun, Apr 29, 2018 at 11:14 AM, Remi Forax  wrote:

I do not care about double and float, doing == on a double or a float is
> already dubious, but why drop the support for long ?
>

I think the set should be expanded all at once. It's noisy otherwise.
Secondarily to that I argued that it was better to wait and do them all
together with patterns.



> > * Misc smaller changes from community feedback (thanks!)
> >
> > Comments welcomed!
> > Gavin
>
> Rémi
>
> >
> >> On 12 Apr 2018, at 22:27, Gavin Bierman 
> wrote:
> >>
> >> I have uploaded a draft spec for JEP 325: Switch expressions at
> >> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
> >>
> >> Note there are still three things missing:
> >>
> >> * There is no text about typing a switch expression, as this is still
> being
> >> discussed on this list.
> >> * There is no name given for the exception raised at runtime when a
> switch
> >> expression fails to find a matching pattern label, as this is still
> being
> >> discussed on this list.
> >> * The spec currently permits fall through from a "case pattern:”
> statement group
> >> into a "case pattern ->" clause. We are still working through the
> consequences
> >> of removing this possibility.
> >>
> >> Comments welcomed!
> > > Gavin
>



-- 
Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com


Re: JEP325: Switch expressions spec

2018-04-29 Thread Remi Forax
- Mail original -
> De: "Gavin Bierman" 
> À: "amber-spec-experts" 
> Envoyé: Vendredi 27 Avril 2018 17:03:50
> Objet: Re: JEP325: Switch expressions spec

> I have uploaded the latest draft of the spec for JEP 325 at
> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
> 
> Changes from the last version:
> * Supports new -> label form in both switch expressions and switch statements
> * Added typing rules for switch expression
> * Restrict the type of a selector expression to not include long, double and
> float as previously proposed

I do not care about double and float, doing == on a double or a float is 
already dubious, but why drop the support for long ?


> * Misc smaller changes from community feedback (thanks!)
> 
> Comments welcomed!
> Gavin

Rémi

> 
>> On 12 Apr 2018, at 22:27, Gavin Bierman  wrote:
>> 
>> I have uploaded a draft spec for JEP 325: Switch expressions at
>> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
>> 
>> Note there are still three things missing:
>> 
>> * There is no text about typing a switch expression, as this is still being
>> discussed on this list.
>> * There is no name given for the exception raised at runtime when a switch
>> expression fails to find a matching pattern label, as this is still being
>> discussed on this list.
>> * The spec currently permits fall through from a "case pattern:” statement 
>> group
>> into a "case pattern ->" clause. We are still working through the 
>> consequences
>> of removing this possibility.
>> 
>> Comments welcomed!
> > Gavin


Re: JEP325: Switch expressions spec

2018-04-27 Thread Alex Buckley

On 4/27/2018 8:03 AM, Gavin Bierman wrote:

I have uploaded the latest draft of the spec for JEP 325 at 
http://cr.openjdk.java.net/~gbierman/switch-expressions.html


14.16 is right to say that:

  A break statement with value Expression ***attempts to cause the
  evaluation of the immediately enclosing switch expression***
  to complete normally ...

because the following is legal (x will become 200) :

  int x = switch (e) {
case 1  -> {
  try { break 100; } finally { break 200; }
}
default -> 0;
  };

Therefore, in the discussion section, please say that:

  The preceding descriptions say "attempts to transfer control"
  ***and "attempts to cause evaluation to complete normally",***
  rather than just "transfers control" ***and "causes evaluation
  to complete normally",*** because if there are any try statements ...

  ... innermost to outermost, before control is transferred to the
  break target ***or evaluation of the break target completes***.

  [Notice we don't yet know if evaluation of the break target
   will complete normally or abruptly. If the finally clause above
   was to throw an exception instead of break-200, then the
   switch expression would complete abruptly by reason of the
   exception, rather than completing normally with the value 100.]

(Separately: Please flag the new text in 15.15's opening line.)

Alex


Re: JEP325: Switch expressions spec

2018-04-27 Thread Gavin Bierman
I have uploaded the latest draft of the spec for JEP 325 at 
http://cr.openjdk.java.net/~gbierman/switch-expressions.html

Changes from the last version:
* Supports new -> label form in both switch expressions and switch statements
* Added typing rules for switch expression
* Restrict the type of a selector expression to not include long, double and 
float as previously proposed
* Misc smaller changes from community feedback (thanks!)

Comments welcomed!
Gavin

> On 12 Apr 2018, at 22:27, Gavin Bierman  wrote:
> 
> I have uploaded a draft spec for JEP 325: Switch expressions at 
> http://cr.openjdk.java.net/~gbierman/switch-expressions.html
> 
> Note there are still three things missing:
> 
> * There is no text about typing a switch expression, as this is still being 
> discussed on this list.
> * There is no name given for the exception raised at runtime when a switch 
> expression fails to find a matching pattern label, as this is still being 
> discussed on this list.
> * The spec currently permits fall through from a "case pattern:” statement 
> group into a "case pattern ->" clause. We are still working through the 
> consequences of removing this possibility.
> 
> Comments welcomed!
> Gavin



Re: JEP325: Switch expressions spec

2018-04-23 Thread Guy Steele


Sent from my iPhone

> On Apr 23, 2018, at 4:22 PM, Kevin Bourrillion  wrote:
> 
> On Mon, Apr 23, 2018 at 12:00 PM, Guy Steele  wrote:
>>> On Apr 23, 2018, at 2:58 PM, Kevin Bourrillion  wrote:
>>> 
 On Mon, Apr 23, 2018 at 11:20 AM, Guy Steele  wrote:
 
 (1) We have moved toward allowing “arrow versus colon” to be a syntax 
 choice that is COMPLETELY orthogonal to other choices about the use of 
 `switch`.  If this rule is to hold universally, then any switch statement 
 or expression should be convertible between the arrow form and the colon 
 form using a simple, uniform rule.
 
 (2) In switch expressions we want to be able to use the concise notation 
 `case a, b, c -> s;` for a switch clause.
 
 (3) From (1) and (2) we inexorably conclude that `case a, b, c: break s;` 
 must also be a valid syntax.
 
 (4) But we could also have written (3) as `case a: case b: case c: break 
 s;` and we certainly expect them to have equivalent behavior.
 
 (5) From (1) and (4) we conclude that we ought also be to be able to write 
 `case a -> case b -> case c -> s;`.
>>> 
>>> Not necessarily, if one simply views (4) as being an artifact of colonform 
>>> switch's capacity for fall-through, which we know should not carry over. 
>>> (Although we technically don't use the term "fall-through" in this 
>>> no-intervening-code case, it works the same way and many people do think of 
>>> it that way.)
>> 
>> You could view it that way—but such a view is incorrect, going back to JLS1.
> 
> To be more clear, I wasn't trying to make a statement about what is correct 
> or incorrect by the spec. (On such matters I will always be deferring to the 
> rest of you!)
> 
> My claim is just that it is not hard for a user to make sense of why `case A: 
> case B: x` would work in colonform yet `case A -> case B -> x` might not work 
> in arrowform. These don't necessarily feel contradictory. A user may simply 
> understand that since colonform's design is made to support fall-through, 
> that became an obvious way that it could address multiple labels as well, 
> whereas the same does not apply in arrowform.

Fair enough. 

> Okay, so it's a "folk model". I think that neither makes it automatically 
> good nor automatically bad.
> 
> To the user, I believe that the ability to choose `case A -> case B ->` is an 
> unnecessary choice and feels like the same kind of baggage that I'd hoped to 
> leave behind when moving to arrowform.

Yep. Agreed that you would almost never want to use it. But it would give me a 
warm, fuzzy feeling to know it’s lurking there for the few times you really 
need it

Re: JEP325: Switch expressions spec

2018-04-23 Thread Guy Steele

> On Apr 23, 2018, at 3:00 PM, Guy Steele  wrote:
> . . .
> You could view it that way—but such a view is incorrect, going back to JLS1.
> 
> I know that many people develop alternate “folk models” for how they think 
> things work or ought to work, but sometimes such alternate models lead one 
> astray.  This is one such instance.  This is why we have a spec.
> 
> My argument does not rely on fallthrough; it relies on the notion of a case 
> label being “associated with” a statement.  JLS is quite clear on this.

Alex Buckley has kindly pointed out to me that the preceding remark is in 
error.  I misread the wording in JLS1 14.9 (and JDK8 JLS 14.11), paragraph 3.  
A case label is “associated with” the containing `switch` statement, not the 
statement that follows it in the SwitchBlockStatementGroup.

I should have said:

My argument does not rely on fallthrough; it relies on the notion of 
executing all statements after the matching case label in the switch block.  
This execution of statements, once initiated, may then “fall through” labels, 
but the initiation of this execution (specifically, initiation of execution of 
the first such statement) does not fall through labels.  JLS is quite clear on 
this.

This is also confirmed by the first sentence in that section: “The 
`switch` statement transfers control to one of several statements depending on 
the value of an expression.”  Despite the fact that one might like to think of 
"transferring control to a case label” rather than to a statement, the official 
model is that control is transferred directly to a statement.

> To be more explicit about assumption (1) above: I propose the simple, uniform 
> rule that the way to convert colon form to arrow form is to (a) replace every 
> colon in a SwitchLabel with an arrow, then (b) add braces and “break” where 
> necessary (and the rules for this depend on whether you are converting a 
> statement switch or an expression switch).  The point of this definition is 
> that step (a) need not require any exceptions or special cases.
> 
> —Guy
>  



Re: JEP325: Switch expressions spec

2018-04-23 Thread Guy Steele
I agree; and that is exactly why I would throw in a newline in situations where 
I cared to use two arrows:

case pat1 ->
case pat2 -> s1;

is much to be preferred to

case pat1 -> case pat2 -> s1;

Look, I also think that it’s bad form to write

a = b ? c : d;

because of the risk of misinterpretation; I would write

a = (b ? c : d);

I don’t think the risks of switch syntax are worse (or better) than this.

> On Apr 23, 2018, at 3:07 PM, fo...@univ-mlv.fr wrote:
> 
> '->' being a two characters symbol (at least if you do not enable font 
> ligature of your IDE/editor) is a more strong separator than comma ',',
> so i think it's easy to visually parse
>  case pat1, pat2 -> s
> as
>  case [pat1, pat2] -> s
> than
>  case pat1, [pat2 -> s]
> 
> Rémi
> 
> - Mail original -
>> De: "Guy Steele" 
>> À: "Remi Forax" 
>> Cc: "amber-spec-experts" 
>> Envoyé: Lundi 23 Avril 2018 20:32:26
>> Objet: Re: JEP325: Switch expressions spec
> 
>>> On Apr 23, 2018, at 2:27 PM, Guy Steele  wrote:
>>> 
>>> Good point, Rémi.  However, note that
>>> 
>>> case pat1, pat2 -> s
>>> 
>>> is equally too close to
>>> 
>>> case pat1 -> pat2 -> s
>>> 
>>> and again they have very different meanings.
>>> 
>>> We have to admit that there is room to blunder with this syntax.
>>> 
>>> One way out would be to use a different arrow for `switch` statements:
>>> 
>>> switch (x) {
>>> case pat1 => case pat2 => s1;
>>> case pat3 => pat4 -> s2;
>>> case pat5, pat6 => s2;
>>> case pat7, pat8 => pat9 -> s4;
>>> }
>> 
>> As a careful coder, if I did not have a separate arrow `=>` (and probably 
>> even
>> if I did), I would use formatting and parentheses to convey my intent:
>> 
>>  switch (x) {
>>  case pat1 ->
>>  case pat2 -> s1;
>>  case pat3 -> (pat4 -> s2);
>>  case pat5, pat6 -> s2;
>>  case pat7, pat8 -> (pat9 -> s4);
>>  }
>> 
>> —Guy



Re: JEP325: Switch expressions spec

2018-04-23 Thread Guy Steele

> On Apr 23, 2018, at 2:58 PM, Kevin Bourrillion  wrote:
> 
> On Mon, Apr 23, 2018 at 11:20 AM, Guy Steele  > wrote:
> 
> (1) We have moved toward allowing “arrow versus colon” to be a syntax choice 
> that is COMPLETELY orthogonal to other choices about the use of `switch`.  If 
> this rule is to hold universally, then any switch statement or expression 
> should be convertible between the arrow form and the colon form using a 
> simple, uniform rule.
> 
> (2) In switch expressions we want to be able to use the concise notation 
> `case a, b, c -> s;` for a switch clause.
> 
> (3) From (1) and (2) we inexorably conclude that `case a, b, c: break s;` 
> must also be a valid syntax.
> 
> (4) But we could also have written (3) as `case a: case b: case c: break s;` 
> and we certainly expect them to have equivalent behavior.
> 
> (5) From (1) and (4) we conclude that we ought also be to be able to write 
> `case a -> case b -> case c -> s;`.
> 
> Not necessarily, if one simply views (4) as being an artifact of colonform 
> switch's capacity for fall-through, which we know should not carry over. 
> (Although we technically don't use the term "fall-through" in this 
> no-intervening-code case, it works the same way and many people do think of 
> it that way.)

You could view it that way—but such a view is incorrect, going back to JLS1.

I know that many people develop alternate “folk models” for how they think 
things work or ought to work, but sometimes such alternate models lead one 
astray.  This is one such instance.  This is why we have a spec.

My argument does not rely on fallthrough; it relies on the notion of a case 
label being “associated with” a statement.  JLS is quite clear on this.

To be more explicit about assumption (1) above: I propose the simple, uniform 
rule that the way to convert colon form to arrow form is to (a) replace every 
colon in a SwitchLabel with an arrow, then (b) add braces and “break” where 
necessary (and the rules for this depend on whether you are converting a 
statement switch or an expression switch).  The point of this definition is 
that step (a) need not require any exceptions or special cases.

—Guy
 

Re: JEP325: Switch expressions spec

2018-04-23 Thread forax
'->' being a two characters symbol (at least if you do not enable font ligature 
of your IDE/editor) is a more strong separator than comma ',',
so i think it's easy to visually parse
  case pat1, pat2 -> s
as
  case [pat1, pat2] -> s
than
  case pat1, [pat2 -> s]

Rémi

- Mail original -
> De: "Guy Steele" 
> À: "Remi Forax" 
> Cc: "amber-spec-experts" 
> Envoyé: Lundi 23 Avril 2018 20:32:26
> Objet: Re: JEP325: Switch expressions spec

>> On Apr 23, 2018, at 2:27 PM, Guy Steele  wrote:
>> 
>> Good point, Rémi.  However, note that
>> 
>>  case pat1, pat2 -> s
>> 
>> is equally too close to
>> 
>>  case pat1 -> pat2 -> s
>> 
>> and again they have very different meanings.
>> 
>> We have to admit that there is room to blunder with this syntax.
>> 
>> One way out would be to use a different arrow for `switch` statements:
>> 
>>  switch (x) {
>>  case pat1 => case pat2 => s1;
>>  case pat3 => pat4 -> s2;
>>  case pat5, pat6 => s2;
>>  case pat7, pat8 => pat9 -> s4;
>>  }
> 
> As a careful coder, if I did not have a separate arrow `=>` (and probably even
> if I did), I would use formatting and parentheses to convey my intent:
> 
>   switch (x) {
>   case pat1 ->
>   case pat2 -> s1;
>   case pat3 -> (pat4 -> s2);
>   case pat5, pat6 -> s2;
>   case pat7, pat8 -> (pat9 -> s4);
>   }
> 
> —Guy


Re: JEP325: Switch expressions spec

2018-04-23 Thread Guy Steele

> On Apr 23, 2018, at 2:27 PM, Guy Steele  wrote:
> 
> Good point, Rémi.  However, note that
> 
>   case pat1, pat2 -> s
> 
> is equally too close to
> 
>   case pat1 -> pat2 -> s
> 
> and again they have very different meanings.
> 
> We have to admit that there is room to blunder with this syntax.
> 
> One way out would be to use a different arrow for `switch` statements:
> 
>   switch (x) {
>   case pat1 => case pat2 => s1;
>   case pat3 => pat4 -> s2;
>   case pat5, pat6 => s2;
>   case pat7, pat8 => pat9 -> s4;
>   }

As a careful coder, if I did not have a separate arrow `=>` (and probably even 
if I did), I would use formatting and parentheses to convey my intent:

switch (x) {
case pat1 ->
case pat2 -> s1;
case pat3 -> (pat4 -> s2);
case pat5, pat6 -> s2;
case pat7, pat8 -> (pat9 -> s4);
}

—Guy



Re: JEP325: Switch expressions spec

2018-04-23 Thread Guy Steele
Good point, Rémi.  However, note that

case pat1, pat2 -> s

is equally too close to

case pat1 -> pat2 -> s

and again they have very different meanings.

We have to admit that there is room to blunder with this syntax.

One way out would be to use a different arrow for `switch` statements:

switch (x) {
case pat1 => case pat2 => s1;
case pat3 => pat4 -> s2;
case pat5, pat6 => s2;
case pat 7, pat8 => pat9 -> s4;
}

> On Apr 23, 2018, at 2:29 PM, Remi Forax  wrote:
> 
> I agree with Kevin,
>   case pat1 -> case pat2 -> s
> is too close to
>   case pat1 -> pat2 -> s
> which has a very different meaning (the result is a lambda).
> 
> Rémi



Re: JEP325: Switch expressions spec

2018-04-23 Thread Guy Steele

> On Apr 23, 2018, at 2:02 PM, Kevin Bourrillion  wrote:
> 
> On Fri, Apr 20, 2018 at 11:55 AM, Guy Steele  > wrote:
> 
> You know, if s2 is short (say, less than 30 or 40 characters), there are 
> worse things than writing
> 
>  case A -> s1;
>  case null -> s2;
>  default   -> s2;
> 
> especially if you use spaces (as I just did) to line up the two occurrences 
> of s2 to make it easy to see they are identical.
> 
> And if s2 is long, there are worse things than making a little sub method to 
> handle it:
> 
>  case A -> s1;
>  case null -> frobboz(a, b);
>  default   -> frobboz(a, b);
> 
> int frobboz(int a, String b) { … }
> 
> And if even THAT is not satisfactory, well, there are worse things than 
> giving up on the arrows and just using colons (and break, if needed).
> 
> I think neither of these goes down well. Having to repeat yourself at all, 
> while normal cases get to use comma, will feel very wrong. Having to abandon 
> arrowform over this would be even worse.
> 
> 
> BUT, on the other hand, if we wanted to: instead of, or in addition to,
> 
> case pat1, pat2, pat3 -> s;
> 
> we could allow the form
> 
> case pat1 -> case pat2 -> case pat3 -> s;
> 
> This seems like a step backward to me (whether it is instead or in addition).
> 
> fwiw, I think `default, case null ->` is superior to all of these options.

As an ad-hoc patch that solves this one problem, I agree.

But let me make a revised pitch for allowing it “in addition to” (which, now 
that I have pondered it over the weekend, I think is clearly the correct 
approach).

(1) We have moved toward allowing “arrow versus colon” to be a syntax choice 
that is COMPLETELY orthogonal to other choices about the use of `switch`.  If 
this rule is to hold universally, then any switch statement or expression 
should be convertible between the arrow form and the colon form using a simple, 
uniform rule.

(2) In switch expressions we want to be able to use the concise notation `case 
a, b, c -> s;` for a switch clause.

(3) From (1) and (2) we inexorably conclude that `case a, b, c: break s;` must 
also be a valid syntax.

(4) But we could also have written (3) as `case a: case b: case c: break s;` 
and we certainly expect them to have equivalent behavior.

(5) From (1) and (4) we conclude that we ought also be to be able to write 
`case a -> case b -> case c -> s;`.

Notice that so far I have said nothing about the “default and null” problem 
being a motivation.  It’s all about preserving assumption (1).

The issue with default and null has nothing to do with the issue of arrow 
versus colon.  It *does* have to do with the issue of repeating the `case` 
keyword versus listing multiple values (or patterns) by using commas after a 
single `case` keyword: `default` does not play well with the comma-separated 
case when you use colons, so there is no reason to expect it to play well when 
you use arrows.  Trying to make a special-case exception for `default` in the 
arrow case requires making a similarly ugly exception in the colon case if 
assumption (1) is to be preserved.

I argue that there is no need to make the special-case exception for `default`. 
 When you need to play that game (usually because null needs to be addressed), 
you cannot use the comma-separation syntax.  Instead, just say either

case null: default: s;  (or, if you prefer, `default: 
case null: s;`)

or

case null -> default -> s;  (or, if you prefer, `default -> 
case null -> s;`)

depending on whether your `switch` is using colon syntax or arrow syntax.  The 
latter is just two characters longer than `default, case null -> s;` and has a 
much simpler and more consistent underlying theory.

—Guy



Re: JEP325: Switch expressions spec

2018-04-23 Thread Remi Forax
I agree with Kevin, 
case pat1 -> case pat2 -> s 
is too close to 
case pat1 -> pat2 -> s 
which has a very different meaning (the result is a lambda). 

Rémi 

> De: "Kevin Bourrillion" 
> À: "Guy Steele" 
> Cc: "amber-spec-experts" 
> Envoyé: Lundi 23 Avril 2018 20:02:30
> Objet: Re: JEP325: Switch expressions spec

> On Fri, Apr 20, 2018 at 11:55 AM, Guy Steele < [ mailto:guy.ste...@oracle.com 
> |
> guy.ste...@oracle.com ] > wrote:

>> You know, if s2 is short (say, less than 30 or 40 characters), there are 
>> worse
>> things than writing

>> case A -> s1;
>> case null -> s2;
>> default -> s2;

>> especially if you use spaces (as I just did) to line up the two occurrences 
>> of
>> s2 to make it easy to see they are identical.

>> And if s2 is long, there are worse things than making a little sub method to
>> handle it:

>> case A -> s1;
>> case null -> frobboz(a, b);
>> default -> frobboz(a, b);

>> int frobboz(int a, String b) { … }

>> And if even THAT is not satisfactory, well, there are worse things than 
>> giving
>> up on the arrows and just using colons (and break, if needed).

> I think neither of these goes down well. Having to repeat yourself at all, 
> while
> normal cases get to use comma, will feel very wrong. Having to abandon
> arrowform over this would be even worse.

>> BUT, on the other hand, if we wanted to: instead of, or in addition to,

>> case pat1, pat2, pat3 -> s;

>> we could allow the form

>> case pat1 -> case pat2 -> case pat3 -> s;

> This seems like a step backward to me (whether it is instead or in addition).

> fwiw, I think `default, case null ->` is superior to all of these options.

> --
> Kevin Bourrillion | Java Librarian | Google, Inc. | [ 
> mailto:kev...@google.com |
> kev...@google.com ]


Re: JEP325: Switch expressions spec

2018-04-20 Thread Guy Steele

> On Apr 20, 2018, at 2:55 PM, Guy Steele  wrote:
> . . .
> Motto: “It’s not fallthrough, it’s just a SwitchBlockStatementGroup.”

So the syntactic explanation for switch expressions would generalize from

"case a -> s;" means "case a: break s;”

to

"case a -> case b -> … case z -> s;" means "case a: case b: … case 
z: break s;”



Re: JEP325: Switch expressions spec

2018-04-20 Thread Guy Steele
You know, if s2 is short (say, less than 30 or 40 characters), there are worse 
things than writing

 case A -> s1;
 case null -> s2;
 default   -> s2;

especially if you use spaces (as I just did) to line up the two occurrences of 
s2 to make it easy to see they are identical.

And if s2 is long, there are worse things than making a little sub method to 
handle it:

 case A -> s1;
 case null -> frobboz(a, b);
 default   -> frobboz(a, b);

int frobboz(int a, String b) { … }

And if even THAT is not satisfactory, well, there are worse things than giving 
up on the arrows and just using colons (and break, if needed).

Yeah, null makes things uglier, but at least you have your choice of three 
different kinds of ugly.
_

BUT, on the other hand, if we wanted to: instead of, or in addition to,

case pat1, pat2, pat3 -> s;

we could allow the form

case pat1 -> case pat2 -> case pat3 -> s;

which of course could be stacked vertically for visual graciousness and 
perspicuity:

case pat1 ->
case pat2 ->
case pat3 -> s;

and such a format would clearly accommodate

case A -> s1;
case null ->
default -> s2;

Con: Could look like a programming error (unintentionally omitted statement), 
but that’s also true for the colon forms already permitted.
Con: More verbose than the comma-separated form `case pat1, pat2, pat3 ->`, 
which may matter for smallish switch expressions.
Pro: Doesn’t stick `default` in a weird place, or otherwise make a special rule 
just to handle “default and null”.
Pro: The keyword `case` appears in front of EVERY individual pattern, making 
them easier to see.
Pro: Avoids possible confusion between `case a,b,c ->` and `case (a,b,c) ->`.

Motto: “It’s not fallthrough, it’s just a SwitchBlockStatementGroup.”

> On Apr 20, 2018, at 2:40 PM, Brian Goetz  wrote:
> 
> One thing that is relevant to the short term is that now that we killed mixed 
> labels, we'd have to have a way to say "case null or default" in arrow world. 
>  The least stupid thing seems to be to allow default to be tacked on to a 
> comma-separated case list as if it were a pattern: 
> 
> case A -> s1;
> case null, default -> s2;
> 
> since you can no longer say:
> 
> case A -> s1;
> case null:
> default:
> s2;



Re: JEP325: Switch expressions spec

2018-04-20 Thread Brian Goetz
One thing that is relevant to the short term is that now that we killed 
mixed labels, we'd have to have a way to say "case null or default" in 
arrow world.  The least stupid thing seems to be to allow default to be 
tacked on to a comma-separated case list as if it were a pattern:


    case A -> s1;
    case null, default -> s2;

since you can no longer say:

    case A -> s1;
    case null:
    default:
    s2;


On 4/20/2018 2:36 PM, Kevin Bourrillion wrote:
On Fri, Apr 20, 2018 at 10:45 AM, Brian Goetz > wrote:



So, all I'm asking is: can we make this particular change
atomically with patterns itself, not before? I believe that the
change has negative value until then because it is too easy to
use it to write bugs. (If this means that long and booleanalso
wait until then, I don't think anyone would really mind. If
necessary I can look up how common
simulated-switch-on-longhappens in our codebase, but we all know
it won't be much.)

The extra primitive types are separable, so could be deferred. 
I'd be less sanguine about adding long now but not float.


Agreed, it would seem weird to keep adding more piecemeal over and over.


Separately but similarly, the merits of case null: have also been
justified almost entirely in the context of patterns. Without
patterns, I believe the benefits are far too slight. We studied
six digits' worth of switch statements in the Google codebase,
using a /liberal/ interpretation of whether they are simulating a
null case, and came up with ... 2.4%.  (You will find that
suspicious as hell, since it's the exact same percentage I cited
for fall-through yesterday, but I swear it's a coincidence!)

More nervous about this.  Would rather start the education curve
on this earlier. And there are plenty of existing switches that
are wrapped with "if target != null" that would be clearer/have
less needless repetition by pushing the case null into the switch.


Er - just clarifying that this is the /same/ 2.4% that I am referring 
to. Of course, numbers will vary (and I concede that we are quite 
toward the null-hostile end of the spectrum in our general dev 
practices). Still, I'm sure we would not be making this change for 
this reason alone, so it really is about this issue of "starting the 
education curve earlier". Trying to figure out how much that matters.


For what it's worth, Guava took the position at the start that, since 
working with null is risky and problematic, it's /okay/ if code that 
deals with null is uglier than code that doesn't. It's only natural, 
so we don't bend over backwards to try to smooth it over. If that 
decision has played /some/ /small/ part in helping shift the world 
away from rampant overuse of null everywhere, we wouldn't regret it a 
bit. I think JDK collections post-1.4 could say the same thing to a 
larger degree. Okay, I guess this is just the "moral hazard" argument 
stated a different way - sorry.


(Full disclosure: if you accuse me of wanting more time before `case 
null:` lands just so I have more time to try to talk us out of it 
completely, I suppose have no defense to that. :-))


--
Kevin Bourrillion | Java Librarian | Google, Inc. |kev...@google.com 





Re: JEP325: Switch expressions spec

2018-04-20 Thread Guy Steele

> On Apr 20, 2018, at 1:37 PM, Kevin Bourrillion  wrote:
> 
> On Wed, Apr 18, 2018 at 11:16 AM, Kevin Bourrillion  > wrote:
> 
> If one of the patterns is a constant expression or enum constant that is 
> equal to the value of the selector expression, then we say that the 
> patternmatches.
> 
> I think "equal" is ambiguous for strings (and will be for doubles when they 
> happen).
> 
> Whoops: I belatedly noticed that we are expanding to all primitive types 
> already. Okay. So, unless I missed it somewhere, I think we need to specify 
> that all comparisons are made as if by equals() on the (boxed) type (or 
> whatever better way to word it). We might even want to call out the specific 
> consequences that case NaN: works as expected, and that 0.0 and -0.0 are 
> fully distinct despite being ==.
> 
> But here is the real wrench I want to throw in the works... (and I apologize, 
> as always, if I am unknowingly rehashing old decisions that were already 
> finalized):
> 
> The most compelling reason to support float and double switches is the fact 
> that pattern matching will automatically cover them via boxing anyway. If it 
> were not for that, I believe it is a feature with too much risk to be useful. 
> case 0.1: simply does not mean what any developer would wish it to mean. At 
> Google we spend real effort trying to get our developers to depend less on 
> exact floating-point equality, not more.

I agree that it would (almost always) be insane to write `case 0.1:`.

However, it may actually be extremely attractive for some purposes to write 
something like:

switch (x) {
case NaN -> foo;
case Double.NEGATIVE_INFINITY -> bar;
case Double.POSITIVE_INFINITY -> baz;
case +0.0 -> quux;
case -0.0 -> ztesch;
default -> frobboz(x);
}

and I can even imagine `case 1.0 ->` or `case 2.0 ->` sneaking in as special 
cases on occasion.

You don’t always want to write library code this way—rather, analysis may show 
that `frobboz` computes the desired results for some or all of the special 
cases.  But when code clarity is more important than that last ounce of speed, 
this is a very clear way to say what you want.

Seems to me that the compiler could certainly warn about case labels such as 
0.1 that suffer rounding during the decimal-to-binary conversion.  Or about any 
category of cases label we wish to denigrate.

—Guy



Re: JEP325: Switch expressions spec

2018-04-20 Thread Brian Goetz


So, all I'm asking is: can we make this particular change atomically 
with patterns itself, not before? I believe that the change has 
negative value until then because it is too easy to use it to write 
bugs. (If this means that long and booleanalso wait until then, I 
don't think anyone would really mind. If necessary I can look up how 
common simulated-switch-on-longhappens in our codebase, but we all 
know it won't be much.)


The extra primitive types are separable, so could be deferred.  I'd be 
less sanguine about adding long now but not float.


Separately but similarly, the merits of case null: have also been 
justified almost entirely in the context of patterns. Without 
patterns, I believe the benefits are far too slight. We studied six 
digits' worth of switch statements in the Google codebase, using a 
/liberal/ interpretation of whether they are simulating a null case, 
and came up with ... 2.4%.  (You will find that suspicious as hell, 
since it's the exact same percentage I cited for fall-through 
yesterday, but I swear it's a coincidence!)


More nervous about this.  Would rather start the education curve on this 
earlier. And there are plenty of existing switches that are wrapped with 
"if target != null" that would be clearer/have less needless repetition 
by pushing the case null into the switch.





Re: JEP325: Switch expressions spec

2018-04-18 Thread Brian Goetz

All good points.  Minor comments inline.

|Were we considering allowing `case /something/, default:` or 
`default, case /something/:`? Of course you would never ever actually 
/need/ this... except in the one case that /something/ is null. In a 
switch expression it would be sad to be forced to revert to the old 
syntax for only this reason.|


|This may well be needed, especially if we prohibit fallthrough from a 
colon label into a arrow label.


Another case where a simliar problem arises is this:

    case null:
    case String s:
    // whoops, s is not DA here

Really, we'd like to say

    case null s, String s:

or

    case (null | String) s:

or something similar.  We don't have to cross this until we get to type 
patterns, but it's on the horizon.


|


Re: JEP325: Switch expressions spec

2018-04-18 Thread Alex Buckley

On 4/18/2018 11:16 AM, Kevin Bourrillion wrote:

Evaluation of an expression can produce side effects, because
expressions may contain embedded assignments, increment operators,
decrement operators, and method invocations. *In addition, lambda
expressions and switch expressions have bodies that may contain
arbitrary statements.

A lambda "contains" statements /physically/, but nothing gets
executed. If anything, it is anonymous /classes/ that belong here
(though maybe, arguably, that would be covered if "method invocations"
was changed to "method or constructor invocations"?).


The goal was to highlight that a lambda/switch expression is not like 
(say) a field access expression, because of the ability to have a body 
of statements rather than merely a tree of subexpressions ... but you're 
right, "Evaluation of a lambda expression is distinct from execution of 
the lambda body." (JLS 15.27.4)



Suggestion: "... because expressions may contain embedded assignments,
increment operators, decrement operators, and method or constructor
invocations, as well as arbitrary statements nested inside a switch
expression."


Yes, limiting the arbitrariness to switch expressions (the sole "home" 
for something-resembling-block-expressions) is right.


Alex


Re: JEP325: Switch expressions spec

2018-04-16 Thread Gavin Bierman
Thanks Maurizio. Some replies inline.

> On 13 Apr 2018, at 12:15, Maurizio Cimadamore 
>  wrote:
> 
> Looks neat. Some comments:
> 
> * I note that you introduced patterns to describe the new syntactic options; 
> while that's a completely fine choice, I wonder if it could lead to confusion 
> - I always thought of JEP 325 as a set of standalone switch improvements, 
> which don't need the P-word to be justified. Of course, I'm not opposed to 
> what you have done, just noting (aloud) the mismatch with my expectations.

Yes, you spotting me setting things up for a future release :-) But in my 
defence: in the current spec, we say “case constant” where constant is either a 
constant expression or an enum constant. We are adding to this the possibility 
of a “null”, so we need to find another word anyhow. That said, I think you 
have a point, so I’ll look again to see if I can dial it down a bit. 

> 
> * in 14.11 I find these sentences:
> 
> "then we say that the null pattern matches", "then we say that the pattern 
> matches"
> 
> A bit odd to read , as the transitive verb 'matches' is missing its object.

I know what you mean, but the spec today already states “...then we say that 
the case label *matches*.” So I actually kept that text as it is. 

> 
> * also I note some replication:
> 
> "If all these statements complete normally, or if there are no statements 
> after the pattern label containing the matching pattern, then the entire 
> switch statement completes normally."
> "If all these statements complete normally, or if there are no statements 
> after the pattern label containing the matching pattern, then the entire 
> switch statement completes normally."
> "If all these statements complete normally, or if there are no statements 
> after the default pattern label, then the entire switch statement completes 
> normally."
> 
> The first two are identical, the last only slightly different, perhaps 
> something can be done to consolidate

I’ll take another look.

> 
> * "A break statement either transfers control out of an enclosing statement 
> or returns a value to an immediately enclosing switch expression."
> 
> Is it an either/or? My mental model is that break always transfer controls 
> out - it can do so with a value, or w/o a value (as in a classic break).

This is a good question, although probably only one for spec-nerds. The problem 
is that the concept of “transfer of control” is only valid for statements - in 
essence you jump from one statement to the other. There is no concept in the 
JLS of control for *expressions*. So you can’t really say that the break 
statement with a value transfers control to an *expression*. This is what is so 
“unusual” about switch expressions, they are expressions with statements 
inside...

This either/or distinction makes clear, for better or for worse, the new dual 
nature of break statements: they either transfer control to another statement, 
or they end up returning a value to an enclosing expression.


> 
> * I like the fact that you define the semantics of the expression switch 
> clauses in terms of desugaring to statements blocks - this is consistent with 
> what we do in other areas (enhanced for loop, try with resources).

Thanks! Although, with the proposed change to forbid fall through from 
statement groups into clauses, I’m not sure they can stay.

> 
> * I suggest putting the paragraph in 15.29 starting with:
> 
> "Given a switch expression, all of the following must be true"
> 
> Ahead of the desugaring paragraph, which seems more 
> execution/semantics-related, while this one is still about well-formedness.

Yes! Thanks.


> * On totality - this line:
> 
> default -> 10; // Legal
> 
> deserves some more explanation - e.g. one might think it's unreachable, but 
> it's not because new constants could pop up at runtime; maybe add a 
> clarification.

Yes! Thanks.

> 
> * On non-returning, this sentence is obscure:
> 
> "Thus a switch expression block that can not complete normally, can only do 
> so by occurrences of a break statement with an Expression. This ensures that 
> a switch expression must either result in a value, or complete abruptly."
> 
> because it contradicts what is said just a line above:
> 
> "an occurrence of a break statement with an Expression in a switch expression 
> means that the switch expression will complete normally with the the value of 
> the Expression"
> 
> The way I read this is:
> 
> 1) the only way for the block after a 'case' in a switch pattern to complete 
> abnormally is via a break expression
> 2) even if the _block_ completes abnormally, the containing switch expression 
> will complete normally, with the value of Expression
> 
> Is that what you meant?

Yes, although I’m not sure I quite see the “contradiction”. I’ll take another 
look at this text.


> * At the end of the switch expression section there are sub-optimal sentences 
> like the one that appear for switch statem

Re: JEP325: Switch expressions spec

2018-04-13 Thread Maurizio Cimadamore

Looks neat. Some comments:

* I note that you introduced patterns to describe the new syntactic 
options; while that's a completely fine choice, I wonder if it could 
lead to confusion - I always thought of JEP 325 as a set of standalone 
switch improvements, which don't need the P-word to be justified. Of 
course, I'm not opposed to what you have done, just noting (aloud) the 
mismatch with my expectations.


* in 14.11 I find these sentences:

"then we say that the null pattern matches", "then we say that the 
pattern matches"


A bit odd to read , as the transitive verb 'matches' is missing its object.

* also I note some replication:

"If all these statements complete normally, or if there are no 
statements after the pattern label containing the matching pattern, then 
the entire switch statement completes normally."
"If all these statements complete normally, or if there are no 
statements after the pattern label containing the matching pattern, then 
the entire switch statement completes normally."
"If all these statements complete normally, or if there are no 
statements after the default pattern label, then the entire switch 
statement completes normally."


The first two are identical, the last only slightly different, perhaps 
something can be done to consolidate


* "A break statement either transfers control out of an enclosing 
statement or returns a value to an immediately enclosing switch expression."


Is it an either/or? My mental model is that break always transfer 
controls out - it can do so with a value, or w/o a value (as in a 
classic break).


* I like the fact that you define the semantics of the expression switch 
clauses in terms of desugaring to statements blocks - this is consistent 
with what we do in other areas (enhanced for loop, try with resources).


* I suggest putting the paragraph in 15.29 starting with:

"Given a switch expression, all of the following must be true"

Ahead of the desugaring paragraph, which seems more 
execution/semantics-related, while this one is still about well-formedness.


* On totality - this line:

default -> 10; // Legal

deserves some more explanation - e.g. one might think it's unreachable, 
but it's not because new constants could pop up at runtime; maybe add a 
clarification.


* On non-returning, this sentence is obscure:

"Thus a switch expression block that can not complete normally, can only 
do so by occurrences of a break statement with an Expression. This 
ensures that a switch expression must either result in a value, or 
complete abruptly."


because it contradicts what is said just a line above:

"an occurrence of a break statement with an Expression in a switch 
expression means that the switch expression will complete normally with 
the the value of the Expression"


The way I read this is:

1) the only way for the block after a 'case' in a switch pattern to 
complete abnormally is via a break expression
2) even if the _block_ completes abnormally, the containing switch 
expression will complete normally, with the value of Expression


Is that what you meant?

* At the end of the switch expression section there are sub-optimal 
sentences like the one that appear for switch statements (e.g. "pattern 
matches") - see above.


Cheers

Maurizio

On 12/04/18 22:27, Gavin Bierman wrote:

I have uploaded a draft spec for JEP 325: Switch expressions at 
http://cr.openjdk.java.net/~gbierman/switch-expressions.html

Note there are still three things missing:

* There is no text about typing a switch expression, as this is still being 
discussed on this list.
* There is no name given for the exception raised at runtime when a switch 
expression fails to find a matching pattern label, as this is still being 
discussed on this list.
* The spec currently permits fall through from a "case pattern:” statement group into a 
"case pattern ->" clause. We are still working through the consequences of removing 
this possibility.

Comments welcomed!
Gavin