2024 年 Clojure 状态调查中分享您的想法!

欢迎!请参阅 关于 页面以了解如何使用此功能的更多信息。

0
core.async

`
(go (or true

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

`

5 个答案

0

评论者:alexmiller

That <!缺少一个通道,所以这似乎是开始时的破坏性代码 - 标记为不可重复,直到示例被修复。

0

评论者:lgs32a

Hi Alex,传递给<!的不合法参数是有意的。

重点是,根据定义的行为,应该不会评估它,因此它是正确的。

您也可以用以下替换第2行:
(= (<! (do (js/console.log "this should not happen") (chan)))
或在该处调用一个同时记录并返回通道的函数。

在我看来,这不应该影响将其标记为错误。

在 0.2.395 中仍然存在此错误。

0
_评论者:hiredman_

由于某种奇怪的原因(可能是某种优化的原因?),在某些情况下,cljs 中的 or 宏扩展为 if 调用(像 clojure 中的 does 一样),有时扩展到 `(js* "(~{}) || (~{})" a b)`。ioc 机器没有特别处理`js*`,所以它执行其正常的 ANF 转换


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


转换为


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

因此当然失去了短路。


对js*在ioc机器中的通用支持将需要解析和重写JavaScript,这似乎不太可能发生。js*的具体情况可以通过匹配JavaScript的确切字符串来处理,但这可能会比较脆弱。

最好的方法是改变ClojureScript中或的定义,使其总是发出If(像Clojure),并将优化移入编译器。
0

评论者:hiredman

在ClojureScript中,或和and都运行分析作为宏展开的一部分,这可能导致宏被多次展开

0
参考: https://clojure.atlassian.net/browse/ASYNC-128(由lgs32a报告)
...