Interesting problem with JS iterables and mutability, see comment in the ticket https://clojure.atlassian.net/browse/CLJS-3199 One solution would be to realize the whole iterator at seq creation time. With this we could also use IndexedSeq instead of special ES6IteratorSeq type. The downside is that behaviour wouldn't exactly match Clojure, where iterator is realized lazily in chunks.
Consuming iterables lazily could be useful.
I’m not sure that I (as a potential user of this) care about the difference between CLJS and CLJ w.r.t. mutation
FWIW array-seq
already works this way
cljs.user> (def foo #js [1 2 3])
#'cljs.user/foo
cljs.user> foo
#js [1 2 3]
cljs.user> (def foo-seq (array-seq foo))
#'cljs.user/foo-seq
cljs.user> (aset foo 0 2)
2
cljs.user> foo
#js [2 2 3]
cljs.user> foo-seq
(2 2 3)
Also in Clojure nothing stops you from mutating nested java collections in a seq, so maybe that's fine.
I've chatted about this briefly with @mfikes, still would like to get more input on this.
(defonce x js/v)
would still eval after reloads when js/v
is undefined
. This happens because exists?
checks for undefined
, but in cljs we treat both null
and undefined
as nil
. I propose to change the check to ns.hasOwnProperty(x)
specifically for defonce
, but also I'm wondering if this should go into exists?
as well?
it should be used in neither since it will very likely interfere with :advanced
remember that foo.bar/x
is flattened to var xT
(or anything like that) in :advanced
and there is no "property" to check
yeah that’s a good point
@roman01la I'm confused as to why it matters that will eval when it evals to undefined
I would say this is not a problem and to avoid the pattern that allows this to happen
i.e. just fix the code - we don't need to work around this
re: iterators, I'm not sure that we care about the JS / Java differences here
we can't do anything about mutation - I would say not a big deal - realizing the whole thing is not a good idea
I'm pretty sure you can make infinite iterables
I often bump into something like this (defonce init ((fn [] (js-undefined-returning-fn))))
, every time it takes me some time to figure out the problem. But I’m also fine to leave it as is.
btw, I checked exists?
it doesn't coerce, we use !==
against 'undefined'
so the problem is not nil
but that the fn returned undefined
and you set to that
if it returned nil
it would work exactly as expected
yes, I was talking specifically about undefined
ok sorry, wasn't sure
right I think this is just too trivial to solve in userland
a helper fn, or a macro
This also popped out in https://clojure.atlassian.net/browse/CLJS-3195, I think the patch there should still make sure that “no value” is null
, not undefined
For CLJS-3195, since null
and undefined
are both aliased to nil
, for ClojureScript code things should generally be OK. But, the risk is that someone passes such a value into JavaScript that cares.
hrm my first impression is ergh re: 3195
probably not going to consider that one too problematic
I'm not really interested in futzing around with undefined
anymore - so I would spend effort elsewhere