> 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>

Reply via email to