`
yangdong
  • 浏览: 66413 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Stream in Clojure

 
阅读更多
(define fibs
  (stream-cons 0
    (stream-cons 1
      (stream-add (stream-cdr fibs) fibs))))

The code above is an excerpt from SICP that generates an infinite Fibonacci sequence. I've tried to migrate it to Clojure.

The following code is the implementations of the stream concept mentioned in SICP and the the Fibonacci function. The essential part is this: (defmacro stream-cons [e s] ...). Because Clojure's cons requires that s to be a ISeq or Seqable, that makes the "(stream-cdr fibs)" part always fails. Because this piece of code is executed before the outer stream-cons ever happened. By the time we execute "(stream-cdr fibs)", we haven't had the value of "fibs" yet.
(defn pair [x y] (cons x [y]))
  
(defn pair-car [p] (first p))

(defn pair-cdr [p] (second p))

(defmacro stream-cons [e s]
  `(pair ~e (delay ~s)))
  
(defn stream-car [s]
  (pair-car s))
  
(defn stream-cdr [s]
  (force (pair-cdr s)))
  
(defn stream-map
  ([f s]
    (stream-cons
      (f (stream-car s))
      (stream-map f (stream-cdr s))))
  ([f s & ss]
    (let [step (fn step [ss]
                  (when (not (empty? ss))
                    (stream-cons (map stream-car ss) (step (map stream-cdr ss)))))]
      (stream-map #(apply f %) (step (cons s ss))))))
    
(defn stream-add [& ss]
  (apply stream-map + ss))
  
(defn take-stream [s count]
  (when (> count 0)
    (stream-cons
      (stream-car s)
      (take-stream (stream-cdr s) (dec count)))))
      
(defn print-stream [s]
  (let [step (fn step [s]
                (when (not (empty? s))
                  (print (stream-car s) "")
                  (recur (stream-cdr s))))]
    (step s)
    (println)))
    
(def fibs
  (stream-cons 0
    (stream-cons 1
      (stream-add (stream-cdr fibs) fibs))))
      
(def ones (stream-cons 1 ones))
(def twos (stream-add ones ones))

(print-stream (take-stream twos 10)) ; => 2 2 2 2 2 2 2 2 2 2
(print-stream (take-stream fibs 10)) ; => 0 1 1 2 3 5 8 13 21 34

Interesting enough that I haven't thought of a way to seamlessly integrate the above stream code into Clojure. If we implement it using (deftype LazyStream [] clojure.lang.Seq ...) that would make cons a function instead of a macro. Therefore I temporarily think that it's impossible to seamlessly integrate the implementation.
分享到:
评论
2 楼 yangdong 2011-01-10  
谢谢。我只是追求形似,所以找不到对应的写法。
1 楼 jamesqiu 2011-01-10  
Clojure的lazy-cat和Scala的Stream实现fib数列都很清楚明白:
--- Clojure
(defn fib [a b] (lazy-cat [a] (fib b (+ a b))))
(take 10 (fib 0 1))
--- Sclaa
def fib(a:Int,b:Int):Stream[Int] = a #:: fib(b,a+b)
fib(0,1) take 10 toList

相关推荐

    Mastering.Clojure.1785

    Learn to handle data using sequences, reducers, and transducers in Clojure Explore the lesser known and more advanced features, constructs, and methodologies of the Clojure language and its ecosystem,...

    Clojure电子书合集1(12本)

    [2011] Clojure in Action.(Amit Rathore).[1935182595].pdf [2011] The Joy of Clojure - Thinking the Clojure Way.(Michael Fogus, Chris Houser).[1935182641].pdf [2012] Clojure Programming - Practical Lisp...

    Professional.Clojure.1119267277

    Designed specifically to meet the needs of professional developers, this book briefly introduces functional programming before skipping directly to the heart of using Clojure in a real-world setting....

    clojure相关书籍1

    【1】[Clojure编程乐趣](The Joy of Clojure).pdf 【2】Clojure – Functional Programming for the JVM中文版.pdf ...【6】Clojure in Action.pdf 【7】clojure in small pieces.pdf 以上7本书的电子版

    Clojure入门教程- Clojure – Functional Programming for the JVM中文版

    - **书籍**: 有许多优秀的书籍可以帮助深入理解Clojure的语言特性和最佳实践,如《Clojure in Action》和《Programming Clojure》等。 #### 七、案例分析与实践 - **Clojure项目实战**: 通过实际项目来学习Clojure...

    Clojure编程乐趣]+clojure_programming.pdf

    Clojure是一种基于Lisp家族的函数式编程语言,它运行在Java虚拟机(JVM)上,同时也支持JavaScript和其他平台。Clojure的设计目标是提供一个高效、并发、可移植的环境,适合解决现代软件开发中的复杂问题。在这个...

    clojure电子书

    《Clojure电子书》集合包含了三本关于Clojure编程的重要书籍和一个Leiningen的Windows安装程序,这对于学习和深入理解Clojure语言至关重要。Clojure是一种基于Lisp的函数式编程语言,它运行在Java虚拟机(JVM)上,...

    Practical Clojure.pdf

    根据提供的文件内容,我们可以提取出以下关于Clojure语言的知识点: Clojure是一种编程语言,它给作者留下了深刻的印象,并且被视为一种多用途的、全面的编程语言。作者在开始学习Clojure时,体会到了编程的乐趣,...

    Clojure电子书合集2(13本)

    [2013] Functional Programming Patterns in Scala and Clojure - Write Lean Programs for the JVM.(Michael Bevilacqua-Linn).[1937785475].pdf+epub.rar [2014] Clojure Cookbook - Recipes for Functional ...

    Programming Clojure 英文电子版

    ### 编程Clojure:全面解析与学习指南 #### 一、Clojure语言概述 《Programming Clojure》是一本深入探讨Clojure编程语言的书籍,该书由Stuart Halloway编写,出版于2009年3月,由Pragmatic Bookshelf出版社发行。...

    Clojure Cookbook

    The book details a large number of recipes – pairs of problems and solutions – for common topics in Clojure. Clojure Cookbook doesn't just teach you Clojure, it also shows you how to use the ...

    Clojure High Performance Programming(PACKT,2ed,2015)

    Like most general purpose languages, various Clojure features have different performance characteristics that one should know in order to write high performance code. This book shows you how to ...

    clojure1.3.0及资料

    Clojure是一种基于Lisp的函数式编程语言,它运行在Java虚拟机(JVM)上,充分利用了Java的生态系统。Clojure的设计目标是提供一种静态类型的、并发的、内存安全的语言,同时保持Lisp的简洁性和灵活性。在这个压缩包...

Global site tag (gtag.js) - Google Analytics