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

0 votes
in core.async by

`
(go (or true

    (= (<! (do (js/console.log "this should not happen") (chan)))
       :doesnt-matter)))

`

5 Answers

0 votes
by

Comment made by: alexmiller

That <! is missing a channel so this seems to be broken code to start with - marking not reproducible till example fixed.

0 votes
by

Comment made by: lgs32a

Hi Alex, the invalid arg to <! was intended.

The point is that it should never be evaluated according to defined behavior of or and thus is correct.

You can also substitute line 2 with
(= (<! (do (js/console.log "this should not happen") (chan)))
or invoke a function there that logs and returns a channel.

IMO that should not make a difference to label this a bug.

The bug still exists in 0.2.395

0 votes
by
_Comment made by: hiredman_

For some weird reason (maybe as an optimization of some sort?), the or macro in cljs some times expands as calls to if (like clojure's does) and some times expands to `(js* "(~{}) || (~{})" a b)`. the ioc machinery has no special handling for `js*` so it does its normal ANF like transform:


(js* "(~{}) || (~{})" A B)


to


(let [x A
      y B]
  (js* "(~{}) || (~{})" x y))

so of course you lose short circuiting.


General support in the ioc machinery for js* would require parsing the rewriting the javascript, which seems unlikely to happen. Specific cases of js* could be handled by matching the exact string of javascript, but that may be kind of brittle.

The best thing to do is likely to change the clojurescript definition of or to always emit ifs (like clojure's) and move an optimizations in to the compiler.
0 votes
by

Comment made by: hiredman

also or and and in clojurescript both run analysis as part of the macro expansion, which can lead to macros be expanded multiple times

0 votes
by
Reference: https://clojure.atlassian.net/browse/ASYNC-128 (reported by lgs32a)
...