Comments/Feature Requests regarding JEP 305: Pattern Matching
Brian Goetz
brian.goetz at oracle.com
Thu Jul 6 18:27:22 UTC 2017
There are really at least three separate requests here.
1. Don't make me provide a name if I don't need one.
2. Please provide flow-typing so that I can just reuse the target.
(And with instanceof too, thanks.)
3. Don't make me provide unique names for every binding.
#1 is well in hand; you can always use an unnamed binding (_), and we
may make bindings optional as well.
#2 sounds nice, but runs out of gas pretty quickly. Sometimes the
switch target is not a variable, but an expression; repeating the
expression is undesirable (especially if there are side-effects.)
#3 is taken care of by our scoping rules. You can re-use binding
variable names:
case Integer x:
case Double x:
case Float x:
A variant of #2 would be to allow the user to explicitly re-use (and
hence shadow) the target:
switch (p) {
case Integer p:
case Double p:
case Float p:
}
We might consider that, as it is in line with another shadowing-related
change we're making as part of Lambda Leftovers.
On 7/5/2017 4:34 PM, William Shackleford wrote:
> In the examples provided in the JEP it looks as though it would always be
> required to provide new
> variable names each time a pattern match is used.
>
> Could we eliminate the new variable names or make them optional?
> As written it doesn't seem to completely provide the benefits of flow
> typing.
>
> This would have the following benefits.
>
> 1. It is more compact.
> 2. It reduces the number of variable names you need to think of when
> writing code.
> 3. It reduces the chances of needing one variable name to shadow another.
> 4. It is easier to see if a variable is used or modified if it is only
> referenced with one name.
>
>
> For example
>
> String formatted;
> switch (p) {
> case Integer i: formatted = String.format("int %d", i); break;
> case Byte b: formatted = String.format("byte %d", b); break;
> case Long l: formatted = String.format("long %d", l); break;
> case Double d: formatted = String.format(“double %f", d); break;
> case String s: formatted = String.format("String %s", s); break
> default: formatted = obj.toString();
> }
>
> would change to
>
>
> String formatted;
> switch (p) {
> case Integer: formatted = String.format("int %d", p); break;
> case Byte: formatted = String.format("byte %d", p); break;
> case Long: formatted = String.format("long %d", p); break;
> case Double: formatted = String.format(“double %f", p); break;
> case String: formatted = String.format("String %s", p); break
> default: formatted = p.toString();
> }
>
>
> In the second one if i,b,l,d,s are other variables in scope there is no
> chance of misunderstanding that they have been shadowed by the new
> variables. If you look for where is p used, the answer in both cases is all
> the format calls but thats easier to
> see at a glance in the second example. Generally the variable name p would
> give one insight into the source or purpose of that variable which is lost
> if you change to a variable name chosen just to indicate the type, or the
> variable names end up too long if one always appends the type info to the
> source and/or purpose info in the name.
>
>
> Also :
>
> int eval(Node n) {
> switch(n) {
> case IntNode(int i): return i;
> case NegNode(Node n): return -eval(n);
> case AddNode(Node left, Node right): return eval(left) +
> eval(right);
> case MulNode(Node left, Node right): return eval(left) *
> eval(right);
> default: throw new IllegalStateException(n);
> };
> }
>
>
>
> could be written more concisely as
>
>
> int eval(Node n) {
> switch(n) {
> case IntNode: return n.i;
> case NegNode: return -eval(n.n);
> case AddNode: return eval(n.left) + eval(n.right);
> case MulNode: return eval(n.left) * eval(n.right);
> default: throw new IllegalStateException(n);
> };
> }
>
>
> In addition to being more concise:
> n is not both used as the positive part of the NegNode and as the input
> parameter.
> It works with classes that have more fields/methods than constructor
> arguments.
> It seems to me that is better to consistently use a single syntax style
> rather than having one for classes
> that have only one or two fields that happen to match the constructor
> arguments and another more
> general style. This is especially true given that it doesn't even seem to
> make the code more concise.
>
>
> -- Will
More information about the amber-dev
mailing list