Cause: Functions have metadata, but Compiler does not look in them for type hints. Var expressions and local bindings use :tag metadata to override return of getJavaClass(). Compiler parses #() into a FnExpr, which always return AFunction as its class.

Proposed: Change FnExpr.getJavaClass() to return tag as type if it is available.

Caused by: java.lang.IllegalArgumentException: More than one matching method found: submit
at clojure.lang.Compiler.getMatchingParams(Compiler.java:2380)
at clojure.lang.Compiler$InstanceMethodExpr.<init>(Compiler.java:1412)
at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:952)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
... 87 more

Caused by: java.lang.IllegalArgumentException: More than one matching method found: submit
at clojure.lang.Compiler.getMatchingParams(Compiler.java:2380)
at clojure.lang.Compiler$InstanceMethodExpr.<init>(Compiler.java:1412)
at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:952)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
... 87 more
{code}

When compiler is determining which native method to use, it matches method signature with classes of given args. There is a getJavaClass() method in Compiler.java which returns a class for given expression. Vars expressions and local bindings use :tag metadata to override this class, but most other expressions don't. Compiler parses #() into a FnExpr, which always return AFunction as its class.

Most of time this approach is OK, as AFunction implements Runnable and Callable so there is no need for type hint. However, in this particular case, there are overrides for both Runnable and Callable, and as AFunction can be either of them, the expression is ambiguous.

When compiler is determining which native method to use, it matches method signature with classes of given args. There is a getJavaClass() method in Compiler.java which returns a class for given expression. Vars expressions and local bindings use :tag metadata to override this class, but most other expressions don't. Compiler parses #() into a FnExpr, which always return AFunction as its class.
Most of time this approach is OK, as AFunction implements Runnable and Callable so there is no need for type hint. However, in this particular case, there are overrides for both Runnable and Callable, and as AFunction can be either of them, the expression is ambiguous.

[ I suspect this is because functions don't have metadata. Metadata is attached to vars or locals (neither of which exist in the anonymous function case). So the issue is not really the anonymous function, but that there is no place to hang the meta. For example this example using #() is fine:

Caused by: java.lang.IllegalArgumentException: More than one matching method found: submit
at clojure.lang.Compiler.getMatchingParams(Compiler.java:2380)
at clojure.lang.Compiler$InstanceMethodExpr.<init>(Compiler.java:1412)
at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:952)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
... 87 more
{code}

Example showing how a local fn can be hinted but an anonymous function cannot:

*Cause:* Functions have metadata, but Compiler does not look in them for type hints. Var expressions and local bindings use :tag metadata to override return of getJavaClass(). Compiler parses #() into a FnExpr, which always return AFunction as its class.

*Proposed:* Change FnExpr.getJavaClass() to return tag as type if it is available.

*Cause:* Functions have metadata, but Compiler does not look in them for type hints. Var expressions and local bindings use :tag metadata to override return of getJavaClass(). Compiler parses #() into a FnExpr, which always return AFunction as its class.

*Proposed:* Change FnExpr.getJavaClass() to return tag as type if it is available.

*Patch:* clj-1378-v2.diff

*Screened by:*

Example showing how a local fn can be hinted but an anonymous function cannot:

*Cause:* Functions have metadata, but Compiler does not look in them for type hints. Var expressions and local bindings use :tag metadata to override return of getJavaClass(). Compiler parses #() into a FnExpr, which always return AFunction as its class.

*Proposed:* Change FnExpr.getJavaClass() to return tag as type if it is available.