On Sat, Aug 27, 2011 at 8:31 PM, Tal Liron <tal.li...
> I can think of a few ways in which it would be possible to distribute a
> clojure.jar that supports JVM 7 features while still falling back to JVM 5
> compatibility. So, I don't think this was ever a barrier. But you obviously
> unconvinced by my report! Thank you for challenging me on this, As I said,
> I'm by no means 100% sure I exhausted the issue. I would encourage you to
> try out your ideas.
I agree. I wasn't saying that it was impossible to target both Java 5 and
take advantage of Java 7 features. I had mentioned that targeting Java 7
could be specified as an option when AOT compiling, or it could
automatically be detected when compiling at runtime. However, I think that
people (perhaps rightly so) make the argument that the amount of effort
weighed against compatibility concerns and resource allocation and the
percentage of Clojure code that would benefit, doesn't make it worth doing.
That's different than saying that there would be no benefit to Clojure.
*-- If you don't provide any type hints, then the constructor for
> InstanceMethodExpr sets method = null and warns you that you're doing
> You are right! This is perhaps the only place where invokedynamic can be
> useful for Clojure. *However*, to me this is not a big deal, because the
> workaround of allowing for type hinting solves the problem just as well, and
> perhaps even more efficiently from the compiler's point of view. All it does
> is require some extra annotations by the programmer. The fact that Clojure
> emits a warning seems good enough for me, personally.
This seems to be a standard response from people, and I don't really
understand it. You are comparing apples to oranges. Don't get me wrong. Type
hints are a critical tool for improving the performance of critical
sections, and would probably be necessary even if Clojure's dynamic dispatch
was faster than it is, but it seems like a win to just automatically make
dispatch faster without type hints, and I guess it boils down to mostly
non-technical factors (see above). Plus the biggest boost would be to code
that interoperates with Java, which is arguably rarer than pure Clojure code
(though I think that invokedynamic could even speed up Var dispatch,
protocol dispatch, and multimethod dispatch (see below)).
*-- I may be missing something, but I don't see how JRuby needs different
I'm still not seeing an problems that are different than Clojure. JRuby must
create a class for every method of every class in order to make the methods
hot-swappable at runtime. Clojure does the same thing for its IFns and for
the same reason. Both JRuby and Clojure would have to do this even if
invokedynamic didn't exist, because it is a problem more with classes and
class loading, than with invocation. I don't necessarily want to get
distracted by this...
*-- Clojure has similar needs. For instance, Clojure has protocol dispatch
> and multimethod dispatch as well as Var based dispatch. The multimethod
> dispatch does a look up in the derivation hierarchy. All of this stuff can
> change at runtime, just like in Ruby you can add methods to a class, change
> methods on a class, etc. I don't see how Clojure's dispatch needs are much
> different than what other dynamic languages are doing.
> So, perhaps I'm not understanding how you are using the term "change at
> runtime" to describe both JRuby regular dispatch and Clojure's multimethod.
Correct me if I'm wrong, but multimethod dispatch calls a dispatch function
that returns a value. This value can then be used to inspect the global
derivation hierarchy. Then the result is used to find the right defmethod to
call, by basically looking up in a dictionary of methods. The global
derivation hierarchy can be changed at runtime which can cause different
dispatch values to be returned for the same arguments at different times.
Also, new defmethods can be added at runtime, which can change the
dictionary of methods. Protocol dispatch is similar, but doesn't go through
the global derivation hierarchy.
I believe there's already some form of caching implemented for multimethods
and protocols. That caching code could be replaced by bootstrap methods and
CallSites, which isn't really that exciting. However, I do believe that the
JVM can better optimize a MethodHandle in a CallSite than it can an IFn that
is fetched from a method dictionary at runtime. Perhaps that's just
speculation on my part. However, I've been hearing good things about
Plus, I believe with a CallSite the cache is more immediate than with a
dictionary lookup. With a dictionary lookup, you do the lookup every time
through the code path, but, as Charlie mentioned in another post, with a
MethodHandle you go straight from a reference to the implementation code
without having to do the lookup and without going through an interface. This
seems to be not only a performance boost, but provides more specific
information to the JVM, which would seem to improve optimizations.
Anyway, the biggest boost would seem to be calling Java methods from Clojure
without type hints.
Clojure's multimethod is "dynamic" in an entirely different way: the correct
> function is selected at runtime *according to the arguments* of the
> function. JVM-level linkage to the selected method would make no sense,
> because you'd be calling your bootstrapping method every single call!
Yeah, I've thought about that. That may be true. However, Clojure does use
caching for multimethod and protocol dispatch, and to whatever extent that
caching is successful it can be pushed down into the JVM. And again, to me
the advantage would be that the JVM has a MethodHandle directly to a method,
which would improve optimization potential, and also once they are
bootstrapped MethodHandles don't have check and recheck access levels and
types of arguments. MethodHandles are designed to remove the extra layers of
things you normally have to deal with when implementing dynamic languages on
You can argue that Clojure multimethods are inherently inefficient, and