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

+2 votes
in Java Interop by
retagged by

Here's some code:

(set! *warn-on-reflection* true)
(defrecord Foo [bar])
(.-bar (->Foo "bar"))

;;> Reflection warning, NO_SOURCE_PATH:1:1 - reference to field bar can't be resolved.
;;=> "bar"

As we can see, the generated ->Foo function to construct record of type Foo is not type hinted, and thus Clojure will use reflection when doing interop calls over it.

It would be nice if Clojure would generate a type hinted constructor instead.

1 Answer

+1 vote

I'm almost certain this has been discussed in the past and deemed either less useful or more complicated than it appears on the surface. I don't see a jira ticket, but it may have happened in some other forum.

I do not consider the example here to be motivating - using :bar for keyword access is the expected usage pattern which is simpler, more portable, and preferred (and does not require a type hint).

I'm not disagreeing, I doubt this is a very important issue. Not sure if code bases in the wild would really see any noticable performance improvement if this was added.

That said, to answer the example, maybe field access was a bad choice, but if the record implements protocols or interfaces, then method calls on those will also be reflective unless explicitly type hinted. That might be a more common use case.
I would be compelled by a compelling example. :)  

Protocol invocations aren't reflective - those are always runtime type checks at the call-site. Interfaces, maybe relevant.
What about for deftype, which doesn't support keyword access? I'm currently running into reflection warnings for field access in a codebase I inherited.

I searched the mailing list and the Clojurians archives on this topic, but didn't find anything explaining why the positional factory fn couldn't be hinted.