Are keywords with the same name guaranteed to be identical? - clojure

Are Clojure keywords with the same name guaranteed to be identical? i.e. Is (identical? :a :a) guaranteed to return true?
What are the precise rules when the keywords of the same name are in different namespaces? For example, (identical? :a ::a) is false. Why?

Keywords which are = are guaranteed to also be identical?, and those which are not = are of course guaranteed to not be identical?.
:a is different from ::a because the latter has a namespace component and the former doesn't. How could they be identical? Identical means, the very same object reference. Since they have different characteristics they cannot be the same object.

Related

Is there a canonical way to name variables that would otherwise cause name collisions?

Say I'd like to name a variable seq, referring to some kind of sequence.
But seq is already a function in clojure.core, so if I try to name my variable seq, the existing meaning of seq will be overwritten.
Is there a canonical way in Clojure to name a variable that would otherwise have a name collision with a default variable?
(e.g., in this case, my-seq could be used, but I don't know whether that would be standard as far as style goes)
There is no "standard" way of naming things (see the quote and the related joke).
If it is a function of only one thing, I often just name it arg. Sometimes, people use abbreviations like x for a single thing and xs for a sequence, list, or vector of things.
For small code fragments, abbreviating to the first letter of the "long" name is often sufficient. For example, when looping over a map, each MapEntry is often accessed as:
(for [[k v] some-map] ; destructure key/val into k & v
...)
Other times, you may prefix it with a letter like aseq or the-seq.
Another trick I often use is to add a descriptive suffix like
name-in
name-full
name-first
(yes, there is a Clojure function name).
Note that if you did name it seq, you would create a local variable that shadowed the clojure.core/seq function (it would not be "overwritten"). I often just "let it slide" if the scope of the shadowing is limited and the name in question is clear & appropriate (key and val are often victims of this practice). For name, I would also probably just ignore the shadowing of clojure.core/name, since I rarely use that function.
Note that you can shadow your own local variables. This is often handy to coerce data in to a specific format:
(defn foo
[items]
; assume we need a sorted vector with no duplicates
(let [items (vec (sort (set (items))))]
...))
By shadowing the original items argument, we ensure the data is in the desired form without needing to come up with two good, descriptive names. When this technique doesn't quite fit, I often fall back to the suffix trick and just name them items-in and items or similar.
Sometimes a suffix indicating type is valuable, when multiple representations are required. For example:
items
items-set
items-vec
type-str
type-kw
type-sym
There are many other possibilities. The main point is to make it clear to the reader what is happening, and to avoid creating booby traps for the unaware.
When in doubt, add a few more letters so it is obvious to a new reader what is happening.
You won't override clojure.core/seq. You will be simply shadowing the var seq with your local bindings or vars. One can always use fully qualified name to use core seq.
Example:
;; shadow core seq
(def seq [1 2 3])
WARNING: seq already refers to: #'clojure.core/seq in namespace: user, being replaced by: #'user/seq
=> #'user/seq
;; local binding
(defn print-something [seq]
(prn seq)
(prn (var seq)))
=> #'user/print-something
;; use fully qualified name
(clojure.core/seq "abc")
=> (\a \b \c)
(print-something "a")
"a"
#'user/seq
=> nil
(prn seq)
[1 2 3]
=> nil
(var seq)
=> #'user/seq
But, its not a clean practice to shadow clojure.core vars as it might lead to buggy code. It does more harm than good if any. I usually name vars based on code context, like employee-id-seq, url-seq etc. Sometimes, it okay to use short names like x or s if usage scope is limited. You can also see clojure.core implementation to find more examples.
A good guide: https://github.com/bbatsov/clojure-style-guide#idiomatic-names
I also recommend clj-kondo plugin

What are the benefits of using keywords as keys in maps in Clojure?

I've noticed that in Clojure it's common to use keywords as keys in a map, while in other languages that do not have such concept it is common to use strings.
What are benefits of using keywords instead of strings or other types?
Keywords are a symbol type, semantically distinguished from strings and with a smaller range of representable values. They can be namespaced, there are checks for legal use of namespaces and such, and hence users can be more confident in EDN keyword keys meaning what they expect than in e.g. JSON with the equivalent string keys.
Keywords are interned, so all instances of a keyword refer to identically the same object. This is useful for e.g. equality checks.
Keywords are functions, acting like get with themselves as the key argument. This is convenient for cases like "I want the phone number of all these people" - (map :phone-no people) vs. (map #(get % "phone-no") people)
Keywords are also convenient with let and other destructuring tools:
(let[{:keys [foo bar]} {:foo 1 :bar 30}]
(+ foo bar)) ;;=>31
but this does actually apply to string keys as well using the less common :strs destructuring.

What should we call an object declared in a clojure prog?

When we talk about a clojure (or other lisp) prog, what should we say when refer an object declared in it? For example:
(let [a ...
Of course, if a is a function, we say function a, but what should we say when it's not a function? Form? Data? Symbol? Literal?
Generally, we say those things in other prog language variables or objects.
The let special form creates bindings between symbol(s) and a value.
The official documentation for let actually uses the vocabulary and wording that you are looking for and should use, specifically the Binding Forms section sheds more light to the subject:
The basic idea is that a binding-form can be a data structure literal containing symbols [or just a single symbol] that get bound to the respective parts of the init-expr.
I think the question mixed up two things, or at least didn't make it clear that they're different.
As the other answers so far indicated, "a" is a symbol, which evaluates to something else. So when we talk about a, we could mean the symbol, or the something else. And we could even mean the var that is an intermediary between the symbols and the something else. (See the page linked by Guillermo Winkler for more on the var/symbol relationship, which I'll leave in the background.)
A symbol is never a function, but it can have a function as its value. When you call a function, you are just using its value in a special way. You can even set the values of built-in functions to other values:
(def + -)
WARNING: + already refers to: #'clojure.core/+ in namespace: user, being replaced by: #'user/+
#'user/+
user=> (+ 5 2)
3
user=> (def - "This used to be the minus function")
WARNING: - already refers to: #'clojure.core/- in namespace: user, being replaced by: #'user/-
#'user/-
user=> -
"This used to be the minus function"
I gave + the value of -, and then made -'s value a string. (Yes, there were warnings, but it worked.) The fact that functions are just values of symbols is a way in which Clojure differs from many other languages. (Scheme is similar. Common Lisp is similar, but in a more complicated way.)
So the symbol is just the symbol. And it usually has a value, which may be a function, or a number, or a string, or a keyword, or anything that can be a value in Clojure--vectors, lazy sequences, lists (which may be Clojure code), or even another symbol (even the same one: (def a 'a).) You could call some of these things data if that's useful in a particular context. It's sometimes reasonable to describe functions as data in Clojure.
(def add-fns [#(+ 1 %) #(+ 2 %) #(+ 3 %)]) ;=> #'user/add-fns
add-fns ;=> [#object[user$fn__1178 0x71784911 "user$fn__1178#71784911"] #object[user$fn__1180 0x45ed957d "user$fn__1180#45ed957d"] #object[user$fn__1182 0x7838c8c5 "user$fn__1182#7838c8c5"]]
add-fns is a vector of functions. What should we call the functions that are elements of the vector? Aren't they data in some sense, if we use them like data? We can map a function over them, or reorder them, for example:
(map #(% 10) add-fns) ;=> (11 12 13)
(map #(% 10) (reverse add-fns)) ;=> (13 12 11)
Each of those expressions takes each function in add-fns and calls it with 10 as its argument, returning the results in a sequence.
Exception: macros don't follow the same rules:
user=> and
CompilerException java.lang.RuntimeException: Can't take value of a macro: ...
Some of the Java interop tricks don't follow the same rules, either.
a is always a symbol, independently of the value bound to it (whether it's a function or a number or anything else)
There's a previous answer on Clojure symbols that may clarify things a little bit more here: Symbols in Clojure
And remember symbols are not the same thing as vars

Clojure, why both key and values are using ":"?

(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.
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:
Can look themselves up in a map (def m {:abba 1 :beef 2}) .. (:abba m) => 1
Are easy to stringify (name :foo) => "foo"
Are easy to make from strings (keyword "bar") => :bar
Are performant: fast to compare and don't waste memory
: 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
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].

Using quote in Clojure

Quoting in clojure results in non-evaluation. ':a and :a return the same result. What is the difference between ':a and :a ? One is not evaluated and other evaluates to itself... but is this same as non-evaluation ?
':a is shorthand for (quote :a).
(eval '(quote form)) returns form by definition. That is to say, if the Clojure function eval receives as its argument a list structure whose first element is the symbol quote, it returns the second element of said list structure without transforming it in any way (thus it is said that the quoted form is not evaluated). In other words, the behaviour eval dispatches to when its argument is a list structure of the form (quote foo) is that of returning foo unchanged, regardless of what it is.
When you write down the literal :a in your programme, it gets read in as the keyword :a; that is, the concrete piece of text :a gets converted to an in-memory data structure which happens to be called the :a keyword (Lisp being homoiconic means that occasionally it is hard to distinguish between the textual representation of Lisp data and the data itself, even when this would be useful for explanatory purposes...).
The in-memory data structure corresponding to the literal :a is a Java object which exposes a number of methods etc. and which has the interesting property that the function eval, when it receives this data object as an argument, returns it unchanged. In other words, the keyword's "evaluation to itself" which you ask about is just the behaviour eval dispatches to when passed in a keyword as an argument.
Thus when eval sees ':a, it treats it as a quoted form and returns the second part thereof, which happens to be :a. When, on the other hand, eval sees :a, it treats it as a keyword and returns it unchanged. The return value is the same in both cases (it's just the keyword :a); the evaluation process is slightly different.
Clojure semantics -- indeed Lisp semantics, for any dialect of Lisp -- are specified in terms of the values returned by and side-effects caused by the function eval when it receives various Lisp data structures as arguments. Thus the above explains what's actually meant to happen when you write down ':a or :a in your programme (code like (println :a) may get compiled into efficient bytecode which doesn't actually code the function eval, of course; but the semantics are always preserved, so that it still acts as if it was eval receiving a list structure containing the symbol println and the keyword :a).
The key idea here is that regardless of whether the form being evaluated is ':a or :a, the keyword data structure is constructed at read time; then when one of these forms is evaluated, that data structure is returned unchanged -- although for different reasons.