> On May 20, 2019, at 12:16 PM, Brian Goetz <brian.go...@oracle.com> wrote: > >> But I now think that this argument is weak, because I believe it is in fact >> unlikely that there will be a large number of other statement types that we >> will want to turn into expressions. >> >> * Yes, we may want block expressions. >> * We would want `if`-statement expressions _except_ that we already >> have the ternary operator ? :, so I don’t really think there is a pressing >> need. >> * As a Common Lisp programmer, I can see the value of having a `for` >> loop produce a value. But I very much doubt that Joe Java-programmer wants >> that. >> * And if we don’t want values from `for` loops, I doubt there will be >> much demand for values from `while` loops or `try` statements. > > While I agree about if / for / while, I’m not completely convinced on `try`; > the notion of “produce a value or throw” is a common one, and has all the > same advantages over a try statement that a switch expression has over a > switch statement — that initialization of variables with side-effectful > statements is messier and more error-prone than with expressions. So, for > example, the not-so-uncommon idiom: > > static final Foo foo; > static { > try { > foo = new Foo(); > } > catch (FooException fe) { > throw new OtherKindOfException(fe); > } > } > > leaves, well, room for improvement. Let’s just register that as something we > might want to do someday.
Sure, I concede that I was hasty on this one. > Another form of expression that might have statements in it is some sort of > “let” or “with” expression; it is not uncommon enough to have to execute > statements to produce a result: > > Foo f = new Foo(); > f.setBar(1); > return f; > > which similarly would like to be replaced with an expression. (let’s not > design this here, the point is that this is a road we might well want to walk > again some day.) But that’s easily handled by a block expression. (Java doesn’t already have a `let` or `with` statement precisely because being able to intersperse declarations with statements in a block does that job quite nicely.) <bikeshed level=“hyper"> So, for fun, I’m going to taste-test these two excellent examples. Offhand I see no problem with using the `try` keyword in the middle of an expression, just as we did for `switch`, so: static final Foo = try { break: new Foo(); } catch (FooException fe) { throw new OtherKindOfException(fe); }; Perhaps more interesting is returning a default value if a FooException occurs—and maybe we can tighten up the main body by using parentheses: static final Foo = try (new Foo()) catch (FooException fe) { break: myDefaultFoo; }; and maybe even the `catch` body could be tightened up in the same way: static final Foo = try (new Foo()) catch (FooException fe) (myDefaultFoo); As for the other one: ({ Foo f = new Foo(); f.setBar(1); f }) looks pretty good me. None of this is to make an actual proposal that this is best or even good, or that we should do it soon; it’s just to see whether there is something plausible available. </bikeshed>