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.
well, more like unfinished - we should fix that not the docstring
Notes for the next release, feedback welcome https://github.com/clojure/clojurescript-site/blob/801fbdc16a7b0bb58c8795e9eeb9ae072ec43947/content/news/2025-11-24-release.adoc
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?
the builder lets you supply your own key-fn, the zero arity version uses a default key-fn
it could change, of course, feedback appreciated
the builder docstring outlines some non-obvious things about how it works, worth looking over
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
noted, feedback is being collected 🙂
https://clojure.atlassian.net/browse/CLJS-3462 - one problem is just what to name the thing
@jarrodctaylor @alexmiller whenever you all are around, I cannot cut a release myself, the artifact gets made, but the release step fails
I’ll look into it in the morning when I have some focus time and report back here.
@dnolen The release action is back in working order.
Thank you!
Glad to help
Thanks Jarrod!
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.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.
Hm. But this:
cljs.user=> (= nil 0)
false
so it’s not as if nil equals zero in all cases.= is an exception. CLJS implements its own equality semantics (for data structures, etc)
So is this the answer? https://stackoverflow.com/questions/2910495/why-null-0-null-0-but-not-null-0
I am not a JavaScript expert by a longshot.
yes, with regards to <, > etc you are delivered to JS craziness
OK, thanks. It is what it is.
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}"JS is 💥.
Thanks @borkdude. I’ll add that to my bag of tricks
also == is for numbers
@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
@jeaye actually it was at one point, now just calls fix - behaviour is identical to int - the docstring are descriptive here
== is a inlining macro that becomes === operator in JS
How many = can there be?
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.
@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?
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.
Right. Understood.
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
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.
not assuming anything over here, so no worries.
ClojureScript leverages the fact that JS math is fast if the VM detects that code is implicitly operating on 32 bits.
So we don't check anything at all.
Yep, totally rational way to do it. And JavaScript is, ahem, creative on many of these issues.
the problem is that w/o checks of course you run into all the coercion crap.
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.
But really that stuff is not about proper numeric code, rather just weird stuff due to being a scripting language in the web browser.
Yep, exactly.
so not just numerics, but arrays would be weird too. places that host coercion appears
all of these cases would be ill-formed Clojure(Script) programs
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.
warning is a compile time attempt to let the user know their program is ill formed
but runtime checks are too costly
Makes sense
a related problem is JS falsey values, 0 and the blank string are false-y in JS.
so every (if x ...) needs to guard against this, it's a performance hole.
back ~2012, we started adding ^boolean hints to get rid of the checks so that PersistentVector would have acceptable perf
Yea, as I was telling @jeaye earlier, every time I interact with JavaScript, I walk away shaking my head and muttering “WTF??” 🙂
The JavaScript designers made some interesting choices, let’s just say.
As you said, it’s a scripting language in a browser.