Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops clojure中的顽固循环,让我们不要进行评估_Loops_Clojure - Fatal编程技术网

Loops clojure中的顽固循环,让我们不要进行评估

Loops clojure中的顽固循环,让我们不要进行评估,loops,clojure,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

我有以下代码:

(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))
我注意到
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))
  )) 
我更希望
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)))))

我对正在发生的事情的猜测:

map
是一个惰性函数,因此当它是
do
中的最后一项时,它将被评估,因为这是
do
返回的内容。如果它不是
do
中的最后一项,那么它的返回值将不会被使用,因此不会得到评估


尝试使用
doseq
而不是
map

你已经被懒惰的错误咬到了:

  • 我注意到let评估必须是最后一次,否则它不会得到评估。
    这是因为调用map的结果是惰性的,所以只有当有东西读取结果时才会对其进行计算。如果将其放在最后,则它将成为repl打印的
    do
    的返回值,从而使其实际运行

  • 当我在循环中实现此功能时,永远不会对let求值:
    while
    将一直运行,直到表达式的返回值为false。在这种情况下,表达式的返回值是一个延迟序列,如果有人查看它,就会导致下载某些页面。在这种情况下,不会查看结果,因此不会下载任何内容,因为它不是false,所以会继续运行

  • 如何让我进行评估?:
    将对map的调用包装在
    (doall(map……)
    中,以计算惰性序列


可能的重复不是重复,它只回答了部分问题。(尽管为“clojure-lazy-bug”做一个标签很有诱惑力,但这个函数是否能像doall的速记版本一样解决这个难题,还是对所有场景来说都过于简单和短视?(defn dmap[f&[m]](doall(map f m)))是的,这就是我的想法,尽管它需要在映射之前应用一个apply,才能拥有与mapon相同的功能。第二,我想我会看看doall的源代码,然后复制它(def-dmap(comp-doall-map))