Did you know about ::keywords?

In this week's „did you know“ will we have a short look at :keywords and what nice little features are hiding in there…

Keywords

We all know and love :keywords . They are a often used as keys in maps and their ability to be called like a function on maps makes for some very concise code.

user=> ( map :a [ { :a 1 } { :a 2 } { :a 3 } ] ) ( 1 2 3 )

However what happens if two libraries modify the same map? On the same key? Then we are in trouble, because one overwrites the other. To remedy this issue, Clojure provides (similar to Symbols) namespace-qualified keywords. Simply add a double-colon in front and the keyword will be qualified with the current namespace.

user=> ::foo :user/foo

Using the fully-qualified form, we can create keywords with an arbitrary namespace.

user=> :my.company.division.project.module-a/keyword :my.company.division.project.module-a/keyword

So we can communicate with a library using its own qualified keywords. The library can then internally use the short ::keyword form. But now imagine you have to use the above namespace several times! Ieck!

However, we can relax! Clojure wouldn't be Clojure if this was the only way to handle this situation. A little known fact is, that the double-colon form also allows for aliases! So all we have to do is set up a suitable alias for the namespace and we can save some serious typing.

( ns my.company.division.project.module-b ( :require [ my.company.division.project.module-a :as module-a ] ) )

And later on in the code we can simply use:

( get some-map ::module-a/keyword )

Nice and short.