[CLJ-890] Tagged literals in reader Created: 02/Dec/11 Updated: 01/Mar/13 Resolved: 03/Feb/12 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Major |
| Reporter: | Stuart Sierra | Assignee: | Stuart Sierra |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Vetted |
| Description |
|
See http://dev.clojure.org/display/design/Tagged+Literals |
| Comments |
| 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: user=> #foo.bar/bar {:a 1}
CompilerException java.lang.RuntimeException: No such var: foo.bar/bar, compiling:(NO_SOURCE_PATH:0)
user=> (quote #foo.bar/bar {:a 1})
{:a 1}
user=> (meta *1)
{:data foo.bar/bar}
|
| Comment by Stuart Sierra [ 09/Dec/11 3:08 PM ] |
|
New file
|
| Comment by Stuart Sierra [ 13/Jan/12 8:28 AM ] |
|
Patch |
| 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 |