Welcome! Please see the About page for a little more info on how this works.

0 votes
ago in Compiler by
edited ago by

As of Clojure 1.13.0-alpha2, (.method ClassName) expands to (.method ^Class (identity ClassName)).

This is to force (.method ClassName) to always be an instance method. Without this, it would expand to (. ClassName method), which may instead be interpreted as a static method.

For example, (.getMethods String) expands to (.getMethods ^Class (identity String)).

This was introduced in these two commits:
- force instance member interpretation of (.method ClassName), e.g. (.getMethods String) works
- added autohinting to Class in macroexpansion of (.instanceMethodOfClass Classname) calls

Since then, Clojure has added support for qualified methods which we can use to reliably propagate the tag without any runtime changes. For example, expanding to (Class/.getMethods String) is now equivalent to (.getMethods ^Class (identity String)) in terms of tag propagation.

I have a proof-of-concept here that includes disassembled and decompiled output before and after the change. The net effect of using qualified methods in this case under direct linking is a removal of a single method call to identity:

   3: invokestatic  #20                 // Method clojure/core$identity.invokeStatic:(Ljava/lang/Object;)Ljava/lang/Object;

The effect is more substantial without direct linking (not included in the PR), with clojure.core/identity also being added to the static initializer.

I've also experimented with expanding to (. (do String) getMethods) (see earlier commits in that PR), which seems to also work and might be another approach.

Please log in or register to answer this question.

...