I am looking for a list of the allowed characters in a clojure keyword. Specifically I am interested to know if any of the following characters are allowed: -
From that list, the reader certainly allows - and _, but / has a special meaning as the delimiter between namespaces and symbol names. Period (which you didn't ask about) is problematic inside symbol names as well, since it is used in fully-qualified Java class names.
As far as Clojure idiom goes, - is your best friend in symbol names. It takes the place of camel case in Java or the underscore in Ruby.
Edit:
When I initially composed this answer, I was probably a little too heavily invested in the question of "what can you get away with?" In fairness to myself though, the keyword admissibility issue appears to be unsettled still. So:
First, a little about keywords, for new readers:
:foo
, have no namespace component. Qualified keywords look like :foo/bar
where the part prior to the slash is the namespace, ostensibly. Keywords can't be referred, and can be given a non-existent namespace, so their namespace behaviour is different from other Clojure objects.:foo
, or by the keyword
function, which is (keyword name-str)
or (keyword ns name)
.What is officially permitted?
According to the reader documentation a single slash is permitted, a no periods in the name, and all rules to do with symbols.
What is actually permitted?
More or less anything but spaces seem to be permitted in the reader. For instance,
user> :-_./asdfgse/aser/se
:-_./asdfgse/aser/se
Appears to be legal. The namespace for the above keyword is:
user> (namespace :-_./asdfgse/aser/se)
"-_./asdfgse/aser"
So the namespace appears to consist of everything prior to the last forward slash.
The keyword
function is even more permissive:
user> (keyword "////+" "/////")
:////+//////
user> (namespace (keyword "////+" "/////"))
"////+"
And similarly, spaces are fine too if you use the keyword
function. I'm not sure exactly what limitations are placed on Unicode characters, but the REPL doesn't appear to complain when I put in arbitrary characters.
What's likely to happen in the future:
There have been some rumblings about validating keywords as they are interned. Supposedly one of the longest open clojure tickets is concerned with validation of keywords. So the keyword function may cease to be so permissive in the future, though that seems to be up in the air. See the assembla ticket and google group discussion.
The "correct" answer is documented:
Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, and ? (other characters will be allowed eventually, but not all macro characters have been determined). '/' has special meaning, it can be used once in the middle of a symbol to separate the namespace from the name, e.g. my-namespace/foo. '/' by itself names the division function. '.' has special meaning - it can be used one or more times in the middle of a symbol to designate a fully-qualified class name, e.g. java.util.BitSet, or in namespace names. Symbols beginning or ending with '.' are reserved by Clojure. Symbols containing / or . are said to be 'qualified'. Symbols beginning or ending with ':' are reserved by Clojure. A symbol can contain one or more non-repeating ':'s.
Edit: And further with respect to keywords:
Keywords are like symbols, except:
* They can and must begin with a colon, e.g. :fred.
* They cannot contain '.' or name classes.
* A keyword that begins with two colons is resolved in the current namespace
starting in 1.3 you can use '
anywhere not starting a keyword. so :arthur's-keyword
is allowed now :)
I use the keywords :-P
and :-D
to spice up my code occasionally (as synonyms for true and false)