2
votes

The following import statements in Clojure all seem to be valid:

(import '(com.example.db.modules DBModule))
(import 'com.example.db.modules.DBModule)
(import '[com.example.db.modules DBModule])
(import (com.example.db.modules DBModule))
(import com.example.db.modules.DBModule)
(import [com.example.db.modules DBModule])

But what is their difference, and why should I use one or the other? (Especially when importing several Classes in one import-statement)

1

1 Answers

5
votes

The import macro removes the quote of each expression if there is one, so there's no difference between quoting the arguments it receives from not quoting them. This means the expressions (import 'com.example.db.modules.DBModule)) and (import com.example.db.modules.DBModule) are equivalent. You can check this by macro-expanding each expression.

user=> (macroexpand-1 '(import 'com.example.db.modules.DBModule))
(do (clojure.core/import* "com.example.db.modules.DBModule"))
user=> (macroexpand-1 '(import com.example.db.modules.DBModule))
(do (clojure.core/import* "com.example.db.modules.DBModule"))

Specifying a vector or a list allows you to import more than one class from the same namespace, using either one is equivalent since import makes use of Clojure's sequence abstraction to map and reduce over them.

To sum up:

  • Use (import com.example.db.modules.DBModule) when you need only a single class from a namespace.
  • Use either (import [com.example.db.modules DBModule]) or (import (com.example.db.modules DBModule)) when you need to import more than one class. I personally prefer vectors.
  • You can provide any combination of the previous items as arguments to import. For example (import com.example.db.modules.DBModule [com.example.model Client Order Payment])).
  • Don't quote the arguments since it is not necessary.