Re: Closure syntax
On 10/04/2009 06:21 PM, Tom Anderson wrote:
On Sun, 4 Oct 2009, Joshua Cranmer wrote:
It's generally lesser known, as many of the closure adherents don't
want to make do with a Java "closures lite" solution (which is
essentially what FCM is: basically a way to define a function in the
middle of a method, as opposed to a true closure that handles control
flow of the enclosing [1] method).
Since when was that the "true" meaning of 'closure'? That's a genuine
question - i hadn't come across the idea of nonlocal control flow being
essential to closures before. Indeed, it seems to me like an incredibly
bad idea which definitely should not be in the language.
I suppose that FCM does provide full closures, strictly according to the
definition of closure. But then again, Java already has a limited form
of closures: inner classes, defined within methods, gain access to the
(final) local variables in scope.
This is roughly the story as I understand it:
It all begins, I think, with the try-finally construct. Whenever you
work with native resources, you typically need to open them and then
always close them, such that this becomes boilerplate:
SomeObject foo = /* get from somewhere */;
foo.open();
try {
// Magic foo operations
} finally {
foo.close();
}
The typical name for this is Automatic Resource Management (the ARM in
CICE+ARM). The idea is to be able to simplify that into:
with (foo.open()) {
// Magic foo operations
}
People then got the idea that it would be nice to be able to create
arbitrary control structures--the only other one I've seen that looked
remotely useful (indeed, the /only/ other I've seen at all) was some
sort of forEachInMap construct. This can of course be implemented with a
sufficiently-advanced closures framework, specifically one allowing
non-local control flow modification.
Now there's something else that a lot of BGGA proponents seem to cite.
Something called "Tennent's Correspondence Principle" which I've
actually found very hard to track down. Apparently, it roughly states
that |expression| should be equivalent to |{ ==> expression }.invoke()|
(to use the BGGA syntax). The BGGA proponents cite that as the reasoning
behind having the non-local control flow, but it seems to be an open
question as to whether or not the guy actually meant to include the
effects of control flow statements in his principle.
In short, it's the middle ground between two rather polarized sides in
the debate. Which means that most people who count find it untenable,
since there is too much of the other side in it. The proposal, as nice
as it is, seems to be rather defunct nowadays.
Shame. It mostly looks pretty good, although the stuff about automatic
conversion to single-method interface types is decidedly iffy.
It is ugly, but closures proponents would tell you that it's necessary
to tack closures onto the current language: it represents the ability to
use closures with classes not designed with them in mind.
I've become rather convinced that the question of closures in Java
will end up being "none." However, I am still undecided as to whether
to cheer or bemoan that fact.
Better nothing than BGGA!
Well, I gave up on BGGA after seeing a conversation to this effect:
"Well, of course { => return 42 } is the correct answer; why would
anyone think it should be { => return 42; }?" Even if that part is
completely eradicated from the final proposal, just the mere fact that
proponents didn't realize the pitfall in having the presence or lack of
the statement delimiter do two *completely* different things is enough
in my mind to banish it to the deepest flames of Hell for all eternity.
Where does execution go after the line marked A? Oh, apparently we get a
UnmatchedTransfer exception? Christ on a bike. Have the people who come
up with this shit ever actually programmed a computer?
Well, Neil Gafter works for Microsoft now, so I'm going to guess the
answer is `no.' :-)
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth