cljs-dev

p-himik 2025-11-23T15:12:33.871149Z

Looks like the docstring of parents is wrong? https://ask.clojure.org/index.php/14764/how-does-parents-work-for-javascript-inheritance I don't see anything relevant in the impl that would care about JS types.

dnolen 2025-11-23T17:02:57.508479Z

well, more like unfinished - we should fix that not the docstring

dnolen 2025-11-23T17:00:56.036649Z

Notes for the next release, feedback welcome https://github.com/clojure/clojurescript-site/blob/801fbdc16a7b0bb58c8795e9eeb9ae072ec43947/content/news/2025-11-24-release.adoc

🆒 2
🙌 1
Felipe 2025-11-24T18:23:10.557199Z

maybe a silly question: why does the API for proxy require you to def your own builder? why can't you simply call a cljs.proxy/proxy fn and get the proxied data structure?

dnolen 2025-11-24T18:29:54.229159Z

the builder lets you supply your own key-fn, the zero arity version uses a default key-fn

dnolen 2025-11-24T18:30:15.442879Z

it could change, of course, feedback appreciated

dnolen 2025-11-24T18:30:45.515589Z

the builder docstring outlines some non-obvious things about how it works, worth looking over

👍 1
Felipe 2025-11-24T18:39:21.852039Z

yeah was taking a look just now. for ergonomics I wish I could use a pre-built (builder keyword) as that's what I imagine I'd want for interop in most cases, but it's simple enough to define my own

dnolen 2025-11-24T18:43:45.492869Z

noted, feedback is being collected 🙂

🙌 1
dnolen 2025-11-24T18:54:14.970649Z

https://clojure.atlassian.net/browse/CLJS-3462 - one problem is just what to name the thing

dnolen 2025-11-23T18:26:44.030229Z

@jarrodctaylor @alexmiller whenever you all are around, I cannot cut a release myself, the artifact gets made, but the release step fails

Jarrod Taylor (Clojure team) 2025-11-23T18:37:17.934579Z

I’ll look into it in the morning when I have some focus time and report back here.

👍🏽 1
🙏🏽 1
Jarrod Taylor (Clojure team) 2025-11-24T17:26:25.970519Z

@dnolen The release action is back in working order.

💥 1
dnolen 2025-11-24T17:26:56.777849Z

Thank you!

Jarrod Taylor (Clojure team) 2025-11-24T17:27:48.820789Z

Glad to help

Alex Miller (Clojure team) 2025-11-24T18:24:11.393239Z

Thanks Jarrod!

dgr 2025-11-23T23:01:19.487429Z

Is this expected or is it a bug?

ClojureScript 1.12.42
cljs.user=> (< 1 nil)
false
cljs.user=> (< nil 1)
true
Clojure JVM throws for the arity-2+ case when given nil as one of the arguments (but not for the arity-1 case where true is returned without checking the argument). This appears to treat nil as equivalent to zero in this case.

borkdude 2025-11-23T23:06:45.977769Z

Many math-related functions don't do any checking on the input and just compile directly to JS math. This is usually for performance reasons.

dgr 2025-11-23T23:08:38.135809Z

Hm. But this:

cljs.user=> (= nil 0)
false
so it’s not as if nil equals zero in all cases.

borkdude 2025-11-23T23:09:35.003239Z

= is an exception. CLJS implements its own equality semantics (for data structures, etc)

dgr 2025-11-23T23:09:54.585819Z

So is this the answer? https://stackoverflow.com/questions/2910495/why-null-0-null-0-but-not-null-0

dgr 2025-11-23T23:11:05.133719Z

I am not a JavaScript expert by a longshot.

borkdude 2025-11-23T23:11:19.561979Z

yes, with regards to <, > etc you are delivered to JS craziness

dgr 2025-11-23T23:11:41.607859Z

OK, thanks. It is what it is.

borkdude 2025-11-23T23:12:28.920049Z

you can check how something is compiled with this little trick:

cljs.user=> (str (fn [] (= nil 0)))
"function (){\nreturn cljs.core._EQ_.call(null,null,(0));\n}"
cljs.user=> (str (fn [] (< nil 0)))
"function (){\nreturn (null < (0));\n}"

🤯 1
jeaye 2025-11-23T23:12:36.986819Z

JS is 💥.

dgr 2025-11-23T23:14:29.008289Z

Thanks @borkdude. I’ll add that to my bag of tricks

dnolen 2025-11-24T00:37:17.075789Z

also == is for numbers

jeaye 2025-11-24T00:40:12.282759Z

