1

I'm taking my first steps with Clojure. Otherwise, I'm somewhat competent with JavaScript, Python, Java, and a little C.

I was reading this artical that describes destructuring vectors and maps. E.g.

=> (def point [0 0])
=> (let [[x y] point]
=>   (println "the coordinates are:" x y))
the coordinates are: 0 0

but I'm having a difficult time understanding keywords. At first glance, they seem really simple, as they just evaluate to themselves:

=> :test
:test

But they seem to be used is so many different ways and I don't understand how to think about them. E.g., you can also do stuff like this:

=> (defn full-name [& {first :first last :last}]
=>   (println first last))
=> (full-name :first "Tom" :last "Brennan")
Tom Brennan
nil

This doesn't seem intuitive to me. I would have guessed the arguments should have been something more like:

(full-name {:first "Tom" :last "Brennan"})

because it looks like in the function definition that you're saying "no required arguments, but a variable number of arguments comes in the form of a single map". But it seems more like you're saying "no required arguments, but a variable number of arguments comes which should be a list of alternating keywords and values... ?" I'm not really sure how to wrap my brain around this.

Also, things like this confuse me too:

=> (def population {:humans 5 :zombies 1000})
=> (:zombies population)
1000
=> (population :zombies)
1000

How do maps and keywords suddenly become functions?

If I could get some clarification on the use of keywords in these two examples, that would be really helpful.

Update I've also seen https://stackoverflow.com/questions/3337888/clojure-named-arguments and while the accepted answer is a great demonstration of how to use keywords with destructuring and named arguments, I'm really looking more for understanding how to think about them--why the language is designed this way and how I can best internalize their use.

1 Answer 1

4

the & in (defn full-name [& {first :first last :last}] indicates that all the remaining arguments should be gathered into a single collection. the map destructuring form following the & then takes the map created by the & apart again.

(defn full-name [& {first :first last :last}]...)
(full-name :first "Tom" :last "Brennan")

without the & becomes

 (defn full-name [{first :first last :last}]...)
(full-name {:first "Tom" :last "Brennan"})

for your other question: symbols and keywords implement the function interface so they can be called just like any other Clojure function. when called as a function they look themselves up in their argument which they expect to be a map (or something implementing the appropriate interface)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.