我正在尝试编写一个简单的筛子函数来计算clojure中的素数.我已经看到了这个关于编写高效的筛分功能的问题,但我不是为了那点呢.现在我只想写一个非常简单(缓慢)的筛子.以下是我的想法:
(defn sieve [potentials primes]
  (if-let [p (first potentials)]
    (recur (filter #(not= (mod % p) 0) potentials) (conj primes p))
    primes))
对于小范围,它工作正常,但导致堆栈溢出大范围:
user=> (sieve (range 2 30) [])
[2 3 5 7 11 13 17 19 23 29]
user=> (sieve (range 2 15000) [])
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
我认为通过使用recur这将是一个非堆栈消耗循环结构?我错过了什么?
在Clojure [1]中编写惯用的函数代码,如何编写一个用空格分割字符串但保持引用短语完整的函数?快速解决方案当然是使用正则表达式,但如果没有它们,这应该是可能的.快速浏览一下似乎很难!我在命令式语言中写了类似的东西,但我想看看功能性的递归方法是如何工作的.
快速检查我们的功能应该做什么:
"Hello there!"  -> ["Hello", "there!"]
"'A quoted phrase'" -> ["A quoted phrase"]
"'a' 'b' c d" -> ["a", "b", "c", "d"]
"'a b' 'c d'" -> ["a b", "c d"]
"Mid'dle 'quotes do not concern me'" -> ["Mid'dle", "quotes do not concern me"]
我不介意引号之间的间距是否变化(因此可以先使用空格分割简单).
"'lots    of   spacing' there" -> ["lots of spacing", "there"] ;is ok to me
[1]这个问题可以在一般水平上回答,但我想Clojure中的一种功能方法可以轻松地转换为Haskell,ML等.
根据Mark的精彩教程页面,"map函数应用一个给定函数,该函数将一个参数带到集合中的每个项目,返回结果的惰性序列".
然而,当我做以下事情时:
(def input-message-list (range 100 126))
(defn test-123 [in]
  (println "doing " in)
  (str "out " in))
(def output-test (map
                   test-123
                   input-message-list))
(first output-test)
,在REPL中我得到了全范围的println副作用,而不仅仅是第一个元素!
这里的人怎么了?
假设我有一个巨大的 lazy seq,我想迭代它,所以我可以处理迭代过程中得到的数据.
问题是我想失去头(GC'd)的lazy seq(即处理),这样我就可以有seqs工作的数以百万计的数据,而不必OutofMemoryException.
我有3个例子,我不确定.
你能为此目的提供最佳实践(例子)吗?
这些功能失去了作用吗?
例1
(defn lose-head-fn
  [lazy-seq-coll]
  (when (seq (take 1 lazy-seq-coll))
    (do
      ;;do some processing...(take 10000 lazy-seq-coll)
      (recur (drop 10000 lazy-seq-coll)))))
例2
(defn lose-head-fn
  [lazy-seq-coll]
  (loop [i lazy-seq-coll]
    (when (seq (take 1 i))
      (do
        ;;do some processing...(take 10000 i)
        (recur (drop 10000 i))))))
例3
(doseq [i lazy-seq-coll]
  ;;do some processing...
  )
更新:这里的答案也有解释