dragon4587 2016-02-20 22:56
浏览 72
已采纳

为什么Clojure的异步库无法处理Go主筛?

To try out the async library in Clojure, I translated the prime sieve example from Go. Running in the REPL, it successfully printed out the prime numbers up to 227 and then stopped. I hit Ctrl-C and tried running it again but it wouldn't print out any more numbers. Is there a way to get Clojure to handle this, or is the async library just not ready for it yet?

;; A concurrent prime sieve translated from
;; https://golang.org/doc/play/sieve.go

(require '[clojure.core.async :as async :refer [<!! >!! chan go]])

(defn generate
  [ch]
  "Sends the sequence 2, 3, 4, ... to channel 'ch'."
  (doseq [i (drop 2 (range))]
    (>!! ch i)))

(defn filter-multiples
  [in-chan out-chan prime]
  "Copies the values from 'in-chan' to 'out-chan', removing
  multiples of 'prime'."
  (while true
    ;; Receive value from 'in-chan'.
    (let [i (<!! in-chan)]
      (if (not= 0 (mod i prime))
        ;; Send 'i' to 'out-chan'.
        (>!! out-chan i)))))

(defn main
  []
  "The prime sieve: Daisy-chain filter-multiples processes."
  (let [ch (chan)]
    (go (generate ch))
    (loop [ch ch]
      (let [prime (<!! ch)]
        (println prime)
        (let [ch1 (chan)]
          (go (filter-multiples ch ch1 prime))
          (recur ch1))))))
  • 写回答

1条回答 默认 最新

  • dqtu14636 2016-02-21 10:21
    关注

    go is a macro. If you want to take advantage of goroutine-like behaviour in go blocks you must use <! and >!, and they must be visible to the go macro (that is you mustn't extract these operations into separate functions).

    This literal translation of the program at https://golang.org/doc/play/sieve.go seems to work fine, also with a larger i in the main loop:

    (require '[clojure.core.async :refer [<! <!! >! chan go]])
    
    (defn go-generate [ch]
      (go (doseq [i (iterate inc 2)]
            (>! ch i))))
    
    (defn go-filter [in out prime]
      (go (while true
            (let [i (<! in)]
              (if-not (zero? (rem i prime))
                (>! out i))))))
    
    (defn main []
      (let [ch (chan)]
        (go-generate ch)
        (loop [i 10 ch ch]
          (if (pos? i)
            (let [prime (<!! ch)]
              (println prime)
              (let [ch1 (chan)]
                (go-filter ch ch1 prime)
                (recur (dec i) ch1)))))))
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 QT6颜色选择对话框显示不完整
  • ¥20 能提供一下思路或者代码吗
  • ¥15 用twincat控制!
  • ¥15 请问一下这个运行结果是怎么来的
  • ¥15 单通道放大电路的工作原理
  • ¥30 YOLO检测微调结果p为1
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下