Fork me on GitHub
#clojure
<
2023-10-11
>
Panel13:10:22

I'm curious why the core team added clojure.datafy/datafy when clojure.java.data/from-java was already there. One is a multimethod and the other a protocol but they seems to have the same purpose.

ghadi13:10:30

clojure.data/from-java is not a thing in clojure -- link to what you're looking at?

✔️ 1
Alex Miller (Clojure team)14:10:49

They don’t have the same purpose

👍 1
Alex Miller (Clojure team)14:10:32

java.data is about converting java objects following javabean patterns into Clojure data

Alex Miller (Clojure team)14:10:50

datafy/nav allow lazy partial walking over arbitrary object graphs (which may not be fully realized in memory, like databases via jdbc or Datomic)

Alex Miller (Clojure team)14:10:52

They do overlap in the sense of Java->Clojure but datafy/nav is much more general

Panel14:10:12

Thanks Alex. From what I understand if not using nav it's the same thing. Actually you could even use the nav meta without datafy ?

Panel14:10:46

Can I use the Navigable protocol with core map access function like get or :keyword ? Something like https://github.com/strojure/zmap. I need to navigate a geodatabase loaded from disk via interop. So I need to turn the java object into clojure maps lazily when accessing then. datafy/nav is cool for portal /rebl workflow, but I will rather use core fn to navigate the object graph.

Alex Miller (Clojure team)14:10:28

that is not the goal of datafy/nav but there have been a variety of lazy map implementations written over time

👍 1
seancorfield17:10:43

Also bear in mind that clojure.java.data is a separate Contrib library and is not part of core -- you need to add a separate dependency for it. And, as Alex says, it's intended for a completely different purpose. I maintain java.data these days and I'm also a heavy user of datafy / nav -- they are very different 🙂

Panel14:10:46

Can I use the Navigable protocol with core map access function like get or :keyword ? Something like https://github.com/strojure/zmap. I need to navigate a geodatabase loaded from disk via interop. So I need to turn the java object into clojure maps lazily when accessing then. datafy/nav is cool for portal /rebl workflow, but I will rather use core fn to navigate the object graph.

respatialized15:10:11

Is there a way to override an already-defined multimethod within a specific lexical scope in a manner similar to with-redefs?

borkdude15:10:25

capture the old definition with get-method, then define the new one, and when you leave the body, restore the old one?

borkdude15:10:35

(defmulti foo :id)
user=> (defmethod foo :dude [_] :dude)
#object[clojure.lang.MultiFn 0x1c12f3ee "clojure.lang.MultiFn@1c12f3ee"]
user=> (foo {:id :dude})
:dude
user=> (let [old-method (get-method foo :dude)] (.addMethod foo :dude (fn [_] :no-dude)) (prn (foo {:id :dude})) (.addMethod foo :dude old-method))
:no-dude
#object[clojure.lang.MultiFn 0x1c12f3ee "clojure.lang.MultiFn@1c12f3ee"]
user=> (foo {:id :dude})
:dude

👀 1
borkdude15:10:01

use try/finally for the proper implementation

respatialized15:10:07

Interesting. I do worry a bit about what might happen if this kind of dynamism is used in a multithreaded context. I think this https://github.com/camsaul/methodical may ultimately better support what I'm looking for, in part because it explicitly treats methods as immutable

borkdude15:10:30

well, you said, like with-redefs , which is kind of a footgun, especially when multi-threading, so I kinda assumed you meant "for testing"

respatialized15:10:39

Right, i forgot about that https://stackoverflow.com/a/20139566 myself when asking the question!

respatialized15:10:52

I think using vars for both the dispatch fn and the method impls would be enough for my purposes before reaching for a library like methodical.

borkdude15:10:03

perhaps it also helps that you can use a non-global :hierarchy?

emccue16:10:28

There is a library for that

emccue16:10:26

tube-alloys/redef-methods

emccue16:10:00

has caveats though