Reputation: 5173
(defn foo [[a] b]
(println a b))
(foo "one" "two") ; => o two
(foo 1 2) ; => Execution error (UnsupportedOperationException) at user/foo (REPL:1).
; nth not supported on this type: Long
What are the second pair of brackets around a
doing?
Or, a real-world example where I encountered it:
(parser/add-tag! :i18n
(fn [[k] context]
(->> k (keyword) (translate (or (:i18n/locale context) :en)))))
Upvotes: 0
Views: 372
Reputation: 5173
It is Clojure's syntax for destructuring.
(defn bar [[a b] c]
(println a b c))
would "pull out" the first and second items from the first argument passed to bar
and immediately assign them to variables a
and b
respectively. It is functionally equivalent to:
(defn bar [vector c]
(let [a (nth vector 0) ; assign first item in first parameter to a
b (nth vector 1)] ; assign second item in first parameter to b
(println a b c))) ; c is passed & printed as-is
In your example:
(defn foo [[a] b]
(println a b))
Running (foo "one" "two")
would mean "set a
to first item in "one"
and b
to "two"
, then print a b
.
In Clojure, strings are seq-able, so [[a]]
in this specific case means "set a
to the first character of the string "one"
, which is o
.
(foo 1 2)
fails because numbers (Longs) are not seq-able, so they cannot be destructured.
(fn [[k] context] … )
would mean "of the two arguments passed into this function, take the first item from the first argument and set it as k
. Leave the second argument as-is."
Upvotes: 6