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

欢迎!请在 关于 页面了解更多有关该功能的信息。

0
core.logic

conda 和 condu 的语义为每个子句的首部赋予特殊重要性,但建立在它们之上 core.logic 中的模式匹配宏将体合并到首部。这意味着在决定选择哪一行时,会考虑体位置中的每一个表达式,而不仅仅是首部位置的表达式。这是因为整个子句被一个新表达式包裹以绑定模式中出现的隐式指定的 lvars。

为了说明

`
(matcha ['a]

[['a] u#]
[['a] s#])

;; 展开为

(conda
[(fresh [] (== 'a 'a) u#)]
[(fresh [] (== 'a 'a) s#)])

;; 与以下有不同含义

(conda
[(== 'a 'a) u#]
[(== 'a 'a) s#])

`

理想情况下,我们可以设计一个新系统来结合 conda 的语义与模式匹配。至少,我认为有问题的宏在其文档字符串中应该带有警告,指出这种语义差异。

我怀疑这也会导致“第三诫”警告应用于整个行,而不仅仅是头部/问题,但尚未调查该问题。

以下是一个演示意义差异的示例

`
;; 这不成功,因为我们承诺了第一行,
;; 因为问题成功,但是在体中失败。

(run* [q]
(conda
[(== 'a 'a) u#]
[(== 'a 'a) s#]))

;; => ()

;; 这成功,因为整个行用于确定要承诺哪一行,
;; 而不仅仅是头部的模式匹配子句。所以当第一行失败时,
;; 会尝试第二行。

(run* [q]
(matcha ['a]
[['a] u#]
[['a] s#]))

;; => (_0)
`

4 答案

0

评论者:austinhaas

仅供参考

{quote}

第三诫

在确定conda(或condu)线路的问题之前,如果一个变量是新鲜的,那么在讨论该线路的问题时它必须保持新鲜。
{quote}

摘自《The Reasoned Schemer》。

0
by

评论者:dnolen

抓得好,我需要考虑这个问题。

0
by

评论者:dnolen

问题在于我们依赖于不是非常灵活的conde宏。我们可能需要做一步,这样可以包裹每个conde行在一个创建逻辑变量的let中,然后确保所有的头统一都被包裹在一个fresh中,以保持conda/u的语义。

0
by
参考:https://clojure.atlassian.net/browse/LOGIC-129(由austinhaas报告)
...