> So, my question is this: what is the difference/relationship between
> #' and the fully-qualified name?
#'x is a sequence of characters that the reader (LispReader.java)
translates into (var x) when reading. (see http://clojure.org/special_forms#var)
.
The simplest way to see this is by quoting it at the repl:
user=> (quote #'x)
(var x)
The purpose of the "var" special form is to return the var object
named by its argument (a symbol). It does this by using the symbol's
name part as a key in the ns-map for a namespace: (see clojure.core/ns-
map)
- If the symbol has a namespace part, var uses the namespace it names;
- If not, var uses the current namespace (*ns*).
If a symbol has a namespace part, using #' or var is unnecessary
because because such a symbol cannot refer to a function argument or
let-bound local.
For symbols without a namespace part, by using (var x) or #'x, you're
specifying you want the var object associated with that symbol in the
ns-map of the current namespace rather than leaving open the
possibility of getting the value of a function argument or let-bound
local named by that symbol.
> When should they be used? What are the standard idioms for using
> these?
Here are some suggestions of mine. I don't claim they're standard:
- Avoid using an argument name or let-bound local name that "shadows"
the (unqualified) name of a var you need to use within its scope
- Failing that, use a namespace qualified symbol to refer to the var
- If namespace qualifying a symbol is too verbose, use "alias" to
create a shorter name for the namespace
- If that's still too verbose, use #' or (var ...) to refer to the
var in the current namespace
- #'x and (var x) are equivalent. Use whichever you find readable and
adequately succinct.
Regarding binding itself, binding a var is an operation on the var
object itself. For a given var, that operation is the same and has the
same effect no matter how you acquired a reference to the var:
- using a fully qualified symbol name
- by resolution of a simple symbol name that's not shadowed by a
function argument or let-bound local
- by resolution of a simple symbol name within a var special form (or
#')
- by direct lookup in the ns-map for a namespace
Your experiment proved that.
--Steve
There's not so much difference when they are used in function position
but in argument position they behave differently.
Below is an example (from
http://clj-me.blogspot.com/2009/01/shadowing-global-names.html) where
you can see that with a name (I could have used a qualified name) you
pass the current value of the binding while with #' you pass the var
itself and those values will behave differently if they are "leaked"
outside of the calling scope (eg: sent to another thread or agent, used
in a lazy sequence or a delay, stored in a mutable box etc.)
(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*)/
Christophe
> Regarding binding itself, binding a var is an operation on the var
> object itself. For a given var, that operation is the same and has the
> same effect no matter how you acquired a reference to the var:
Except that in one case (name) you acquire the current value of the var
but not the var itself. It doesn't matter as long as you are in function
position but, elsewhere, it makes a difference (cf my response to parent
post).
Christophe
--
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.blogspot.com/ (en)