tags:

views:

163

answers:

4

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. "-" "_" "/".

[EDIT] I am not a java programmer. So i would not know the underlying ramifications if any. I dont know if the clojure keyword is mapped to a java keyword if there is such a thing. Also i could not find anything on this subject in my search.

+4  A: 

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.

tlberglund
Thanks thats what i wanted to know.
Santosh
@Santosh: In that case, you should accept this answer by clicking the check mark at the left. You may want to wait a bit to see if anyone else answers with additional information that you didn't know you wanted to know.
intuited
+5  A: 

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:

  • Keywords come in two flavours, qualified and unqualified. Unqualified keywords, like :foo, have no namespace component. Qualified keywords look like :foo/bar and 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.
  • Keywords can be created either by literals to the reader, like :foo, or by the keyword function, which is (keyword name-str) or (keyword ns name).
  • Keywords evaluate to themselves only, unlike symbols which point to vars. Note that keywords are not symbols.

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 is 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 the 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.

Rob Lachlan
Interesting. What i really want to do is use path variables as keywords. And I don't even want to use the ":". And my path variable chars are restricted to #"[A-Za-z0-9-_\/]". So I think it should be ok in that case.
Santosh
I think the real answer is to point to [the reader documentation](http://clojure.org/reader), which for example clearly prohibits several slashes in keywords and symbols.
kotarak
@kotarak: It clearly prohibits that in the case of symbols. Since keywords are not symbols, and all the documentation says is that "keywords are like symbols", I'd say that's clear as mud.
Rob Lachlan
@Santosh: sorry for the repeated edits. As you can see, it took a while to look at all sides of the question.
Rob Lachlan
@Rob thanks. I think you have managed to put the whole issue in the right perspective. This has been useful for me and i hope too for others who are researching this subject.
Santosh
+2  A: 

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

Alex Taggart
@Alex Taggart: Keywords aren't symbols.
Rob Lachlan
@Rob Lachlan: But the rules for symbols are applicable to keywords. There is a small variance noted in the linked docs which I've edited into my answer.
Alex Taggart
@Alex Taggart: First of all: +1. Second, I guess the problem that I really have with this is that a: the reader doesn't enforce good behaviour, and b: there seems to be no great harm in allowing arbitrary strings as keyword names and namespaces. Since all they really are are strings and hashes in a ConcurrentHashMap. Currently, the keyword function lets us put any fool strings we want as keyword names and namespaces. I would vote that it stay like this, but I'll concede that the question (of what behavior should prevail) is above my pay grade.
Rob Lachlan
Actually the reader documentation is not very accurate - I don't think it has been updated in a long time. For example, according to that document, the -> and ->> macros in core are illegal, because symbols may not contain an angle-bracket. I doubt there is any intention to remove or rename those, so it must the documentation that is out of date.
@Rob Lachlan: Agreed, hence the scare-quotes around correct.
Alex Taggart
A: 

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)

Arthur Ulfeldt