Fork me on GitHub
#clojurescript
<
2022-08-01
>
Kelvin16:08:21

I noticed a discrepancy between Clojure and ClojureScript when it comes to extend-protocol. Take the following two impls:

(require '[my.protoocols :as p])

;; Impl 1: Namespaced protocol fn
(extend-protocol p/Foo
  string
  (p/-foo [s] (foo-fn s))) ; Namespace

;; Impl 2: No namespace on protocol fn
(extend-protocol p/Foo
  string
  (-foo [s] (foo-fn s))) ; No namespace

Kelvin16:08:25

Both impls would work in Clojure, but only the second works in ClojureScript. If I do the first I’d get this error:

; WARNING: Use of undeclared Var my.protocols/p/-foo at line 1 <cljs repl>
; Execution error (TypeError) at (<cljs repl>:1).
; Cannot read properties of undefined (reading '_foo_')

Alex Miller (Clojure team)16:08:55

I suspect the first one working in Clojure is more accident than intent

Alex Miller (Clojure team)16:08:12

yeah, the namespace of that p/-foo is not even looked at (could be anything)

Alex Miller (Clojure team)16:08:19

the name is the important part

Alex Miller (Clojure team)16:08:59

this behavior should be considered undefined and thus both clj and cljs are not wrong (but probably Clojure should complain about this)

Alex Miller (Clojure team)16:08:55

the second example is the correct way

Lone Ranger17:08:41

Is there conditional compilation available for nodejs? Let me explain -- let's say I have this chunk of code.

(defn foo []
   (something something)
   (-> (.. js/document (querySelector ".foo"))
       something 
       something))
If I want to do conditional compilation for clojure, I can put this in a .cljc file and put in the appropriate reader conditionals. But if I want to reuse browser code on nodejs (let's say for lambda functions), the js/document will throw an error. Now, I know I can shim it out, but wondering if there's a more elegant way.

rolt17:08:02

in official clojurescript: no, but with shadow-cljs: yes https://shadow-cljs.github.io/docs/UsersGuide.html#_conditional_reading

Lone Ranger17:08:00

interesting, thanks!

agorgl17:08:39

Hello there! Quick question, what do you use to consume rest api's in clojurescript? Do you use js/fetch or some other library?

Lone Ranger17:08:21

I've had luck with but you're probably better off writing a light wrapper around js/fetch depending on your comfort level.

agorgl17:08:50

Ah nice, I've stumbled upon this too: https://github.com/r0man/cljs-http I'm just making a quick poll to see what people here use

Lone Ranger17:08:15

I like that one but it doesn't support certain things I needed like DELETE

Lone Ranger17:08:29

so depends on your use case

agorgl17:08:14

Does cljs-ajax support core.async?

Lone Ranger17:08:08

There's a few weird quirks with cljs-ajax. One of the params it accepts is a :handler argument which is a callback. You can do a pattern like

(defn my-post [opts]
  (a/go 
    (let [done? (a/promise-chan)]
       (ajax/post 
          (merge opts 
             :handler 
             (fn [data]
                (swap! some-atom some-func data)
                (a/offer! done? true))))
      done?))
             

Lone Ranger17:08:39

(my parens may be out of whack there)

Lone Ranger17:08:54

that would then make my-post an async function

agorgl17:08:02

Yeah you could always wrap them

Lone Ranger17:08:49

So yeah at that point might as well use fetch since the API will be more up-to-date

Michaël Salihi19:08:15

> ...but you're probably better off writing a light wrapper around js/fetch depending on your comfort level. If you don't want to write your own wrapper, there is https://github.com/lambdaisland/fetch

👍 2