Possible namespace bug

0 views
Skip to first unread message

Brent Millare

unread,
May 25, 2010, 6:17:31 PM5/25/10
to Clojure
May have found a bug, here is how to duplicate it. Hopefully someone
can confirm this.

Here is expected behavior when run in the repl:
Clojure 1.2.0-master-SNAPSHOT
user=> (ns foo)
nil
foo=> (defmacro f []
`(eval `(def ~'~'x 'foo)))
#'foo/f
foo=> (ns bar)
nil
bar=> (defn b []
(foo/f))
#'bar/b
bar=> (b)
#'bar/x

However, if you put them in separate files the namespace of x changes:

$ ls -R *
clojure-1.2.0-master-SNAPSHOT.jar

src:
bar.clj foo.clj

$ cat src/foo.clj
(ns foo)

(defmacro f []
`(eval `(def ~'~'x 'foo)))

$ cat src/bar.clj
(ns bar (:require foo))

(defn b []
(foo/f))

$ java -cp clojure-1.2.0-master-SNAPSHOT.jar:src/ clojure.main -e "(do
(require 'bar) (bar/b) )"
#'user/x

^^ That should read #'bar/x instead of #'user/x

Best,
Brent

Meikel Brandmeyer

unread,
May 26, 2010, 1:27:14 AM5/26/10
to Clojure
Hi,

On May 26, 12:17 am, Brent Millare <brent.mill...@gmail.com> wrote:

> ^^ That should read #'bar/x instead of #'user/x

No. foo/f expands into a macro calling eval on a def. This eval
is put into a function bar/b. When you call the function the
namespace "in charge" is user. So everything is correct.

Usual disclaimer:
Don't do non-global def (besides a surrounding scope-limiting
let). Avoid eval.

Sincerely
Meikel

Brent Millare

unread,
May 26, 2010, 2:28:42 AM5/26/10
to Clojure
Hi Meikel,

Well if #'user/x is the correct behavior, then the repl behavior needs
to be fixed. Either one may be "correct" but that does not explain the
discrepancy. Also I agree that eval should be avoided, but I found an
extreme case where it was necessary (due to the desired side effect of
starting a new classloader).

Best,
Brent

Brent Millare

unread,
May 26, 2010, 2:35:02 AM5/26/10
to Clojure
Ah wait, I may have read that wrong. So what I understand is because I
am calling it from the the -e, it is ran in the user ns. Ok that makes
sense.

Meikel Brandmeyer

unread,
May 26, 2010, 2:38:32 AM5/26/10
to Clojure
Hi,

On May 26, 8:35 am, Brent Millare <brent.mill...@gmail.com> wrote:

> Ah wait, I may have read that wrong. So what I understand is because I
> am calling it from the the -e, it is ran in the user ns. Ok that makes
> sense.

Exactly! And in the Repl you are still in the bar namespace.
Doing a (in-ns 'user) and then calling bar/b should give the
same effect as for -e invokation.

Sincerely
Meikel

Reply all
Reply to author
Forward
0 new messages