Problems
- It's very easy to accidentally print invalid EDN
- eg when doing host interop
- Workaround: (assert (= (clojure.edn/read-string (pr-str value)) value))
- There is no standard in-memory representation for tagged literals
- This is a problem for tools that want to analyze code
Workaround: (defrecord TaggedLiteral [tag value]), *default-data-reader-fn*Fails when tools want to collaborate: differing representations
- RESOLVED! in clojure 1.7
- extending print-method is a bad model
- Exposes mutable printer
- Requires each tagged-literal provider to implement the same printing logic
- Allows printing of unreadable forms
Potential Solution
(defrecord TaggedLiteral [tag value])Has a print-method which does the #tagged/literal "thing"
- (defprotocol ILiteral (-literal [this]))
- Converts an object into a valid EDN structure
- Add pr, prn, pr-str, and prn-str to clojure.edn
- Implements closed set of print methods for each EDN type
- Calls -literal on every object recursively
- Throws if any object isn't one of the EDN types
- Protocols are problematic for types with potentially differing representations and for non-owned types.
- Reading tagged literals is configured via two dynamic vars: 1) a map of symbols to readers and 2) a fallback function.
- Writing tagged literals could similarly be configured by a map of types to writers and a fallback function.
- That would allow for custom types to have multiple tagged literal representations depending on need.
Questions
Should ->EDN conversion be shallow or deep? Points for each.
- shallow: Can operate "lazily" without paying to convert the entire structure
- shallow: Deep couples conversion and traversal.
- deep: Shallow must use combine with clojure.walk or similar if a deep conversion is needed
- deep: More efficient than shallow + walk, when you want the whole structure converted
- shallow: Deep has much higher space complexity when composing traversals
My vote: Shallow, since almost every use of this protocol will immediately result in a composed (and often early-terminated) traversal.
An Implementation
Labels: