noprompt / meander

Tools for transparent data transformation
MIT License
918 stars 55 forks source link

Support structmap? #227

Open rgkirch opened 2 years ago

rgkirch commented 2 years ago

https://clojure.org/reference/data_structures#StructMaps "you cannot dissociate a struct map from one of its base keys"

(m/rewrite (struct (create-struct :tag :content) :name "bob")
  {:tag :name & {:content ?name}} ?name)

Even if meander doesn't change to make this code work, I want to at least record it here. It took me a while to figure out what was causing the exception.


  Show: Project-Only All 
  Hide: Clojure Java REPL Tooling Duplicates  (13 frames hidden)

1. Unhandled java.lang.RuntimeException
   Can't remove struct key

                 Util.java:  221  clojure.lang.Util/runtimeException
  PersistentStructMap.java:  179  clojure.lang.PersistentStructMap/without
                   RT.java:  891  clojure.lang.RT/dissoc
                  core.clj: 1513  clojure.core/dissoc
                  core.clj: 1506  clojure.core/dissoc
                      REPL:  190  rewrite.tree/eval32693
                      REPL:  190  rewrite.tree/eval32693
             Compiler.java: 7181  clojure.lang.Compiler/eval
             Compiler.java: 7136  clojure.lang.Compiler/eval
                  core.clj: 3202  clojure.core/eval
                  core.clj: 3198  clojure.core/eval
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 1977  clojure.core/with-bindings*
                  core.clj: 1977  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   84  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  152  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  218  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  217  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  748  java.lang.Thread/run
noprompt commented 2 years ago

Interesting! Hmm... it seems like this should possible. Some brain storming should happen here. Off the top of my head I'm thinking "what if we had a wrapper for maps/structs/sets which held on to a set of keys that have been removed from the collection such that find/contains? returns nil/false?". I'm open to ideas here.

rgkirch commented 2 years ago

Yea, my first thought was to just make it a map before matching against it but then you'd have some unavoidable overhead for large structures. I do think it makes sense to support dissocing here so I'm in favor of your suggestion. I don't have a better idea than that.