Prior to Clojure 1.4.0, the reader only ever emitted a fixed set values, including scalars, vectors, maps, and so on. (There are some ill-advised ways around this, but they are largely made irrelevant by 1.4's extensible reader.)
With Clojure 1.4.0,
you can control how the reader produces values for literals. This doesn't allow you to change syntax arbitrarily (i.e. all forms still need to be s-expressions consisting of scalars, lists, sets, and so on), but it does allow you to specify any function you like that will, at read-time, be able to control what value comes out of the other end of the reader.
For example, Clojure does not currently define built-in syntax for URIs or URLs. This could make things more cumbersome in your application if you work with URIs a lot, as you'd always have to manually use
java.net.URI to parse strings containing URIs, and then producing strings again if you needed to send them to storage or across the wire to a client. With the extensible reader, you could specify URIs using syntax like:
…where the
#net/uri tag would correspond with a function that the reader would invoke with the value immediately after the tag in order to determine what the reader will return for that value. The function corresponding with
#net/uri might be something as simple as returning a
URI instance:
…and so, with this in place, the reader would return a
java.net.URI value anywhere the
#net/uri tag is used, without any additional work on your part.
To learn more, read the
1.4.0 changelog sections related to the extensible reader, which talk about how to get your reader functions mapped to tags, and various other details.
--
(coauthor of
Clojure Programming from O'Reilly; creator of
Clojure Atlas)