Yes, this is a clear improvement to the example code.

That said, I am always (or at least now) a bit leery of language designers 
motivating a new language feature by pointing out that it would make a compiler 
easier to write. As I have learned the hard way on more than one language 
project, compilers are not always representative of typical application code. 
(Please consider this remark as only very minor pushback on the form of the 
argument.)

On Apr 15, 2022, at 5:36 PM, Brian Goetz 
<brian.go...@oracle.com<mailto:brian.go...@oracle.com>> wrote:




  *   asking if something fits in the range of a byte or int; doing this by 
hand is annoying and error-prone
  *   asking if casting from long to int would produce truncation; doing this 
by hand is annoying and error-prone




Here’s some real code I wrote recently that would benefit dramatically from 
this:


default CodeBuilder constantInstruction(int value) {
    return with(switch (value) {
        case -1 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_M1);
        case 0 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_0);
        case 1 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_1);
        case 2 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_2);
        case 3 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_3);
        case 4 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_4);
        case 5 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_5);
        default -> {
            if (value >= -128 && value <= 127) {
                yield ConstantInstruction.ofArgument(Opcode.BIPUSH, value);
            }
            else if (value >= -32768 && value <= 32767) {
                yield ConstantInstruction.ofArgument(Opcode.SIPUSH, value);
            }
            else {
                yield ConstantInstruction.ofLoad(Opcode.LDC, 
BytecodeHelpers.constantEntry(constantPool(), value));
            }
        }
    });
}


could become the less error-prone and uniform:


default CodeBuilder constantInstruction(int value) {
    return with(switch (value) {
        case -1 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_M1);
        case 0 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_0);
        case 1 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_1);
        case 2 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_2);
        case 3 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_3);
        case 4 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_4);
        case 5 -> ConstantInstruction.ofIntrinsic(Opcode.ICONST_5);
        case byte value -> ConstantInstruction.ofArgument(Opcode.BIPUSH, value);
        case short value -> ConstantInstruction.ofArgument(Opcode.SIPUSH, 
value);
        default -> ConstantInstruction.ofLoad(Opcode.LDC, 
BytecodeHelpers.constantEntry(constantPool(), value));
    });
}


​

Reply via email to