-
-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Permit implementing methods for print-method and pprint/simple-dispatch for defrecord #684
Comments
@grzm I will have a look at making the print multimethods work with babashka records. Not sure how easy this will be, but I agree that it would be nice if that would work. Meanwhile, you can make your code write tagged-literals like this: (defn maybe-regex [x]
(if (instance? java.util.regex.Pattern x)
(tagged-literal 're/re (str x))
x))
(defn ednify [x]
(walk/postwalk maybe-regex x))
(let [re #"some-re"
ednified (ednify re)]
(prn ednified)
(pprint/pprint ednified)) $ clojure -M /tmp/print.clj
#re/re "some-re"
#re/re "some-re"
$ bb /tmp/print.clj
#re/re "some-re"
#re/re "some-re" |
One option could be to indeed expose our type as a keyword on the record:
Another option could be to override the print-method defmulti with a custom implementation in sci/bb. |
re: |
Banging on tagged-literal a little more: (defn ednify-1 [x]
(cond
(instance? java.util.regex.Pattern x)
(tagged-literal 're/re (str x))
(or (instance? Regex x))
(let [v (str (:re x))]
(tagged-literal 'regex/re v))
(sci-record-instance? 'com.grzm.x.ppprint/Regex x)
(let [v (str (:re x))]
(tagged-literal 'sci.re/re v))
:else
x))
(defn ednify [x]
(walk/prewalk ednify-1 x))
(defn print-example [_]
(let [x {:foo #"some-re"
:bar (->Regex #"some-Regex")
:baz (with-meta {:re #"another-regex"}
{:sci.impl/record true, :type 'com.grzm.x.ppprint/Regex})}
ednified (ednify x)
ednified-meta (meta ednified)]
(println "prn")
(prn x)
(println "prn ednified")
(prn ednified)
(println "pprint")
(pprint/pprint x)
(println "pprint ednified")
(pprint/pprint ednified))) clojure output
babashka output
Doesn't solve the general |
Is your feature request related to a problem? Please describe.
I want to be able to print records as edn tagged literals. The typical way to do this in Clojure is to implement
clojure.core/print-method
(for most printing functions) andclojure.pprint/simple-dispatch
(forclojure.pprint/pprint
).print-method
andpprint/simple-dispatch
both dispatch on class*. This works in clojure, as defrecord defines a class. Instances of types defined in babashka areclojure.lang.PersistentArrayMap
maps with associated meta::sci.impl/record true
and:type
as the symbol of the record type: simply adding methods toprint-method
andpprint/simple-dispatch
won't work as we're not dispatching on class.*
print-method
also dispatches on meta, and coincidentally it's also the:type
metadata, but only if the :type is a keyword: they're symbols in babashka.Here's an example of what I've done successfully in JVM Clojure and the current behavior in babashka. I want to print
java.util.regex.Pattern
in edn using the tagged literal#re/re
. For example, the Clojure reader macro#"some-regex"
would be printed to edn as"#re/re "some-regex"
.Describe the solution you'd like
I'd like to be able to override
print-method
andpprint/simple-dispatch
the same way I would in JVMClojure, if this is feasible.
Describe alternatives you've considered
One alternative I've considered is dispatching on
clojure.lang.PersistentArrayMap
.clojure.lang.PersistentArrayMap
isn't currently exposed in babashka. If it were, I could then implementand dispatch (perhaps via another multimethod) on the metadata (if present). I'm not sure what the default behavior of the that dispatch would be, however: I'd prefer to call the other functions that handle printing of maps and other data structures, but most of those are private. I could potentially reimplement those private functions in some other namespace.
Another alternative may be to use keywords instead of symbols for the
:type
metadata to hook into the existingprint-method
dispatch function. I don't know what the implications for the rest of babashka would be. Also,pprint/simple-dispatch
only dispatches on class: it doesn't have the conditional to inspect an object's metadata, so I'd have to figure out a different solution forpprint/pprint
.Another idea I've briefly considered is porting ClojureScript's
IPrintWithWriter
andPrettyWriter
into some other namespace (print2
?) and useprint2/prn
andprint2/pprint
instead ofprn
andpprint/pprint
. However, before going down that route I wanted to get some feedback first.I'm hoping I've missed something glaringly obvious and simple to do with the existing implementation 😄
The text was updated successfully, but these errors were encountered: