在Clojure中重复调用时出错

时间:2015-10-28 16:28:58

标签: clojure

我正在尝试从输入中读取数字并将它们打印回Clojure,直到我读到数字42.这是确保我知道如何读取输入的一个非常基本的事情。取自codechef

我写过这个程序。可能不是好的clojure。

(defn universe
  []
  (let [num (line-seq (java.io.BufferedReader. *in*))]
    (if (not= num 42)
      (do
        (println num)
        (recur (universe))
        )
      )
    )
  )

我的理解是,line-seq懒惰地从任何读者的评价中评价。在这种情况下标准输入。

所以我让它成为了数字。然后,如果num不是42,我打印它,然后递归调用universe。但它抛出异常

Mismatched argument count to recur, expected: 0 args, got: 1,

我见过example并且recur确实接受了争论。看official documentation我看不到这个的语法。那我为什么会收到这个错误?

1 个答案:

答案 0 :(得分:4)

recur不会重复使用该位置的名称。相反,重复特殊形式会跳回到最接近的函数或loop表达式,以较近者为准。然后它传递不同的参数。这使您可以在处理数据时重复执行相同的代码块,并且没有函数调用开销。

在你的情况下,它会重复到函数调用:

(defn universe [] ...

并尝试传递一个参数,该参数失败,因为Universe函数不接受任何参数。也许你打算在if?

周围放一个loop表达式
user> (defn universe
        []
        (let [numbers (line-seq (java.io.BufferedReader. *in*))]
          (loop [numbers numbers]
            (let [num (first numbers)]
              (if (not= (Integer/parseInt num) 42)
                (do
                  (println num)
                  (recur (rest numbers))))))))
#'user/universe
user> (universe)
3   ;; typed 3 
nil ;; typed 42

或您打算重新回到函数顶部的位置,在这种情况下只需调用(recur)而不是(recur universe)