Welcome! Please see the About page for a little more info on how this works.

+1 vote
in core.async by

I have the following piece of ClojureScript code within a go block:

(and (vector? x) (= (first x) :some-key)) ...)

This generates the following piece of JavaScript code for the cond case:

if (40 === f) {
d = b(link: 9),
f = cljs.core.vectorQMARK.call(null, d),
d = cljs.core.first.call(null, d),
d = cljs.core.EQ.call(null, d, new cljs.core.Keyword(null, "some-key", "some-key", -978969032)),
cljs.core.truth_(f && d) ? b(link: 1) = 42 : b(link: 1) = 43,
new cljs.core.Keyword(null, "recur", "recur", -437573268);

This looks to me like both and arguments would actually get evaluated. As a result my code crashes whenever it hits this cond case and 'x' is not seqable.

4 Answers

0 votes

Comment made by: favila

CLJS-864 is likely the same issue. (It also has a small test project to reproduce.)

0 votes

Comment made by: raspasov

This happened to me as well with the latest version of core.async on ClojureScript 0.2.395.

I would bump this to not minor since it severely breaks the promise that (and ...) makes.

(def cards :loading)
(go (and (vector? cards) (< 0 (count cards))))

This throws an exception like this:

No protocol method ICounted.-count defined for type cljs.core/Keyword: :loading

I was able to go around this by nesting the checks like this:
(go (if (vector? cards)

  (if (< 0 (count cards))
    (println "counting cards..."))))
0 votes

Comment made by: mfikes

If you

(macroexpand '(go (and (vector? cards) (< 0 (count cards)))))

you will see that arguments to the * special form are lifted out and {{let}}-bound, causing evaluation of code that the special form would never evaluate.

0 votes
Reference: https://clojure.atlassian.net/browse/ASYNC-91 (reported by alex+import)