Fork me on GitHub
#rewrite-clj
<
2021-09-23
>
yogthos15:09:29

so the use case I’ve got for rewrite-edn is that I want to update a config file while preserving formatting, and config uses aero and integrant which use reader tags

yogthos15:09:40

I’m guessing that #ig/ref :bar ending up as (read-string "#ig/ref :bar") is meant for it to get evaluated in the environment

yogthos15:09:12

but in my case I really just need to leave it as is, so I’m thinking the best approach might be to have a function to serialize to string and handle this case there

borkdude15:09:28

Hi @yogthos. This is an interesting issue.

$ bb -e '(rewrite-clj.node/sexpr (rewrite-clj.parser/parse-string "#foo {:a 1}"))'
(read-string "#foo {:a 1}")
It seems rewrite-clj behaves like this and it just manifests in rewrite-edn as well. Perhaps the stringification of the node isn't very accurate

borkdude15:09:35

whereas:

$ bb -e '(str (rewrite-clj.parser/parse-string "#foo {:a 1}"))'
"#foo {:a 1}"

yogthos15:09:50

hmm yeah I think there should probably be an extra step during stringification

borkdude15:09:19

I meant sexprification instead of stringification

borkdude15:09:29

the str-ion seems accurate enough

borkdude15:09:50

The issue here might be that there is no way to make this into a s-expr without making up some kind of thing

lread15:09:04

Ya I noticed that rewrite-clj’s sexpr will sometimes return (read-string...) https://github.com/clj-commons/rewrite-clj/blob/main/doc/01-user-guide.adoc#reader-macro-chars…

borkdude15:09:10

because the reader normally turns this into a s-expr but for this you need to actually execute the reader tag function

borkdude15:09:54

should rewrite-clj be able to get an :readers option which will actually execute the function?

yogthos15:09:57

would it be possible to add metadata in rewrite-clj to disambiguate?

yogthos15:09:39

and yeah passing :readers explicitly could work as well

borkdude15:09:09

like this for example:

$ bb -e '(rewrite-clj.node/sexpr (rewrite-clj.parser/parse-string "#foo {:a 1}") {:readers {(quote foo) identity}})'
(read-string "#foo {:a 1}")

borkdude15:09:24

(parse-string "#js [1 2 3]" {:readers {'js (fn [v] (list 'js v))}})
(js [1 2 3])

borkdude15:09:30

(this is from edamame)

borkdude15:09:49

being able to pass a fn (and not only a map) also gives more flexibility

lread16:09:58

So, being a bit slow simple_smile, I’m not sure I understand yet. Are we talking about this?: code as text -> rewrite-clj node -> clojure form -> rewrite-clj node -> code as text?

lread16:09:05

Sexpr in rewrite-clj is… nuanced… can work… but there are real limitations. Is it possible to work from rewrite-clj nodes only, or is using rewrite-clj’s sexpr necessary for this use case?

yogthos17:09:58

in my use case I don't need to use sexpr as I just need to roundtrip text to text

yogthos17:09:38

so yeah looks like I can just skip that step and everything works as intended, e.g:

(let [zloc (-> (slurp "system.edn") (rewrite-edn/parse-string))
     child (rewrite-edn/parse-string "{:label "ig/ref", :value ":system/env"}")]
    (str (rewrite-edn/assoc-in zloc [:router/core] child)))

yogthos17:09:08

not sure if the current sexpr behavior is desirable or not, but I think just documenting this would be enough for now

lread21:09:48

Yeah it is kinda sorta documented under sexpr nuances in the user guide.