请分享您的想法,参加 2024 年 Clojure 状态调查!

欢迎!有关如何工作的更多信息,请参阅 关于 页面。

0
core.async

`
(go (or true

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

`

5 个答案

0

评论者:alexmiller

那个 丢失了一个通道,所以这似乎是从一开始就是不正确的代码 - 标记无法复现直到示例修复。

0

评论者:lgs32a

嗨 Alex,向 传递的无效参数是有意的。

关键是,按照 or 的定义行为,它永远不应该被评估,因此是正确的。

您也可以将第 2 行替换为
(= (<! (do (js/console.log "这不应该发生") (chan)))
或在那里调用一个记录并返回通道的函数。

在我看来,这不会改变将此标记为 bug 的标签。

该 bug 仍然存在于 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))

因此当然会丢失短路操作。


对ioc机器中js*的一般支持将需要解析并重写javascript,这似乎不太可能发生。js*的特定情况可以通过匹配javascript的确切字符串来处理,但这可能有些脆弱。

最好的做法可能是更改clojurescript中or的声明,始终生成ifs(类似于clojure的),并将优化移至编译器中。
0

评论者:hiredman

此外,clojurescript中的orand都会作为宏扩展的一部分运行分析,这可能导致宏被重复展开

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