m.invoke() vs. m()
Osvaldo Doederlein
opinali at gmail.com
Mon Dec 7 14:46:28 PST 2009
I'll take a chance with my $2c here. I'm in the side of eliminating
".invoke" and allowing a straight call with "()". Some people argued that
closure call and method call are not the same operation; here the difference
is only formal - closure invocation is ultimately compiled/executed as
method invocation. But either way it's irrelevant because we can just
overload the "()" operator to handle both method-call and closure-call,
there's much worse precedent for that in Java (e.g. "+").
The problem of separate variable/method namespaces can be handled by making
the conflict illegal - any given scope cannot see two methods, or variables
of closure type, with the same signature. No problem if I have c(10) and
c("a", "b") where the first c is a closure field and the second c is a
method. IMHO (not being a javac developer or JLS expert) this doesn't make
method resolution more complex, we are unifying closure-typed-vars and
methods and using similar, perhaps exactly identical, rules for both. (We
can overload methods but not variables in the same scope, so we can't have
multiple closures with same name even if their parameter lists differ - but
this is handled before resolution, by Java's rules for variable naming and
hiding.)
2009/12/7 Reinier Zwitserloot <reinier at zwitserloot.com>
> Allowing m() instead of m.invoke() actually spends quite a bit of the
> user-facing complexity budget. I've gone over the reasons, but just to
> highlight the ones relevant to user-facing complexity:
>
> - Changing the type of a field from closure to non-closure or vice versa
> can change the resolution in other source files, and in your own source
> file. In all java releases so far, the only way to do that is to actually
> add or remove members, or rename them.
>
This problem, as well as others I can think, seem strawmen to me. For
another example, if I have interface A that defines a closure-typed field c,
and interface B that defines a method with the same name c, then I can't
have a class C that implements both A and B. So what? This problem exists
since Java 1.0, you can have this kind of screwup with two interfaces that
define two methods of compatible signatures but unrelated meaning, which is
even worse because compilation will succeed but your implementation C.c()
can't possibly satisfy the incompatible specifications of A.c() and B.c().
And you can also have A.c and B.c being fields, then C can actually
implement both and javac accepts this silently, it's an error only if some
code (perhaps a subclass of C) tries to use C.c - this is an interesting
API-design puzzler. Also you can change the resolution of existing calls if
you mess with the parameters of existing methods. Overall, closures don't
bring anything significant to the table.
Finally, I consider that ".invoke" will also spend substantial part of our
"complexity budget". Just think about reflection. When Java was new,
reflection was an obscure feature that was used almost only in the core
libs. Things change; today, I have business-level code - interbank
transaction processing, no less - that uses reflection often enough that IT
HURTS, and I'm very happy that JDK 7 will relieve some of that pain with
multi-catch (possibly), a parent ReflectiveOperationException class, and
perhaps some extra sugar from JSR-292. Now, closure invocations will be rare
in 2010 when JDK 7 ships, but it may (and I hope it will) be EVERYWHERE in
frameworks or apps that are [re]designed a few years down the road. The
closure/single-method-interface conversion will help people migrate as fast
as they want. And when this happens, all those ".invoke" will suck hard. A
significant part of the power of closures is that closures can be used
interchangeably with regular methods or functions. As soon as users learn to
use closures effectively, they will appreciate this and consider very
natural to call closures just like they call methods. It's not a quantum
leap; Java's "working programmers" have cut their teeth with inner classes,
so closures are really not a big deal conceptually, and not hard to master.
Not even with the method-like invocation syntax, and not even with a couple
corner cases and extra rules.
A+
Osvaldo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/closures-dev/attachments/20091207/4f21562f/attachment.html
More information about the closures-dev
mailing list