core.async

(CLJS) 'and' does not short circuit within go block in clojurescript

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    core.async 0.1.338.0-5c5012-alpha

Description

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

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

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

if (40 === f) { return d = b[9], f = cljs.core.vector_QMARK_.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[1] = 42 : b[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.

Activity

Hide
Francis Avila added a comment -

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

Show
Francis Avila added a comment - CLJS-864 is likely the same issue. (It also has a small test project to reproduce.)
Hide
Rangel Spasov added a comment -

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..."))))

Show
Rangel Spasov added a comment - 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..."))))
Alex Miller made changes -
Field Original Value New Value
Summary 'and' does not short circuit within go block in clojurescript (CLJS) 'and' does not short circuit within go block in clojurescript
Hide
Mike Fikes added a comment - - edited

If you

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

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

Show
Mike Fikes added a comment - - edited If you
(macroexpand '(go (and (vector? cards) (< 0 (count cards)))))
you will see that arguments to the js* special form are lifted out and let-bound, causing evaluation of code that the special form would never evaluate.

People

Vote (3)
Watch (2)

Dates

  • Created:
    Updated: