4

I know how to forward declare a var for the current namespace. Instead, I want to declare a var from another namespace. How do I do this? This will help me eliminate a circular load dependency.

At the moment, this is what I've tried:

; this_ns.clj
(ns my-project.this-ns
  (:require ...))
(ns my-project.other-ns)
(declare other-func)
(ns my-project.this-ns) ; return to original namespace
(defn func-1
  []
  (my-project.other-ns/other-func))

It works, but I don't like it.

1 Answer 1

3

I think the solution you already have is the easiest one. If you wrap it into a macro it doesn't even look that bad anymore:

(defmacro declare-extern
  [& syms]
  (let [n (ns-name *ns*)]
     `(do 
        ~@(for [s syms]
            `(do 
               (ns ~(symbol (namespace s)))
               (declare ~(symbol (name s)))))
        (in-ns '~n))))

Call it with:

(declare-extern my.extern.ns/abc) ;; => #<Namespace ...>
my.extern.ns/abc                  ;; => #<Unbound Unbound: #'my.extern.ns/abc>
Sign up to request clarification or add additional context in comments.

2 Comments

But addressing (+ eliminating) the dependency circle would probably a better approach to your problem, making things easier in regard to future changes to your code.
Is "unbound" what you expected? That behavior is consistent with what I'm seeing based on my interpretation of David James' suggestion. How is it supposed to work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.