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

欢迎!请参阅关于页面以了解有关此功能的更多详细信息。

0
core.logic

这可能与core.logic打印向量结构的方式有关

以下是最小化问题复现案例

(ns testclj.logic
(:require (link: clojure.core.logic :as l)))

(def data (link: [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[:a)]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]])

(time (l/run* (link: q) (l/== q data)))

2 个答案

0

评论者:troydm

我认为问题与以下代码片段有关

`
(defn walk* [s v]
(let [v (walk s v)]

(walk-term v
  (fn [x]
    (let [x (walk s x)]
     (if (tree-term? x)
       (walk* s x)
       x))))))

`

另一方面这将调用

`
clojure.lang.IPersistentVector
(walk-term [v f]

(with-meta
  (loop [v v r (transient [])]
    (if (seq v)
      (recur (next v) (conj! r (walk-term (f (first v)) f)))
      (persistent! r)))
  (meta v)))

`

这会递归地对向量的所有元素调用walk-term。
随后会对向量中的每个元素递归调用walk-term,进而会调用walk*,它将访问之前已访问过的向量的元素,这反过来又会再次在向量元素上调用walk-term,直到完全访问整个结构。
这最终会导致多次访问子节点

问题在于walk函数的部分,它递归调用walk,这些向量元素之前已经由walk-term的调用本身走过

我想这部分的设计存在巨大的问题,我不是很确定该提出什么建议,但我认为我们需要将walk-term和walk*合并为一个函数,以一次遍历整个数据结构。你有什么建议吗?

`
(if (tree-term? x)

       (walk* s x)
       x)

`

我认为这部分的设计存在巨大的问题,我不确定该提出什么建议,但我认为我们需要将walk-term和walk*合并为一个函数,以一次遍历整个数据结构。你有什么建议吗?

可能的解决方案是以下代码,但我不确定这是否是正确的解决方案

`
(defn walk* [s v]
(let [v (walk s v)]

(walk-term v
    #(walk s %))))

`

0
参考: https://clojure.atlassian.net/browse/LOGIC-177 (由 alex+import 报告)
...