I'm starting to get more into Clojure-Java interop. If I create a Java class in Clojure, I need to import it, but if I merely use fields or methods of a class, I don't have to import it. For example:
(ns students.Student
(:import [sim.util Double2D])
(defn -step
[this students] ; students is a students.Students, extends sim.engine.SimState
(let [yard (.-yard students) ; a sim.field.continuous.Continuous2D
yard-width (.-width yard)
yard-height (.-height yard)]
(.setObjectLocation yard this (Double2D. (/ yard-height 2) (/ yard-width 2)))))
This won't compile without importing Double2D
, because the code creates a Double2D
instance.
However, the fact that I access the yard
field and setObjectLocation()
method of a Students
instance, and the width
and height
fields of a Continuous2D
instance causes no problems, even though I don't import the Students
or Continuous2D
classes.
Does this mean that Clojure is using reflection at runtime to access Java fields and methods? Is that inefficient? If I need speed in a function, could it be advantageous to add type declarations for the Java classes, along the missing import statements? Would that prevent reflection?
[EDIT: As my second comment on Arthur Ulfeldt's answer suggests, I now think that any inefficiencies that come from not knowing classes at compile time are likely to be not very different from inefficiencies that come from the fact that functions are contained in variables. If I was worried about that, I'd forget about Clojure and program in pure Java (maybe), instead of trying to use Java libs from Clojure. For me, a world in which I can use Clojure instead of Java is a better one.]