Clojure and me has moved.

Saturday, January 31, 2009

Shadowing global names

This post has moved, go to its new location
A nice article on Clojure that gives one wrong tip: to use #'var-name to access a shadowed global.
Don't do that! You'd better use namespace-where-defined-or-alias/var-name.
There are several reasons not to use #'var-name:
  • it doesn't work if the value of your var is not invokable,
  • it evaluates to something different: it returns the var an not its value. It happens that vars proxy function calls to their values but a var can be rebound:
    (def a (map str (range 10)))
    (def b (map #'str (range 10)))
    (take 5 a)
    ("0" "1" "2" "3" "4")
    (take 5 b)
    ("0" "1" "2" "3" "4")
    (binding [str identity] (doall a))
    ("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")
    (binding [str identity] (doall b))
    ("0" "1" "2" "3" "4" 5 6 7 8 9)
NB: @#'var-name is better than #'var-name but, really, just use the namespaced symbol.

1 comment:

Eric said...

Thanks Christophe!

I'll correct it on the blog.

Eric