clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
Sam Ritchie 2020-12-27T03:24:50.474100Z

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?

alpox 2020-12-27T11:36:02.480300Z

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.

👍 1
Sam Ritchie 2020-12-27T15:24:07.480700Z

That is a good idea too

Sam Ritchie 2020-12-27T03:25:29.475100Z

In clojure i can extend APersistentMap, but no base class is available here of course

phronmophobic 2020-12-27T03:46:07.475200Z

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

phronmophobic 2020-12-27T03:46:39.475500Z

• cljs.core/PersistentHashMap • cljs.core/PersistentArrayMap • cljs.core/PersistentTreeMap • cljs.core/ObjMap , not totally sure about this one

phronmophobic 2020-12-27T03:48:50.475800Z

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 implementations

Sam Ritchie 2020-12-27T04:03:25.477300Z

Oh, nice, I’m not sure if I can extend a protocol to a protocol here...

Sam Ritchie 2020-12-27T04:03:30.477700Z

But that would be great

Sam Ritchie 2020-12-27T04:04:17.478700Z

On the JVM that only works for types that extended the protocol at definition time, since their classes also implement the interface

phronmophobic 2020-12-27T04:04:54.478900Z

it seems like most libraries do something like: https://github.com/noprompt/meander/blob/epsilon/src/meander/strategy/epsilon.cljc#L541

phronmophobic 2020-12-27T04:05:53.479200Z

ie. extend the protocol to the following types I listed above: • cljs.core/PersistentHashMap • cljs.core/PersistentArrayMap • cljs.core/PersistentTreeMap

Sam Ritchie 2020-12-27T04:06:48.479600Z

That is a great link

Sam Ritchie 2020-12-27T04:06:52.480Z

Thank you! That’s perfect

😁 1
Dan Maltbie 2020-12-27T21:43:39.481800Z

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.

Sam Ritchie 2020-12-27T22:11:29.482500Z

@dmaltbie I think your condition is backwards -

Sam Ritchie 2020-12-27T22:11:39.482800Z

try #?(:clj

Sam Ritchie 2020-12-27T22:11:52.483200Z

ie, use the keyword :clj instead of the form clj: that you have in that example

Sam Ritchie 2020-12-27T22:12:19.483500Z

and also yes, I believe it needs to be .cljc

Sam Ritchie 2020-12-27T22:12:50.483900Z

(maybe I am actually misunderstanding, I see now that this is in project.clj, and I understand less why you need a conditional there!)

Dan Maltbie 2020-12-27T22:14:00.484Z

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

Dan Maltbie 2020-12-27T22:14:36.484800Z

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?

Dan Maltbie 2020-12-27T22:15:59.485300Z

so you think that the reader conditional syntax should work with cljsbuild?

Dan Maltbie 2020-12-27T22:19:43.486Z

If I rename project.clj to project.cljc lein compile fails with error message Couldn't find project.clj, which is needed for compile

dpsutton 2020-12-27T22:27:03.486400Z

What would be different between the two?

Dan Maltbie 2020-12-27T22:28:44.487900Z

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.