在clojure中顽固循环,不要得到评估

sca*_*ape 2 loops clojure

我有以下代码:

(do
  (prn "sleeping for 60 seconds")
  (Thread/sleep 6000)
  (prn "kicking off calendar downloads @ " (new java.util.Date))
  (let [links (map #(clojure.string/split % #",") (clojure.string/split (clojure.string/replace (slurp "calendars.csv") #"\r" "") #"\n"))]
   (map download links))
Run Code Online (Sandbox Code Playgroud)

我注意到let评估必须是最后的,否则它不会被评估.这对我来说很困惑.尽管如此,当我在循环中实现它时,let永远不会进行评估,因为我认为recur最终会被推断出来.

(while
(do
  (prn "sleeping for 60 seconds")
  (Thread/sleep 60000)
  (prn "kicking off calendar downloads @ " (new java.util.Date))
  (let [links (map #(clojure.string/split % #",") (clojure.string/split (clojure.string/replace (slurp "calendars.csv") #"\r" "") #"\n"))]
   (map download links))
  )) 
Run Code Online (Sandbox Code Playgroud)

我也希望sleep在本do节末尾,但这真的没有实际意义.

我怎样才能let评估?这与我的使用有关map吗?我在这里误解了什么?

下载是一个功能:

(defn download [[calname ics]]
  (prn "attempting cal download: " calname)
  (try (spit (str dest calname ".csv") (slurp ics))
  (catch Exception e (str "caught exception: " (.getMessage e)))))
Run Code Online (Sandbox Code Playgroud)

Art*_*ldt 6

你被这个懒惰的小虫咬了一口:

  • 我注意到评估必须是最后的,否则它不会被评估.
    这是因为调用map的结果是惰性的,所以只有在读取结果时才会计算它.如果你把它放在最后,那么它将成为由repl打印的返回值,do导致它实际运行.

  • 当我在循环中实现它时,let永远不会被评估:
    while将继续运行,直到表达式的返回值为false.在这种情况下,表达式的返回值是一个惰性序列,如果有人查看它,将导致某些页面被下载.在这种情况下,没有任何东西看到结果,所以没有任何东西被下载,并且因为它不是假的它只是继续运行.

  • 我怎样才能让我们评估?:
    将调用包装到map中(doall (map ... ....))以导致计算延迟序列.