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.]