Fork me on GitHub
#clojurescript
<
2022-08-07
>
seancorfield06:08:54

I'm writing some .cljc code that does extend-protocol. In Clojure, it extends String and Object and for ClojureScript I tried js/String and js/Object and while the code works, I get these warnings:

WARNING: Extending an existing JavaScript type - use a different symbol name instead of js/String e.g string at line 267 /home/seanc/oss/honeysql/src/honey/sql.cljc
WARNING: Extending an existing JavaScript type - use a different symbol name instead of js/Object e.g object at line 267 /home/seanc/oss/honeysql/src/honey/sql.cljc
However, if I "use a different symbol name" the extensions don't work. What do this warning actually mean and what should I use in extend-protocol rather than js/String and js/Object?

p-himik06:08:31

Also, I just tried the suggested string and object with a Node-backed CLJS REPL and it seems to be working just fine.

seancorfield06:08:09

Hmm, doesn't work at all with cljs-test-runner which is what HoneySQL uses.

seancorfield06:08:49

So I'm guessing this is a ClojureScript version issue?

p-himik06:08:22

It might be because Object in CLJ is a catch-all and object in CLJS is specifically for something that satisfies object?.

p-himik06:08:54

cljs.user=> (extend-protocol P object (foo [_] (println "object P")))
#object[Function]
cljs.user=> (foo #js [])
Execution error (Error) at (<cljs repl>:1).
No protocol method P.foo defined for type array: 

cljs.user=> (foo #js {})
object P
nil

seancorfield06:08:32

I'm using cljs-test-runner 3.8.0 which is the latest version but it uses ClojureScript org.clojure/clojurescript {:mvn/version "1.10.773"}

p-himik06:08:10

1.11.60 here.

seancorfield06:08:25

Is there an equivalent "catch all" type for cljs to Object?

seancorfield06:08:34

(and what about js/String?)

p-himik06:08:33

A-ha, on CLJS the catch-all is default. And for js/String it's just the suggested string.

seancorfield06:08:46

When I use string instead of js/String a lot of tests fail so that's clearly a bad substitution.

p-himik06:08:23

(unless you construct a js/String object instead of using a string JS primitive - it's not an intuitive concept in JS at all)

p-himik07:08:16

What does a test failure look like?

seancorfield07:08:01

OK, default works instead of js/Object. Thanks.

seancorfield07:08:16

Clone the repo and change that js/String to string and you'll see.

seancorfield07:08:57

clojure -T:build ci is how to run the tests.

p-himik07:08:06

0 failures, 0 errors. throughout the whole suite, which took some time.

seancorfield07:08:30

Hmm, so I need both changes together. I'd tried just string instead of js/String while I still had Object and it didn't work. OK. Thanks for checking @U2FRKM4TW I appreciate it.

👍 1
seancorfield07:08:28

And thanks for the explanation/pointers. I don't do cljs so I find these differences from clj to be annoying/bewildering at times -- and things seem to change very frequently in the cljs world without much external documentation.

p-himik07:08:09

That particular CLJS warning has been introduced 9 years ago, so it's definitely much older than the warnings from CLJ about all the new functions being shadowed by libraries because the names are so popular. ;) I don't feel like similar things happen noticeably more often than in CLJ, but of course YMMV. Also, I had no clue about all this myself - just git blamed the CLJS source code and found the issue with the explanation. And checked the source code for extend-type to find what the catch-all word should be.

lilactown07:08:32

The reason you don't want to use extend-type and extend-protocol with built in "types” is because “extending” means mutating those objects, and it's generally frowned upon to mutate built in objects

lilactown07:08:13

Using the string, object, default, etc. symbols actually uses a lookup table instead of mutating the object

didibus02:08:15

Ya, I do feel Clojurescript doesn't have enough info/doc about it. Or it's just too hard to find and realize it's actual about Clojurescript. But if already Clojure could do with better docs, Cljs is in even more dire needs.

👍 1