Proposal: Block Expressions for Java

Neal Gafter neal at gafter.com
Fri Mar 6 12:58:40 PST 2009


The places I would have found this most useful are in a super()
invocation, where you simply can't write a local variable before, and
in a control-flow expression of one sort or another, like ?:, &&, ||,
or on the right-hand-side of an assert statement.  This kind of thing
is particularly useful in automatically-generated code.

On Fri, Mar 6, 2009 at 12:50 PM, Tim Peierls <tim at peierls.net> wrote:
> I kind of like Neal's block expression proposal, but I am struggling to find
> more compelling examples for it. Instead of
>
> *super((double pi = Math.PI ; pi*pi)**);*
>
> it would be clearer to write
>
> *super(Math.PI * Math.PI**);*
>
> Instead of
>
> public static final Map<Integer,Integer> primes = (
>    Map<Integer,Integer> t = new HashMap<Integer,Integer>();
>    t.put(1, 2); t.put(2, 3); t.put(3, 5); t.put(4, 7);
>    Collections.unmodifiableMap(t));
>
> it would be better to use a Builder like the one in Google Collections'
> ImmutableMap:
>
> public static final ImmutableMap<Integer, Integer> PRIMES =     new
> ImmutableMap.Builder<Integer, Integer>()
>        .put(1, 2).put(2, 3).put(3, 5).put(4, 7)
>        .build();
>
> That particular example could in turn be rewritten more simply as
>
> public static final ImmutableMap<Integer, Integer> PRIMES =
>    ImmutableMap.of(1, 2, 2, 3, 3, 5, 4, 7);
>
> So while I understand the intention behind these examples, I think they
> could be improved.  Any ideas?
>
> What I like about the proposal is the ability to add side-effects in places
> I currently can't without distorting the existing logic. For example, let's
> say I want to add logging of the value computed in the while-loop test
> of this fragment:
>
> while (jobsRemaining() > 0) {
>    processSomeJobs();
> }
>
> I could write:
>
> int j = jobsRemaining();
> log.info("jobs remaining = %d", j);
> while (j > 0) {
>    processSomeJobs();
>    j = jobsRemaining();
>    log.info("jobs remaining = %d", j);
> }
>
> but that means repeating the logging statement and introducing a variable j
> with scope greater than the while loop. If I don't introduce a variable I
> have to repeat the call to jobsRemaining(), which might not be appropriate
> if it's an expensive call (and I'd still have to repeat the logging call).
>
> I could write a helper method instead:
>
> int computeAndLogJobsRemaining() {
>    int j = jobsRemaining();
>    log.info("jobs remaining = %d", j);
>    return j;
> }
> ...
> while (computeAndLogJobsRemaining() > 0) {
>    processSomeJobs();
> }
>
> but that's adding a lot of machinery for something as conceptually simple as
> this. Similarly for solutions involving method interception.
>
> The proposed enhancement would (I think) let me write something like this:
>
> while ((
>    int j = jobsRemaining();
>    log.info("jobs remaining = %d", j);
>    j > 0
> )) {                    // are two levels of parens necessary?
>    processSomeJobs();
> }
>
> which is exactly what I wanted to say, without having to change the
> structure of the original code.
>
> Could I get along without this? Absolutely.  Would I find it useful?  Yes,
> occasionally it would be quite handy.
>
> --tim
>
>



More information about the coin-dev mailing list