Fork me on GitHub
#clojurescript
<
2022-11-27
>
Quentin Le Guennec10:11:28

My clojurescript repl is reading #?(:clj ..) reader conditionals, anyone knows why?

[:website] Build failure:
------ ERROR -------------------------------------------------------------------
 File: /Users/quentinleguennec/wp/ico+staking/src/shared/com/agoraverse/model/user.cljc:36:18
--------------------------------------------------------------------------------
  33 | 
  34 | #?(:clj
  35 |    (pco/defresolver global-score [env _]
  36 |      {::pco/input [:user/id]
------------------------^-------------------------------------------------------
com/agoraverse/model/user.cljc [line 36, col 18] Invalid keyword: ::pco/input.

p-himik10:11:09

The reader has to first read the whole form in order to discard it. Reading a keyword includes resolving its namespace alias, if there's one. If you never require something :as pco (or with :as-alias), the reader won't be able to resolve that keyword. That's also the case with the #_ way of commenting things. But I'm not sure what happens if you require pco under a :clj reader condtional. Is that exactly what's going on in your case?

Quentin Le Guennec10:11:32

Yep, pco is required in a :clj reader conditional. Hopefully the pco namespace was declared in a cljc file so requiring it globally solved the issue.

Quentin Le Guennec10:11:58

No idea how I would solve that if pco was exclusively clj though

phill11:11:23

Could you require it with as-alias in a cljs conditional?

Quentin Le Guennec11:11:54

I don’t know anything about as-alias, I’ll check it out

phill11:11:58

(Or spell out the namespace instead of using the :: short form, in the clj conditional)

p-himik11:11:55

> Yep, pco is required in a :clj reader conditional Then it sounds like a bug in the reader which I'd report to the author of the reader that you're using. Or maybe it's already reported - you could try searching for an issue in their bug tracker.

cjohansen11:11:24

Is satisfies? not supposed to work with values that implement a protocol through metadata? Is there another way to know if a value will respond to protocol function?

(defprotocol IProto
  :extend-via-metadata true
  (format-x [x]))

(def val
  (with-meta
    {:x "Hello"}
    {`format-x (fn [x] "FORMATTED")}))

(format-x val) ;;=> "FORMATTED"
(satisfies? IProto val) ;;=> false
I get the same result in both ClojureScript and Clojure, so I’m guessing this is intended, but still curious about what I can do instead.

p-himik11:11:16

Yes. Add a default implementation that does something reasonable instead of using satisfies?.

cjohansen11:11:05

Can I add a default implementation to everything, or will I have to enumerate every type it will be called with?

p-himik11:11:07

For every protocol, there's a single default implementation. From https://clojure.org/reference/protocols#_basics: > To define a default implementation of protocol (for other than nil) just use Object

p-himik11:11:35

IIRC it's slightly different in CLJS, but the concept is the same.

cjohansen11:11:04

Cool, thanks

👍 1
cjohansen11:11:31

Hah, there is (extend-type default ,,,) for ClojureScript, TIL