Hey all! If I want to extend a protocol to all of the hashmap implementations in cljs, is there some recommended way to do that? Make a map of the impls and use extend on each, perhaps?
I have just read in Clojure Applied
about extending a protocol to a protocol and they showed a possible solution where they extended the target protocol for Object
with an implementation that asks if the object satisfies the "parent" (here IMap) protocol and if so, implements the protocol for the caller type. On next call, the call would be dispatched directly to the new implementation.
That is a good idea too
In clojure i can extend APersistentMap, but no base class is available here of course
from searching, it seems like there's a few types you'll want to extend. https://grep.app/search?q=cljs.core/persistentHash&filter[lang][0]=Clojure
• cljs.core/PersistentHashMap • cljs.core/PersistentArrayMap • cljs.core/PersistentTreeMap • cljs.core/ObjMap , not totally sure about this one
map?
is defined as:
(defn map?
"Return true if x satisfies IMap"
[x]
(if (nil? x)
false
(satisfies? IMap x)))
So potentially anything that implements IMap. Not sure if there's a clean way to look up all IMap
implementationsOh, nice, I’m not sure if I can extend a protocol to a protocol here...
But that would be great
On the JVM that only works for types that extended the protocol at definition time, since their classes also implement the interface
it seems like most libraries do something like: https://github.com/noprompt/meander/blob/epsilon/src/meander/strategy/epsilon.cljc#L541
ie. extend the protocol to the following types I listed above: • cljs.core/PersistentHashMap • cljs.core/PersistentArrayMap • cljs.core/PersistentTreeMap
That is a great link
Thank you! That’s perfect
I'm using Shadow-cljs for my compiler and am trying to track down a problem with npm version mismatches (two modules requiring a different version of another module). I wanted to verify that the code would compile with a different cljs compiler and tried `cljsbuild`. It appears that it does not like reader conditionals (.i.e., `#?(clj:`). Does this only work with Shadow-cljs or is there another compiler that handles reader conditionals? I saw the note in the user guide (sec 6.8) saying it was not a standard feature but it is really useful so I hate to give it up. I'm finding that cljsbuild only complains about conditionals in the project.clj file. Do I need to rename this to .cljc? If I remove the Java specific require statements from the project.clj file my code compiles fine.
@dmaltbie I think your condition is backwards -
try #?(:clj
ie, use the keyword :clj
instead of the form clj:
that you have in that example
and also yes, I believe it needs to be .cljc
(maybe I am actually misunderstanding, I see now that this is in project.clj, and I understand less why you need a conditional there!)
sorry. my comment was wrong. actual code in project.clj is
:dependencies [[org.clojure/clojure "1.10.1"]
[org.clojure/clojurescript "1.10.764"]
[org.clojure/core.async "1.3.610"]
#?(:clj [mvxcvi/alphabase "2.1.0"])
#?(:clj [mvxcvi/multihash "2.0.3"])
#?(:clj [net.named-data/jndn "0.24"])
#?(:clj [org.clojure/java.jdbc "0.7.8"])
#?(:clj [org.postgresql/postgresql "42.2.5.jre7"])
#?(:clj [org.clojure/tools.reader "1.3.2"])
#?(:clj [com.github.serceman/jnr-fuse "0.5.4" :exclusions [org.ow2.asm/asm]]) ;; 0.5.2.1
#?(:clj [org.clojure/data.xml "0.0.8"])
#?(:clj [nio "1.0.4"])
#?(:clj [bytebuffer "0.2.0"])
#?(:clj [clojure-msgpack "1.2.1"])
#?(:clj [org.clojure/math.numeric-tower "0.0.4"])
#?(:clj [org.clojure/java.classpath "1.0.0"])
#?(:clj [clj-http "3.9.1"])
]
i'm trying to use the same project.clj file for both JVM and JS version of the code. Is there a better way to do this?
so you think that the reader conditional syntax should work with cljsbuild
?
If I rename project.clj to project.cljc lein compile
fails with error message Couldn't find project.clj, which is needed for compile
What would be different between the two?
for instance java specific modules (.clj only) would not be loaded when compiling for javascript. And the import statement would not be relevant for javascript since it is importing java libraries.