Jacob Ford
Jacob Ford

Reputation: 5173

What is the meaning of double brackets within a Clojure function definition's parameters?

(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

Answers (1)

Jacob Ford
Jacob Ford

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

Related Questions