代码之家  ›  专栏  ›  技术社区  ›  codeasone

为什么在mapcat中不会再次发生这种情况?

  •  1
  • codeasone  · 技术社区  · 7 年前

    recur 在内部 mapcat 终止,而 fn 呼叫版本等效吗?

    (def tree [1 [2 [3 5]] [6 [[1 2] [8 [9 10]]]]])
    
    (defn leaves
      [node]
      (mapcat #(if (vector? %) (leaves %) [%]) node))
    
    (leaves tree)
    ;; => (1 2 3 5 6 1 2 8 9 10)
    
    (defn leaves-with-recur
      [node]
      (mapcat #(if (vector? %) (recur %) [%]) node))
    
    (leaves-with-recur tree)
    ;; Never terminates
    

    如果使用 重现 是一个直截了当的不不,有没有什么理由让Clojure编译器不捕捉这个场景并警告程序员,甚至拒绝编译它?对于非尾部位置调用 重现 例如。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Svante    7 年前
    #(if (vector? %) (recur %) [%])
    

    (fn [%]
      (if (vector? %)
        (recur %)
        [%]))
    

    recur 将递归到此匿名函数,而不是任何外部函数,并且由于它不会更改任何内容,因此这是一个无休止的循环。

    至于警告,停车问题是众所周知的无法解决的,而且有可能陷入无休止的循环 编译时间

    推荐文章