While writing a new reader I used clojure.lang.LispReader
code as the reference and I discovered there are two type of spaces:
- pure whitespace (anything that matches
#"[ \t\n\r,]+"
), - unvalued stuff (any sequence of: whitespace, comments, discard (
#_
), elided conditionals).
This leads to some quirks. For example in namespaced map syntax is:
namespaced-map:
"#:" (?! whitespace) unvalued-stuff symbol whitespace map
| "#::" symbol? whitespace map
(where ?!
is negative lookahead)
And indeed,
#:#_()#! bang bang
#?(:whatever 42); now a blank line
#?@(:default ())foo
{:bar :baz}
is readable and evaluates to #:foo{:bar :baz}
just fine.
Note: many REPLs choke on this input (use clojure.main -r
or call (read-string {:read-cond :allow} evil-string)
)
Likewise tagged literals actual syntax is:
tagged-literal:
"#" (?! dispatch-char) unvalued-stuff symbol unvalued-stuff form