Why was the yield keyword introduced for switch expressions? (not just use return keyword)

623 Views Asked by At

When a return statement occurs within a lambda expression, it simply causes a return from the lambda. It does not cause an enclosing method to return.

So, for switch expressions why the keyword yield had introduced while return keyword could have been used instead? The first return for returning from method and the inside one for return from switch statement.

class TestClass {
    public int testMethod() {
        // ...
        int a = switch (allOptions) {
            case "case1" -> {
                System.out.println("case 1");
                return 1;
            }
            default -> {
                System.out.println("default");
                return -1;
            }
        };

        return a;
    }
}

Consider this example for lambda expressions:

class TestClass {
    interface FunctionalInterface {
        int test(int n);
    }
    
    public int testMethod() {

        FunctionalInterface f = (n) -> {
            return n * 2;
        };

        return f.test(10);
    }
}

Is there any special reason for that?

Why return keyword is confusing in first example and not confusing in the second one?

3

There are 3 best solutions below

0
On BEST ANSWER

Originally, when switch expressions were introduced in JEP 325, it was proposed that break should be used to yield a value.

int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        break result;
    }
};

It was changed to yield in JEP 354. It was mentioned that:

The two statements, break (with or without a label) and yield, facilitate easy disambiguation between switch statements and switch expressions: a switch statement but not a switch expression can be the target of a break statement; and a switch expression but not a switch statement can be the target of a yield statement.

Which could be seen as a reason for the change. Using return for this certainly would not "facilitate easy disambiguation between switch statements and switch expressions", since you can also return in switch statements.

Then, in JEP 361, it was further explained that overloading break was "confusing".

One aspect of JEP 325 was the overloading of the break statement to return a result value from a switch expression. Feedback on JDK 12 suggested that this use of break was confusing. In response to the feedback, JEP 354 was created as an evolution of JEP 325.

I would imagine overloading return would also be "confusing".

Being able to return from a lambda expression isn't exactly "overloading" return in the same sense. The bodies of lambda expressions represent function bodies. It would make sense for return to return from functions. The body of a switch expression, isn't a function.

3
On

Personally, I find it intuitive to use the yield keyword in switch expressions. It helps to distinguish between returning a value from a method and returning a value from a switch expression.

So, it seems to be a matter of readability and the architect's choice, rather than any functional difference.

0
On

"When a return statement occurs within a lambda expression, it simply causes a return from the lambda. It does not cause an enclosing method to return. ..."

A lambda expression is a closure, so it's actually returning from a method, within that scope.

"... So, for switch expressions why the keyword yield had introduced while return keyword could have been used instead? ..."

Using the return keyword here would have overlapped its meaning.

It's important to disseminate when you want to simply return from the switch and when you want to return from the enclosing method.

A lot of things in Java are written out more than logically required, purposely.
An underlying quality of Java is that you can read the code as if it were a sentence—similar to Objective-C.