I'm trying to understand the syntax for calling use to load a library:
(use 'clojure.contrib.duck-streams)
Makes sense to me as it applies the quote reader macro to clojure.contrib.duck-streams so that the reader doesn't attempt to evaluate that string.
Now, if I want to use the :only t开发者_运维百科ag to only load reader, why is this correct:
(use '[clojure.contrib.duck-streams :only (reader)])
instead of:
(use '[clojure.contrib.duck-streams :only reader])
I read this to mean pass in this vector of arguments to use but the REPL complains with Don't know how to create ISeq from Symbol. Why the parens around reader?
This is also equivalent to the first line and valid:
(use '[clojure.contrib.duck-streams])
So it seems that 'string are '[string] are equivalent arguments which I don't understand either.
:only
wants a list of symbols. That's just how the function is written. Note the docstring for refer
, which use
uses.
refers to all public vars of ns, subject to filters.
filters can include at most one each of:
:exclude list-of-symbols
:only list-of-symbols
:rename map-of-fromsymbol-tosymbol
It's written this way so that you can specify more than one symbol if you want.
(use '[clojure.contrib.duck-streams :only (reader writer)])
As discussed in this recent post, if you're writing a function that takes or returns a variable number of arguments, it's a good idea to have it always take/return a list or vector or set, even if it's taking/returning a single item. Because:
nil
, often used to represent "zero items", isseq
able. Empty collections are alsoseq
able.- Two or more items in a list are
seq
able. - It only makes sense to also have one item be
seq
able by putting it into a list itself.
It would be awkward to have the one-item case be a special case. It's more consistent and easier to program around when you treat one-item as a sort of degenerate case and throw it into a list.
Note that all use
cares about is whether the :only
argument is a seqable collection of symbols. That means lists, vectors and sets all work.
(use '[clojure.contrib.duck-streams :only [reader writer]])
(use '[clojure.contrib.duck-streams :only #{reader writer}])
A single Symbol
however is not seq
able which is why you get the exception you do.
Look in core.clj if you want to see how this is all implemented.
Those aren't just "parens" — parens are the syntax for creating a list. It would appear the item after the :only tag is expected to be a list of things it applies to.
精彩评论