I am working through the joy of clojure and am wondering what the _ syntax does in a functions argument vector.
Example:
(def available-processors
(.availableProcessors (Runtime/getRuntime)))
(prn "available processors: " available-processors)
(def pool
(Executors/newFixedThreadPool (+ 2 available-processors)))
(defn dothreads!
[func & {thread-count :threads exec-count :times :or {thread-count 1 exec-count 1}}]
(dotimes [t thread-count]
(.submit pool #(dotimes [_ exec-count] (func)))))
What is the underscore doing in the form:
#(dotimes [_ exec-count] (func))
I believe that underscore is used in Clojure, by convention, as a placeholder for a required but unused argument. As Keith Bennet puts it:
In Clojure, the underscore is used idiomatically to indicate that the
argument it identifies is not subsequently used.
Your example is consistent with this "usage," since the first argument to dotimes
, which is an indexer, is not needed, but the binding is required by the form.
Nothing special about it, it is just a convention for naming something that you don't care about, but still it is a name and can be used like a normal name.
(defn hello [_] (+ 1 _))
(hello 10)
UPDATE
Doing this:
(defn hello [a a] (+ a a))
doesn't produce an error and hence you can use as many _ as you want ;).
NOTE: The above isn't the case with Scheme or CL... Hmm what was the rational behind it in clojure then???
The previous answers are good, but since I needed some extra clarification, here's my answer.
(defn blah[_] (str "the value you sent is " _)
is identical to
(defn blah[my-arg] (str "the value you sent is " my-arg)
There is no difference. _ is just a way to let the person looking at the code to know that the parameter is not intended to be used.
So for example, this is fine programatically:
(dotimes [_ 5] (println (str "I'm going to print this 5 times, and this is index # " _)))
But someone looking at the code would think you aren't planning on using the _. So it would be better to use 'n' or 'ind' or whatever, instead of _, just to be clear. If you aren't using that value, like below...
(dotimes [_ 5] (println "I'm going to print this 5 times"))
Then it makes since to bind your parameter to _, as you are indicating that you aren't using it.
And one last thing, if bindings have the same name, the last one wins. So the following will print "4last4last4last4last".
(defn will-print [_ a _ a _ a _ a] (println (str _ a _ a _ a _ a)))
(will-print 1 "a" 2 "b" 3 "c" 4 "last")
So in the println block '_' is bound to 4, and 'a' is bound to 'last'. All of the previous values sent are ignored/overwritten.