2015-10-26 41 views
2

我從here創建了練習2的Leiningen項目。我的代碼如下所示:爲什麼lein會跑?

(ns random-quotes.core 
    (:require [clojure.string :as str]) 
    (:gen-class)) 

(defn word-count [s] 
    (frequencies (str/split (first (str/split s #"\n")) #"\s"))) 

(def quote-url "http://www.braveclojure.com/random-quote") 

(def total-word-count (atom {})) 

(defn update-word-count [] 
    (future 
    (swap! total-word-count 
      (partial merge-with +) 
      (word-count (slurp quote-url))))) 

(defn quote-word-count [n] 
    (doseq [quote-future (doall (repeatedly n update-word-count))] 
    @quote-future) 
    @total-word-count) 

(defn -main [n] 
    (doseq [entry (sort-by val (quote-word-count (bigdec n)))] 
    (println entry))) 

所有非常簡單。當我運行時,例如(-main 5)lein repl中,它會按預期運行,打印並返回。但是,當我嘗試使用lein run 5代替它時,它將運行並打印但不會退出,因此我不得不使用Ctrl + C以使我的終端恢復正常。

任何想法爲什麼發生這種情況?

回答

3

Clojure有一個線程池,它可以繼續運行以供代理使用。由於這些線程仍然存在,JVM無法告訴您程序已完成。這只是坐在那裏等待代理退出。您可以通過(shutdown-agents)在程序結束時完成,如here所述。期貨使用代理。

clojure.core/future-call稱像這樣的代理:

(let [f (binding-conveyor-fn f) 
     fut (.submit clojure.lang.Agent/soloExecutor ^Callable f)] 

這實際上開始你的代碼運行。你不會是唯一一個發言some criticism的人,我們都希望找到更優雅的解決方案。

+2

@Elogent - 您在使用「future」時調用了座席。 – DaoWen

+0

謝謝@Elogent我會編輯將其包含在答案中。 –