Motivation
To add extensibility to the Clojure reader in a composable way.
General Goals
- new syntax for "tagged" literals in the reader
- tags can be namespaced
- non-namespace-qualified tags are reserved for Clojure
- when the reader encounters a tagged literal, it invokes a function associated with that tag
- users may define new tags and tag-reader functions
- users may override functions for built-in tags
Non-goals
- Common Lisp-style reader macros
- Custom parsing of the character stream
- Reader will parse tagged literals as data and pass that to the tag function
Open Questions
- What is the syntax for tags?
- Keywords, like
#:tag form- One character longer
- Slightly easier to parse
- Symbols, like
#tag form- One character shorter
- Slightly harder to parse
- Ambiguous with record constructors?
- Not if we assume that:
- 1) record names always contain a dot
- Which they must, because deftypes occur in namespaces
- 2) user-defined tags are always namespace-qualified
- 3) built-in tags do not contain a dot
- What happens when the reader encounters a tag for which no function is defined?
- Error (YES)
- Return form unchanged?
- Return form with extra metadata?
- Only possible if form supports metadata, ignore otherwise?
- How to associate tags with reader functions?
- file containing mapping from tags to Vars
- "magic" file name gets loaded before other files
- doesn't load any code directly
- If 2 JARs on classpath have a magic file, who wins?
- map stored in dynamic var
- thread-local binding for each source file
- can be set! within a source file
- can be rebound when invoking the reader at runtime
References / See Also