cljs-dev

quoll 2024-10-01T20:46:22.396799Z

Silly question (sorry), but is there a reason for key-test to test for (identical? key other) when the next line is (keyword-identical? key other) and that function also tests for (identical? key other)? I was wondering if it might be because the common case of testing a keyword against itself gets short circuited with the call to identical? instead of having to go into another function to do it. Then again, if that cost mattered, then I thought that testing for identical? twice for non-equivalent keywords would have been an expense. Then again, maybe it's just such fast execution that issues like double-calling are just left to the VM to clean up?

dnolen 2024-10-02T10:40:37.725159Z

Never looked at using them for keywords - mostly because they are relatively new feature - but also it would take a bit of work to assess the performance / code size tradeoffs.

👍 1
quoll 2024-10-01T20:47:36.991219Z

Also, it seems strange to be explicitly returning true, and not just defining:

(defn key-test [key other]
  (or (identical? key other) (keyword-identical? key other) (= key other)))
(leaving the call to identical? in there still)

borkdude 2024-10-01T20:49:09.243819Z

identical? in CLJS compiles to a very efficient JS check which is basically free

cljs.user=> (str (fn [] (identical? 1 2)))
"function (){\nreturn ((1) === (2));\n}"

borkdude 2024-10-01T20:49:38.649229Z

not completely free, but I think I have yet to meet the first person who made a noticeable optimization by skipping such a test

quoll 2024-10-01T20:49:45.243959Z

Yup. I've been looking at the code for the function:

function cljs$core$key_test(key,other){
if((key === other)){
return true;
} else {
if(cljs.core.keyword_identical_QMARK_(key,other)){
return true;
} else {
return cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(key,other);

}
}
}

quoll 2024-10-01T20:50:46.446709Z

I'm looking for something else, and it just struck me as "odd" that it gets tested for identical? twice

borkdude 2024-10-01T20:51:21.302239Z

cljs.user=> (keyword-identical? 1 1)
true
;)

😜 2
quoll 2024-10-01T20:52:08.213769Z

Then I realized that the cond returning explicit true seemed like a strange pattern as well. There's no problem per se, but I wondered if there was something going on here, and thought I'd ask

borkdude 2024-10-01T20:56:41.693939Z

google closure would optimize that (the if return true stuff), esbuild would too I think. this is what esbuild makes of it:

function cljs$core$key_test(e,r){return e===r||cljs.core.keyword_identical_QMARK_(e,r)?!0:cljs.core._EQ_.cljs$core$IFn$_invoke$arity$2(e,r)}

👍 1
dnolen 2024-10-01T22:55:30.384309Z

right there are some patterns you should not copy from core - or generated suboptimal code for a very long time

quoll 2024-10-01T23:23:08.723659Z

This is useful to know! Thank you

dnolen 2024-10-01T23:27:53.625649Z

in general code around the persistent stuff looks odd because it's concerned about codegen

quoll 2024-10-02T01:46:52.947849Z

I'm looking at some of the differences between PersistentHashMap on Clojure and ClojureScript. Part of it is due to following:

clj=> (identical? :a :a)
true
cljs=> (identical? :a :a)
false
That shows up in places like https://github.com/clojure/clojurescript/blob/b7ede4bce3e273ab85155fdd8463c291a6f81d43/src/main/cljs/cljs/core.cljs#L7498C17-L7498C49

quoll 2024-10-02T01:47:16.231179Z

So that's why I'm in that code right now

quoll 2024-10-02T01:50:45.111199Z

I do appreciate that keywords differ because ClojureScript doesn't have interning for them

mkvlr 2024-10-02T05:24:39.251069Z

@dnolen did you ever look into https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol for implementing keywords?