clojurescript

dgr 2025-01-17T16:25:24.301189Z

Just found this in ClojureScript 1.8.40. Is this expected or is it a bug?

cljs.user=> *clojurescript-version*
"1.8.40"
cljs.user=> (compare {} (hash-map))
ERROR - Cannot compare {} to {}
cljs.user=> (compare (hash-map) {})
ERROR - Cannot compare {} to {}
cljs.user=> (compare {} {})
0
cljs.user=> (compare (hash-map) (hash-map))
0

thheller 2025-01-17T16:28:08.149229Z

{} is an empty array map and comparing things of different types is sort of undefined. not sure I'd call this a bug, but could probably be improved

p-himik 2025-01-17T16:35:55.569219Z

Another fun comparison - 1 to "1". Cannot compare 1 to 1.

2025-01-17T17:11:54.345349Z

@droberts3 what were you trying to do?

dgr 2025-01-17T17:22:53.205309Z

@thheller, given that Clojure/script auto-converts between array maps and hash maps silently, I would expect that comparing any sort of map to any other sort of map would be well defined. In particular, this works on Clojure JVM as expected.

dgr 2025-01-17T17:26:33.999629Z

@phill, this came up as a failing test case for the clojure.core-test test suite (https://github.com/jank-lang/clojure.core-test). It surprised me that this particular case was failing. Right now the test suite has a lot of tests failing as up until just a few days ago, the tests were being run only against ClojureJVM. I was going into look at the failing cases to adjust them for ClojureScript and this was one that wasn’t obvious it was an invalid test (i.e., ClojureScript has both compare as well as maps and the test case works on Clojure JVM, as compared to tests where ClojureScript doesn’t have the functionality, like ratios).

p-himik 2025-01-17T17:33:17.486129Z

> In particular, this works on Clojure JVM as expected. @droberts3 How did you test? If by using the same code, then try (type (hash-map)). So at the end of the day, the difference that you see is not due to how comparison works but due to how Clojure returns an array map even when you ask for a hash map.

dgr 2025-01-17T17:47:06.959339Z

Yea, I knew that. It looks like it’s a bit of both, oddly. If I force something to be a hash-map by adding 10 things to it and then removing them all via assoc/`dissoc`, Clojure JVM also throws an error and says that

Execution error (ClassCastException) at user/eval208 (REPL:1).
class clojure.lang.PersistentArrayMap cannot be cast to class java.lang.Comparable (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
So, this says that PersistentArrayMap is not even comparable at all. After looking at the source for Clojure compare, I’m guessing this is actually an artifact of the Clojure compiler generating a single constant for the map. compare basically checks for identical? as its first round of comparing things and thus nothing needs to be casted. But when the arguments aren’t identical, then they need to be Comparable. That tells me the test is invalid. I’ll update the code to remove it.

dgr 2025-01-17T17:47:16.548699Z

Sorry to have troubled y’all. Thanks for the answers.

souenzzo 2025-01-23T11:18:01.591089Z

Wired clojure behavior:

(compare
  (hash-map)
  (PersistentHashMap/create (seq [])))
hash-map is implemented via PersistentHashMap/create(hash-map) returns PersistentArrayMap (unexpected!!) • (PersistentHashMap/create (seq [])) returns PersistentHashMap I can't understand how (hash-map) returns an PersistentArrayMap

p-himik 2025-01-23T11:28:03.768629Z

In Clojure, maps with 8 or fewer elements are array maps, in general.

p-himik 2025-01-23T11:29:25.946599Z

Ah, in this case it's different - because 0-arity of hash-map returns {}, which is an array map.

Artur Angiel 2025-01-17T17:17:25.457909Z

Hello, I try to use Supabase Edge Functions for our project in ClojureScript, but I have problem with requiring Supabase JS client. It can't find 'http' module. I've created MRE for that - https://github.com/aangiel/shadow-supabase-edge-functions-require-http-mre Help please 😞

p-himik 2025-01-17T17:44:32.767619Z

I don't know what's going on but it compiles just fine for me. Even when node-libs-browser is removed from package.json.

p-himik 2025-01-17T17:45:16.013659Z

Ah, hold on - I didn't uncomment the line. Yeah, can reproduce and no idea either...

thheller 2025-01-17T17:54:07.106769Z

the default for :target :esm is to bundle all dependencies, but since you are targetting node this is not needed

thheller 2025-01-17T17:54:26.729299Z

so set :js-options {:js-provider :import} in the build config https://shadow-cljs.github.io/docs/UsersGuide.html#_third_party_tool_integration

thheller 2025-01-17T17:54:46.083959Z

should be fine after that

Artur Angiel 2025-01-17T18:03:42.564869Z

@thheller - build works like a charm! But I had to change require to "npm:@supabase/supabase-js", to make it fully work. Thanks!

thheller 2025-01-17T18:05:56.938519Z

side note: :source-paths ["src" "supabase/functions"] this should not have the output directory as a source path. this should only be src with the src files living under that root

thheller 2025-01-17T18:06:44.760799Z

it is generally not a good idea to put the output files with your source files

Artur Angiel 2025-01-17T18:07:12.699239Z

Thanks, it was just first try with that stuff