[CLJ-890] Tagged literals in reader Created: 02/Dec/11 Updated: 01/Mar/13 Resolved: 03/Feb/12
|Reporter:||Stuart Sierra||Assignee:||Stuart Sierra|
|Comment by Stuart Sierra [ 02/Dec/11 5:32 PM ]|
Rough draft in
This adds reader tags like #user/foo. If the symbol following the # is namespace-qualified, or if it is one of a predefined set of built-in tags (currently empty) it is interpreted as a tag. Otherwise, it is interpreted as a class name, as in defrecord literals.
The dynamic Var *data-readers* is a map from tags (symbols) to reader functions/Vars. Each invocation of Compiler.load creates a new thread-local binding, as does the REPL. At the top of a source file, use (set! *data-readers* ...) to define the tags just for that file. For runtime invocations of the reader, use binding.
When reading a tagged literal, if the tag is not defined in *data-readers* it is added as :data metadata on the following form. If the following form does not support metadata, the tag is ignored. This causes a problem when an undefined tag is used in source code, because the compiler tries to evaluate it:
|Comment by Stuart Sierra [ 09/Dec/11 3:08 PM ]|
|Comment by Stuart Sierra [ 13/Jan/12 8:28 AM ]|
|Comment by Brandon Bloom [ 16/Aug/12 9:48 PM ]|
It would be a small extension to allow overriding of readers for untagged forms as well.
For example, MapReader currently calls RT.map(a) when it could call RT.get(data_readers, MAP_TAG).invoke(a)
This would allow consumers of the reader to supply their own implementations for any basic data structure. Not that anyone is likely to have a better map/set/etc, but I could see it being useful for using a different RegExp engine or something like that. The primary use case I have in mind, however, is the ClojureScript compiler. The compiler needs to know the order of the key-value-pairs in a map or the elements in a set. See CLJS-288