@dnolen Speaking of JS 💥 and numeric equality, you said at the Conj that long is a no-op. This is the use case I was referencing, though. What's going on here?

=> (== 5 "5")
false
=> (== 5 (long "5"))
true

dnolen 2025-11-24T00:44:09.202119Z

@jeaye actually it was at one point, now just calls fix - behaviour is identical to int - the docstring are descriptive here

dnolen 2025-11-24T00:45:05.637419Z

== is a inlining macro that becomes === operator in JS

jeaye 2025-11-24T00:45:16.594859Z

How many = can there be?

dnolen 2025-11-24T00:47:18.519429Z

yeah JS numerics in CLJS are just JS numerics - it's going to require some serious thought how to get around that w/o breaking a lot of code wrt. performance.

dgr 2025-11-24T01:30:49.799149Z

@dnolen, I’m not sure I understand your comment about == being for numbers. = and == should return the same result for numbers, right? It’s just that == is specialized for numbers and therefore faster, no? Whereas = can compare more things and is therefore slower?

dnolen 2025-11-24T01:34:09.907249Z

first - Clojure doesn't really make very many promises about what happens w/ the wrong inputs - because that creates problems for the fast path. That's kind of a fundamental design choice.

dgr 2025-11-24T01:34:57.339399Z

Right. Understood.

dnolen 2025-11-24T01:36:34.202149Z

ClojureScript numerics are particularly this way - it's just JS numerics, because on the fast path it's great - the persistent data structres themselves rely on this being the case

dgr 2025-11-24T01:38:40.040569Z

Cool. To be clear, nothing I’ve asked about should be taken as a value judgement. I’m working on writing tests for clojure-test-suite, and as I go along I’m finding stuff like this and wanting to run it by folks who have more knowledge than I do to make sure everything is as-expected. I’m naturally probing the corners of functionality and using Clojure JVM there as the yardstick, so anything that differs in a way that isn’t obviously caused by the underlying platform, I’m asking about. Feel free to just tell me, “Yep, that’s the way it works because we just delegate to JS for that and that’s the way it handles it.” If that’s the case, I’ll just conditionalize the test with the CLJS behavior and move along.

dnolen 2025-11-24T01:39:19.285199Z

not assuming anything over here, so no worries.

👍 1
dnolen 2025-11-24T01:40:29.861129Z

ClojureScript leverages the fact that JS math is fast if the VM detects that code is implicitly operating on 32 bits.

dnolen 2025-11-24T01:40:38.408239Z

So we don't check anything at all.

dgr 2025-11-24T01:41:08.999119Z

Yep, totally rational way to do it. And JavaScript is, ahem, creative on many of these issues.

dnolen 2025-11-24T01:41:41.455709Z

the problem is that w/o checks of course you run into all the coercion crap.

dgr 2025-11-24T01:42:23.794679Z

That’s what I figured and why I was asking. What threw me for a loop is that with < nil compares as zero, but = does not.

dnolen 2025-11-24T01:42:34.394429Z

But really that stuff is not about proper numeric code, rather just weird stuff due to being a scripting language in the web browser.

dgr 2025-11-24T01:43:26.536119Z

Yep, exactly.

dnolen 2025-11-24T01:46:05.459049Z

so not just numerics, but arrays would be weird too. places that host coercion appears

dnolen 2025-11-24T01:46:29.693739Z

all of these cases would be ill-formed Clojure(Script) programs

dgr 2025-11-24T01:47:27.412479Z

I noticed that the CLJS REPL will print a warning for some of these cases, but then allow them and execute the form and print the (odd) result.

dnolen 2025-11-24T01:48:15.841989Z

warning is a compile time attempt to let the user know their program is ill formed

dnolen 2025-11-24T01:48:20.953999Z

but runtime checks are too costly

dgr 2025-11-24T01:48:37.026349Z

Makes sense

dnolen 2025-11-24T01:50:28.762959Z

a related problem is JS falsey values, 0 and the blank string are false-y in JS.

dnolen 2025-11-24T01:50:58.483479Z

so every (if x ...) needs to guard against this, it's a performance hole.

dnolen 2025-11-24T01:51:35.139889Z

back ~2012, we started adding ^boolean hints to get rid of the checks so that PersistentVector would have acceptable perf

dgr 2025-11-24T01:51:58.469349Z

Yea, as I was telling @jeaye earlier, every time I interact with JavaScript, I walk away shaking my head and muttering “WTF??” 🙂

dgr 2025-11-24T01:52:34.820729Z

The JavaScript designers made some interesting choices, let’s just say.

dgr 2025-11-24T01:52:52.804409Z

As you said, it’s a scripting language in a browser.