rewrite-clj

yogthos 2021-09-23T15:14:38.000500Z

@borkdude hi 🙂

yogthos 2021-09-23T15:16:29.001800Z

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

yogthos 2021-09-23T15:20:40.002700Z

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

yogthos 2021-09-23T15:22:12.004Z

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

borkdude 2021-09-23T15:39:28.005300Z

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

borkdude 2021-09-23T15:40:35.006Z

whereas:

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

yogthos 2021-09-23T15:42:50.006600Z

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

borkdude 2021-09-23T15:44:19.007300Z

I meant sexprification instead of stringification

borkdude 2021-09-23T15:44:29.007600Z

the str-ion seems accurate enough

borkdude 2021-09-23T15:45:50.008800Z

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

lread 2021-09-23T15:46:04.009300Z

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…

borkdude 2021-09-23T15:46:10.009700Z

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

borkdude 2021-09-23T15:46:54.010900Z

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

yogthos 2021-09-23T15:46:57.011100Z

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

yogthos 2021-09-23T15:47:39.011800Z

and yeah passing :readers explicitly could work as well

borkdude 2021-09-23T15:48:09.012Z

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}")

borkdude 2021-09-23T15:50:24.012300Z

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

borkdude 2021-09-23T15:50:30.012500Z

(this is from edamame)

borkdude 2021-09-23T15:50:49.012900Z

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

lread 2021-09-23T16:00:58.015400Z

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?

lread 2021-09-23T16:03:05.016900Z

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?

yogthos 2021-09-23T17:12:58.017600Z

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

yogthos 2021-09-23T17:18:38.019300Z

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)))

yogthos 2021-09-23T17:19:08.020Z

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

lread 2021-09-23T21:44:48.020400Z

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