Comments/Feature Requests regarding JEP 305: Pattern Matching

William Shackleford wshackle at gmail.com
Wed Jul 5 20:34:07 UTC 2017


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