Clojure - recur适用于循环或let语句?

时间:2017-01-19 18:37:09

标签: loops recursion clojure let

我在Clojure中有一个关于复发的问题。如果我在循环中有一个let语句,那么recur调用是否可以应用于let语句而不是循环的值? 例如,在这种情况下:

(defn someFunction [listA listB]
  ("do something here...." 
      [new-listA new-listB]))

(defn anotherFunction [listA listB]
  ("do something here...." 
      [new-listA new-listB]))

(defn myFunction [firstList secondList]
  (loop [list1 (someMutation firstList)
         list2 (someMutation secondList)]
    (if (= "true" (someCondition))
      (let [[newlist1 newlist2]
           (someFunction list1 list2)] 
        (recur newlist1 newlist2))
      (anotherFunction list1 list2) )))
应用于循环或let的

是(recur newlist1 newlist2)吗? 有没有一种方法可以跳过这个let语句并直接使用“someFunction”返回的两个值调用recur,假设我无法改变“someFunction”返回带有两个参数的向量的事实?

2 个答案:

答案 0 :(得分:6)

$UserCal`:\calendar 始终会重复到最接近recur形式的loop或函数。它通过编译本质上是一个循环/跳转语句来改变循环变量的值,然后跳回到循环/ fn点。这样它只使用一个堆栈帧并可以全速运行。这种设计有一些有意的权衡:

  • 你不能交错嵌套循环
  • recur只能是表达式中的最后一件事。
  • 必须有相同数量的args才能重复出现loop / the-function

最后一个要求你保留let表达式或类似的东西,例如解构形式。循环确实允许像函数一样对参数进行解构:

recur

因此,您可以编写循环表达式以直接获取 (loop [[a b] [1 2]] (println a b) (if (< a 10) (recur [(inc a) (inc b)]))) 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 的结果

someFunction

答案 1 :(得分:1)

let不是有效的重复目标。

你或许可以在let中设置构造向量的结构,因此也可以跳过let。

另外,等于true有点奇怪。这是你的控制吗?如果是这样,应该只查找布尔值true然后可以说(if (somecondition)...