user4813927
user4813927

Reputation:

What's the use of the underscore in Clojure's let binding form?

What does an underscore within the binding vector of a let do, so if i write (let [a blabla _ (println a)] etc.... what is this underline doing at the place of the keyword?

Upvotes: 8

Views: 2536

Answers (2)

guilespi
guilespi

Reputation: 4702

The underscore is a valid symbol identifier, as you can see by this sample code:

(let [_ 1] 
  (println _))
=> 1

By convention when you have an identifier you won't be using you may use _, but it's not mandatory.

Happens both for side effect situations as in your sample (in your case the println line returns nil so you won't be binding its result to a symbol)

Happens also on destructuring situations where you don't need some of the values.

 (let [[a _ _ d] [1 2 3 4]] 
    (println a))
 => 1

In this case you're not interested in 2nd and 3rd values, so the identifier _ is idiomatic for saying you don't care.

In regular Clojure the underscore _ is treated like any other symbol (e.g. "junk"). However it has a special meaning in some libraries. For example, in Datomic the _ is treated like a "wildcard" that prevents binding/unification. In clojure.core.match, the _ is also treated as a wildcard.

See:

Upvotes: 14

Mark Fisher
Mark Fisher

Reputation: 9886

The underscore is the universal ignore symbol.

There has to be a return value for each sexp in the let form, and println returns nil, so you can set it to _ to tell people you are ignoring the return and just doing debug at that point. e.g.

(let [foo (+ 1 2)
      _   (println "debug! foo is" foo)
      _   (println "more debug!" (+ 1 foo)]
  foo)

each evaluation of the sexp sets the _ to the value returned, but it's not required, so just read it as such.

Upvotes: 4

Related Questions