Reputation: 8113
(defn explain-defcon-level [exercise-term]
(case exercise-term
:fade-out :you-and-what-army
:double-take :call-me-when-its-important
:round-house :o-rly
:fast-pace :thats-pretty-bad
:cocked-pistol :sirens
:say-what?))
If I understand correctly, usually key has colon and value does not. What is the purpose here? Thanks.
Upvotes: 1
Views: 263
Reputation: 4235
You can think of clojure code as consisting of a lot of symbols in s-expressions. When the reader parses these expressions, it has to resolve the symbol to a value. Some of these symbols are self evaluating i.e they will evaluate to themselves. for example, the symbol "Hello world" is a string symbol, which evaluates to itself. the number 123 is also self-evaluating and will evaluate to the number 123.
Other symbols need to be bound to a value. If you just had the symbol fred it needs to be bound to some value i.e. (def fred "Hello world"). If the symbol is the first symbol in a list (s-expression) it must evaluate to a function i.e. (def fred (fn ....) or the shorthand (defn fred [] ....). Note, this is simplifying things a little as you also have macros, but they can be ignored for now - they are special, in fact, often referred to as special forms.
Apart from strings and numbers, there is another very useful self-evaluating symbol, the keyword. It is distinguished by the leading ':'. Keywords evaluate to themselves i.e. :fred evaluates to :fred.
Keywords also have some very nice properties, such as fast comparison and efficient use of space. They are also useful when you want a symbol that represents something, but don't want to have to define (bind) it to something before you use it. In hash maps, keywords are also a function of the hash map, so you can do things like (:mykey maymap) instead of (get mymay :mykey).
In general, every symbol must evaluate to a value and the first symbol in a non-quoted list must evaluate to a function. You can quote lists and symbols, which essentially says "don't evaluate me at this point".
With that in mind, you can use any of these symbols as a value in a clojure data structure i.e. you can have vectors of functions, keywords, strings, numbers etc.
In the example you provide, you want your case statement to return some sort of symbol which you can then presumably use to make some decision later in your program. You could define the return value as a string, such as "You and whose army" and then later compare it to some other string to make a decision. However, You could even make things a bit more robust by defining a binding like
(def a "You and whose army")
and then do things like
(= a return-val)
but it isn't really buying you anything. It requires more typing, quoting, memory and is slower for comparison.
Keywords are often really useful when you are just playing around at the repl and you want to just test some ideas. Instead of having to write something like ["a" "b" "cc"], you can just write [:a :b :c].
Upvotes: 0
Reputation: 2611
Words starting with :
are keywords. Keywords act as known values like enums in some languages. You could also use strings as you might do in Python or JavaScript, but keywords have some nice features.
In this case, if the function receives e.g. the known keyword :round-house
, it will return the known value :o-rly
. Some other code in turn knows what :o-rly
means. You might as well use strings, if the code calling explain-defcon-level
would expect it to return strings.
The keywords:
(def m {:abba 1 :beef 2}) .. (:abba m) => 1
(name :foo) => "foo"
(keyword "bar") => :bar
Upvotes: 5
Reputation: 51500
:
is just a reader form for creating keywords.
Keywords in clojure are data structures, just like symbols, strings or numbers.
Keywords are used as keys in hashmaps because they implement IFn for invoke(), allowing you to write things like (:mykey my-map)
instead of (my-map :mykey)
or (get my-map :mykey)
.
Generally, you could use any data structure as a hashmap key:
(def my-map
{ {:foo :bar} 1
{:bar :baz} 2 })
(my-map {:foo :bar}) ; 1
Upvotes: 3