This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-12-20
Channels
- # adventofcode (29)
- # announcements (7)
- # aws (1)
- # babashka (3)
- # beginners (43)
- # biff (20)
- # clj-kondo (44)
- # cljs-dev (20)
- # clojure (74)
- # clojure-europe (24)
- # clojure-finland (2)
- # clojure-nl (13)
- # clojure-norway (3)
- # clojurescript (31)
- # code-reviews (1)
- # community-development (12)
- # cursive (3)
- # datomic (6)
- # emacs (1)
- # fulcro (25)
- # interop (7)
- # introduce-yourself (2)
- # leiningen (30)
- # nbb (3)
- # overtone (1)
- # podcasts-discuss (5)
- # polylith (24)
- # practicalli (1)
- # reclojure (1)
- # reitit (13)
- # rum (7)
- # shadow-cljs (12)
- # sql (23)
- # squint (51)
- # test-check (1)
- # testing (2)
- # tools-deps (2)
hey all, I am hitting a bug in cljs that I can recreate with shadow, but that I’m not sure how to recreate without shadow in the loop. The error is this:
Uncaught TypeError: Cannot create property 'closure_uid_21581550' on bigint '-12'
at goog.getUid (cljs_env.js:392:127)
at core.cljs:1436:6
at cljs$core$IHash$_hash$dyn_28715 (core.cljs:724:1)
at Object.cljs$core$_hash [as _hash] (core.cljs:724:1)
at Object.cljs$core$hash [as hash] (core.cljs:1036:15)
at Object.cljs$core$hash_ordered_coll [as hash_ordered_coll] (core.cljs:1360:54)
at Object.cljs$core$IHash$_hash$arity$1 (core.cljs:3133:36)
at Object.cljs$core$hash [as hash] (core.cljs:1008:21)
at Object.cljs$core$hash_ordered_coll [as hash_ordered_coll] (core.cljs:1360:54)
at Object.cljs$core$IHash$_hash$arity$1 (core.cljs:3133:36)
I’ve whittled down my reproduction to this:
(let [f (memoize identity)]
(f (list 'a (list 'b (js/BigInt -12) 'c (list 'd)) 'e))
(f 'a)
(f (list 'b (js/BigInt -12) 'c (list 'd)) 'e)
(f 'b)
(f (js/BigInt -12))
(f 'c)
(f (list 'd))
(f 'd)
(f 'e))
I haven’t found a different form that does this, but obviously there is something important about the fact that if I pass
• this nested form with a bigint
inside
• pass each sequence’s node in depth-first order to the memoized function
then on the final entry, this error is throwncc @U05224H0W , here is a repro with shadow: https://github.com/sritchie/shadow-repro I can’t get this to trigger in a bare cljs browser repl with the same cljs version, so maybe it is something about the esm module settings:
{:deps true
:dev-http {9000 "public"}
:builds
{:repro
{:target :esm
:runtime :browser
:output-dir "public/js"
:modules {:main
{:entries [repro]}}
:js-options
{:output-feature-set :es8}}}}
AHHH wait I have a better repro and a bigger clue 🙂 this happens.
If you call the memoized function with more than 8 distinct values, if 1 of the values is a BigInt
, you get the failure.
(let [f (memoize identity)]
(doseq [i (range 8)]
(f i))
(f (js/BigInt 1)))
While playing around with it, found a not-so-great behavior:
cljs.user=> (def i (js/BigInt -12))
#'cljs.user/i
cljs.user=> (hash i)
2
cljs.user=> (hash i)
3
cljs.user=> (hash i)
4
@U2FRKM4TW actually bigint is a red herring too
no, wait, it’s not, sorry. I thought it was because (-hash 10)
fails with the same error
but yeah that is not good @U2FRKM4TW
(defn hash
"Returns the hash code of its argument. Note this is the hash code
consistent with =."
[o]
(cond
(implements? IHash o)
(bit-xor (-hash o) 0)
(number? o)
(if ^boolean (js/isFinite o)
(js-mod (Math/floor o) 2147483647)
(case o
##Inf
2146435072
##-Inf
-1048576
2146959360))
numbers get a pass here
@U2FRKM4TW so in my setup, hash
with a bigint totally fails. what version are you using?
https://ask.clojure.org/index.php/10938/can-js-bigint-be-used-as-a-map-key-in-clojurescript
Feels like failing on hashing BigInt would actually be better than always returning a different hash.
(extend-type js/BigInt
IHash
(-hash
[this] (hash (.toString this 16)))
IEquiv
(-equiv [this o]
(let [other (.valueOf o)]
(if (= "bigint" (goog/typeOf other))
(coercive-= this other)
(= this other)))))
I guess this is the key
not quite right…
I'd say this is a crutch. :) The key would be somehow solving it at the GCC/CLJS level.
agree