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

因此当然会失去短路。


对于ioc机械中js*的一般支持,需要解析和重写JavaScript,这似乎不太可能发生。js*的具体情况可以通过匹配确切的JavaScript字符串进行处理,但这可能相当脆弱。

最好的办法可能是更改Clojurescript的or定义或者始终生成ifs(类似于Clojure的),并且将优化移到编译器中。
0

评论者:hiredman

Clojurescript中的orand在宏扩展过程中都会运行分析,这可能导致宏被多次展开

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