Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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 http://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.

share|improve this question
up vote 4 down vote accepted

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)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.