Fork me on GitHub
#clojure
<
2023-04-16
>
lilactown21:04:41

is there a lib or an easy way to create "sub zippers" out of clojure.zip zippers? I want to write functions that look for nodes by calling clojure.zip/next scoped to a sub tree, edit a node, and then be able to zip back up to the larger tree root

lilactown21:04:16

my first thought is to create a new zipper out of the location of the sub tree and stash the original root as metadata, but experience tells me that meta data is not preserved in some cases

pppaul00:04:08

meta data is pretty safe in clojure. zippers use meta data. just test your transformations for meta data issues. also, there are other tools in clojure for working with trees, zippers are just one option

Brian Beckman00:04:24

Off the cuff, what are some of the other Clojure tools for idiomatically working with trees? When I’m not using zippers, I just resort to Scheme-style recursive functions, which are fine — I’m accustomed to them — but feel “out-dated.”

pppaul01:04:50

i use walk a lot, if you can spare the cycles it's pretty good

pppaul02:04:12

could you post a code example, i haven't used zippers for a very long time.

lilactown02:04:54

so I've forked clojure.zip to fix that issue for my use case

lilactown02:04:22

zippers work well for my use case. I'm writing a DSL for modifying a tree. so I can write code like

(-> config-json ; json read from file
    (zipper) ; create zipper
    (profile "Default profile") ; find the default profile
    (device [1452 834]) ; find device <vendor ID, product ID> inside of profile
    (remap "a" "z") ; remap key "a" to "z" for device in profile
    (to-json)) ; zip up to the top root and convert to json

igrishaev06:04:54

Maybe you can use my lib zippo: https://github.com/igrishaev/zippo it has the loc-update function that takes a predicate and a function that gets applied to the location if the predicate matches

igrishaev06:04:53

The code might look like this:

(-> read-json
    (to->zipper)
    (zippo/update-loc loc-profile? ...)
    (zip/root)
    (zippo/update-loc loc-device? ...)
    (zip/root))

lilactown16:04:53

that does look nice 😄 I think I wrote loc-find in my project. seems like a missing piece

lilactown16:04:19

I think the difference between my pseudo-code and your pseudo-code is that min is meant to scope the update of the key map to the device inside of the default profile

lilactown16:04:08

updat-loc to my understanding is great if you have a pred that matches a single node, but there could be multiple copies of the same "device" in different "profiles" in the tree I'm editing

igrishaev17:04:44

I see. Well, there is not a problem either. First, you find a corresponding node with loc-find (see the zippo library). Then you get the node and create a zipper from it. Then you edit that sub-zipper, get the node with zip/root and update the primary node you've found before.