Compiling a namespace causes subsequent uses of it to fail.

48 views
Skip to first unread message

philip....@gmail.com

unread,
Sep 7, 2009, 3:48:46 PM9/7/09
to Clojure
(ns testcomp)
(var-get (or (ns-resolve *ns* 'foo)
(intern *ns* 'foo :foo)))
;; foo ;(1)
;; (println foo) ;(2)
;; (do foo 3) ;(3)
;; (fn [] foo) ;(4)
;; ((fn [] foo)) ;(5)
;; ((fn [] (println foo))) ;(6)

With (1)-(6) all commented out, behaviour is as expected: you can
compile and use testcomp, and foo is bound to :foo.

With any of (1)-(3) uncommented, you can use testcomp with no problems
as long as it's uncompiled. If you compile it and subsequently attempt
to use it, you get an ExceptionInInitializerError caused by an
IllegalStateException due to Var testcomp/foo being unbound. What
seems to be happening (according to my limited understanding of
compilation) is that testcomp__init.class contains a reference to foo
which causes it to be interned (but unbound) before the body code is
run. ns-resolve then sees this Var, returns it, and var-get raises an
exception.

With (1)-(3) commented out, (4)-(6) can be uncommented and expected
behaviour returns. testcomp__init.class no longer contains a reference
to foo (I checked with grep).

I'm doing something like this in a library, and (5)/(6) provide a
workaround, but is this something that can be fixed at the language
level? I recognise it's not an issue that will commonly be run into,
and that the complexities of compilation might make it unavoidable.

java version "1.6.0_14", clojure commit
5f1e6ed540eab11281b7bfb19f831b7e445ed0d0 (1 Sep 09).

Stuart Halloway

unread,
Jun 23, 2010, 7:29:19 AM6/23/10
to clo...@googlegroups.com, philip....@gmail.com
I think the behavior you are seeing here is reasonable. When you mix compilation and dynamic access to vars, you need to reason carefully about the order in which things will happen.

More usefully: you can write a test in your var-get expression that will make it do what you want in all scenarios. Just add a bound? test before trying to get the value out of variable.

Sorry this was missed earlier.

Cheers,
Stu

> --~--~---------~--~----~------------~-------~--~----~
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> -~----------~----~----~----~------~----~------~--~---
>

philip....@gmail.com

unread,
Jun 24, 2010, 7:11:51 AM6/24/10
to Clojure
On Jun 23, 12:29 pm, Stuart Halloway <stuart.hallo...@gmail.com>
wrote:
> I think the behavior you are seeing here is reasonable. When you mix compilation and dynamic access to vars, you need to reason carefully about the order in which things will happen.

In general I would say that code working differently depending on
whether it's compiled or not is a bug. But I understand that as bugs
go, this one is probably not a big deal, and may be more trouble than
it's worth to fix. At the least I think a note should be added
somewhere to the docs about it though.

> More usefully: you can write a test in your var-get expression that will make it do what you want in all scenarios. Just add a bound? test before trying to get the value out of variable.

Thanks. I'll bear this in mind if I ever pick up the code again.

Phil
Reply all
Reply to author
Forward
0 new messages