请分享您的想法,参加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的做的那样),有时展开成`(js* "(~{}) || (~{})" a b)`的形式。ioc机制没有为`js*`提供特殊处理,所以它像ANF般进行正常的转换。


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


转换为:


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

因此当然失去了短路。


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

最好的做法可能是将clojurescript中对or的定义改为始终输出ifs(就像clojure的),并将优化移到编译器中。
0

评论人:hiredman

此外,在clojurescript中,`or`和`and`都将在宏展开时运行分析,这可能导致宏被多次展开

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