Does:
> Keywords - Keywords are like symbols, except:
> They can and must begin with a colon, e.g. :fred.
Mean that the second character of a keyword (in this case 'f') follow the same rules as the second character of a symbol (e.g. can be a number) or that they follow the rules as the first character of a symbol (e.g. cannot be a number).
Essentially, is :1
valid?
This question has been raised before, and it seems that reasonable people can interpret that statement in (at least) two different ways.
The Clojure reader accepts it now, and there was a patch that made it illegal for one or two alpha/beta releases several years ago, and then it was undone, because several projects used such keywords. Hyrum's Law is an interesting thing to know about as a software developer: https://www.hyrumslaw.com
Annoyingly, :foo/1
is not accepted by the reader.
heh, but ::1
is, so you can produce something that cannot then be read:
user=> (read-string (pr-str ::1))
Execution error at user/eval391 (REPL:1).
Invalid token: :user/1
A twist on this is: those restrictions are about the symbols and keywords that the reader accepts, the symbol and keyword functions are happy to make any keywords you like. This often trips people up.
Any kinds of changes in these things are likely to break something somewhere, unless extremely carefully done, and changes that don't break anything seem unlikely to make anyone happy in a "all of the invariants I wish were true, e.g. everything printable is readable" sense. That said, for all I know there could be changes planned in this area in a future release.
Mmhm, I'm not too worried about changing the reader itself (although :foo/1
should probably work as ::1
does, hyrums law and all :) ). Just curious about what is "proper" I suppose.
These are the questions that keep me up at night (or at least at 5:43)
FWIW, we have several places in our code where we do something akin to
(def m {(keyword foo) 'bar}
...
(get m (keyword baz))
Where (keyword foo)
can produce an unreadable keyword.@dominicm the original intent was that symbols and the non-colon parts of keywords should follow the same naming rules which would mean :1 is invalid (because 1 is an invalid symbol)
The regex in the reader for keywords is wrong. Back in 1.6 I think we fixed it and it broke a bunch of existing code
For issues such as this, would it not be useful to create specs that tighten the contract to the intended/desired behaviour? Thinking like speculative but possibly a step further — specs to prevent you shooting yourself in the foot and creating unreadable keywords etc?
I'm not sure where you would apply such a spec - this is down in the reader code
seems like it would be pretty invasive to install a tighter spec for keyword?
or whatever
We saw no point in breaking stuff people relied on so we reverted it so it’s lived in kind of a gray area since then
These appear to be the questions that keep you up at 05:00 also :)
There are several tickets I could refer you to if you cared
I think it’s highly unlikely we will make stuff that works now stop working
We may make stuff that doesn’t work now start working :)