Fork me on GitHub
#clojurescript
<
2022-09-02
>
shaunlebron19:09:36

Is there any reason why #(@foo) and #(deref foo) wouldn’t be equivalent?

p-himik19:09:17

Because @foo expands to (deref foo) so #(@foo) is actually #((deref foo)).

shaunlebron19:09:10

nice catch! thanks

dpsutton19:09:51

always let the reader expand those:

cljs.user=> '#(@foo)
(fn* [] ((clojure.core/deref foo)))
cljs.user=> '#(deref foo)
(fn* [] (deref foo))
i think noisesmith first showed me that

shaunlebron22:09:23

@U11BV7MTK interesting! thank you

shaunlebron22:09:03

looks like it also works for var:

user=> (def foo 1)
#'foo

user=> '#'foo
(var foo)

user=> (quote #'foo)
(var foo)

shaunlebron22:09:44

are there any other reader forms that we can be observe being desugared like this?

dpsutton22:09:27

anything that gets expanded by the reader presumably. But some things will have the same print representation like #{}

👍 1
shaunlebron22:09:57

ah, quoting itself ''foo => (quote foo) but I think that’s the last one

dpsutton22:09:47

prometheus=> `(inc)
(clojure.core/inc)
prometheus=> '`(inc)
(clojure.core/seq (clojure.core/concat (clojure.core/list 'clojure.core/inc)))

shaunlebron22:09:41

hmm, what’s going on there?

dpsutton22:09:50

evaluate what came back. it is equal to the first form

dpsutton22:09:07

but the semiquote operator can emit some pretty unoptimized sequence operations

dpsutton22:09:25

(seq (ocncat (list inc)) -> (inc) but its a roundabout way to get there

shaunlebron22:09:31

ah I see, wow

dpsutton22:09:09

i suspect it is related to it has to be able to accept ~@ splicing anywhere

👍 1
shaunlebron22:09:44

thanks again, update the cljs docs with some desugar examples: https://github.com/cljs/api/commit/dd197d169a39a22e58b66939be4d814fd4475c09

Lone Ranger19:09:09

I don't suppose there is an equivalent of clojure.core/extend in cljs, is there? 😞

Lone Ranger20:09:30

Oh, interesting. Advanced compilation... yeah that's a thing.

Lone Ranger20:09:11

Ok more direct follow-up, does anyone know of a programmatic way to do extend-type or extend-protocol? i.e., a hypothetical

(extend-types
 [Orange Strawberry Bananna]
 ISomeFuncManager
 (-some-func1 [this a] (* a a))
 Inst
 (inst-ms* [this] (inst-ms (java.time.Instant/now))))
?

p-himik20:09:38

With a macro?

Lone Ranger20:09:46

Yeah. This macro covers the sitauation I just described:

(defmacro extend-types [types & specs]
  (let [impls (#'clojure.core/parse-impls specs)]
    (list* 'do
           (map
            (fn [protocol]
              (let [spec       (get impls protocol)
                    next-specs (list* 'extend-protocol protocol
                                      (mapcat
                                       (fn [type]
                                         (conj spec type))
                                       types))]
                next-specs))
            (keys impls)))))
however, it does not work for this situation:
(let [fruit [Orange Strawberry Bananna]]
    (extend-types fruit
                  ISomeFuncManager
                  {-some-func1 (fn [this a] (* a a))}

                  Inst
                  #(inst-ms (java.time.Instant/now))))
and that's a huge bummer

Lone Ranger20:09:05

and I think bottom line it's a consequence of the fact that extend-protocol and extend-type are macros and you can't put in a variable for the classname

Lone Ranger20:09:55

Another way to put it, this won't work:

(defmacro extend-types [types & specs]
  (let [specs# (#'clojure.core/parse-impls specs)]
    `(for [~'t ~types]
       (extend-type ~'t ~specs#))))

Lone Ranger20:09:37

because this won't work either:

(let [fruit [Orange Strawberry Bananna]]
    (doseq [fruit fruits]
      (extend-type fruit
        ISomeFuncManager
        {-some-func1 (fn [this a] (* a a))}

        Inst
        #(inst-ms (java.time.Instant/now)))))

Lone Ranger20:09:10

It's easy enough to do in Clojure using extend, but I haven't found an equivalent way in cljs