Feedback and comments on ARM proposal (original) (raw)

Joshua Bloch jjb at google.com
Mon Mar 9 16:24:35 PDT 2009


Joe,

Hi. Thanks so much for the comments (both typos and substantive)!

I have some reservations about the ARM proposal.

Many of your comments don't sound like reservations to me:) I may be misunderstanding you, but it sounds like you're saying that Java does need better support for resources with a block structured life cycle pattern. Then you rule out other approaches for various reasons.

Next, you say that "There are limitations in how well the desugaring fits all the use-cases of interest." This does sound like a reservation, but I'm not sure I understand it. I believe the proposed desugaring is good for the great majority of use-cases of interest. Moreover, it is far better than what people do today. Could you please provide examples of important use-cases where the proposed desugaring falls short?

Then you say "While managing block structure resources surely is a problem, a language solution is at or near the limit of the size of a coin." That too sounds like a reservation. But "at or near" is not "beyond." As proposed (and in the revision that I'll be issuing soon), the feature is a straightforward syntactic transformation, with no affect on the type system, class file format, backward compatibility, etc. The worst one can say is that it's a new statement form (like for-each). I do hope that such statement forms are in scope for Project Coin!

All else being equal and given the effort that would be involved, I'd prefer

a change that generally supported block-structured resources rather than "just" the IO related "Closeable" ones. I think doing this would include handling "close" methods that are not declared or expected to throw exceptions.

The proposed construct was designed to go beyond IO-related "Closeable" resources. I mentioned java.net.socket; java.sql.Connection, Statement, ResultSet, and java.awt.Graphics in the proposal, and the list was not meant to be exhaustive. I sincerely hope the construct works for the great majority of block-structured resources, whether or not their close/dispose/release/whatever method is defined to throw an exception. In fact, I'm not clear on the impact of whether the close method throws an exception. Please clarify.

( If any distinct handling is done for close methods that are not expected to throw exceptions, the test would probably need to be done on the dynamic type of the Throwable so that the Liskov substitution principle was followed. Assuming a degenerate exception could indicate it did and did not have a close method that threw exceptions, the runtime treatment of such an exception should not depend on the static type of the variable referring to the exception.

For example, perhaps reasonable semantics are for a Disposable resource to have a secondary exception during close added to the original exception's suppressed exception list while if "DisposableQuiet" resource gets an exception during close, the new exception should be propagated out with the old exception being suppressed?)

I am confused by this. Perhaps a concrete example would make it clear?

Here are a few responses to your interspersed comments:

Like the for-each statement (introduced in Java 1.5), the automatic resource management statement is a small piece of syntactic sugar with a very high power-to-weight ratio.

The for-each statement in JDK 5 was a clear win. While there were details of the design to be debated (what interface should be accepted, etc.) the basic semantics were uncontested: starting with the first element, one by one visit the next element of the structure until reaching the end. As has been discussed on the list, the desired semantics of the ARM blocks are less clear, such as how any secondary exception should be handled. I would expect the same behavior would not be appropriate in all cases. Also as noted on the list and in the proposal itself, there is a big difference in getting an exception on closing an input stream versus an output stream.

Only in retrospect do the for-each semantics seem clear. When we were working on the design, there were many tricky issues, some of which we got wrong initially (remember SimpleIterator?). There was great debate over exactly which types should qualify for the new construct (now I wish we had included CharSequence). I see the automatic resource management as another clear win, with a comparable amount of complexity.

* Is method resolution impacted?

No; although if multiple clean-up methods are supported, "close", "flush", there will need to be rules about which ones are called if more than one is present.

At this point, I think only one name will be supported (close), so the problem goes away. We went through the same conniptions with the for-each statement (Does it work on Iterator as well as Iterable? What happens if you implement both?).

*Ignoring certain *close failures - One shortcoming of the construct as described is that it does not provide a way for the programmer to indicate that exceptions thrown when closing a resource should be ignored. In the case of the copy method, ideally the program would ignore exceptions thrown when closing the InputStream, but not the OutputStream. There are several ways this could be achieved. What did you have in mind here? Different disposable interfaces? Annotations on the resource type?

Two interfaces is one possibility. Another is a second form of the statement, where the client code says "I don't care if this close succeeds or not." The former makes for cleaner client code, the latter allows finer-grained control. I'm ruling out annotations on previously discussed grounds ("the Hamilton principle").

Thinking a bit speculatively, if multi-catch and final rethrow are added, would that have any weird interactions if used with ARM blocks?

Not weird ones, but there is a synergy (noted in the proposa)l: implementation of automatic resource management would be easier with rethrow.

In related matters, I'm working on a writeup on the "finally" variation, an alternative I don't favor, and will send it out in the next day or two.

I think you needn't bother. Its main adherents are now happy with an interface-based version.

      Thanks again,

      Josh


More information about the coin-dev mailing list