[Scheme]如何用stream实现一个无限数列?我这里内存快暴了

我先放我的stream实现

(define (stream-car stream)
  (car stream))
(define (stream-cdr stream)
  (force (cdr stream)))
(define (cons-stream a b)
  (cons a (delay b)))

(define (list->stream lst)
  (if (null? lst) '()
      (cons-stream (car lst)
		   (list->stream (cdr lst)))))

(define (stream-foreach pred stream)
  (if (null? stream)
      'done
      (begin
	(pred (stream-car stream))
	(stream-foreach pred (stream-cdr stream)))))

(define (stream-display stream)
  (stream-foreach (lambda (x)
		    (display x)
		    (newline)) stream))



然后我想看看scheme能不能实现clojure中的take,rangeiterate,于是

(define (stream-take n stream)
  (if (or (= 0 n)
	  (null? stream))
      '()
      (cons-stream (stream-car stream)
		   (stream-take (1- n) (stream-cdr stream)))))

(define (stream-range start end)
  (if (> start end)
      '()
      (cons-stream start
		   (stream-range (1+ start) end))))

(define (stream-iterate pred init)
  (cons-stream init
	       (stream-iterate pred (pred init))))

测试range

(stream-display (stream-range 1 10))
1
2
3
4
5
6
7
8
9
10
done

测试take

(stream-display (stream-take 10 (stream-range 1 10)))
1
2
3
4
5
6
7
8
9
10
done

测试iterate 这里出错了

> (stream-display (stream-take 10 (stream-iterate 1+ 1)))

break> s
(time (stream-display (stream-take 10 ...)))
    110 collections
    1.126950969s elapsed cpu time, including 1.000801726s collecting
    1.126519705s elapsed real time, including 1.000760044s collecting
    922329216 bytes allocated, including 8679712 bytes reclaimed

请各位教教我 :joy:

(define (cons-stream a b)
  (cons a (delay b)))

cons-stream 被定义成了procedure,而非syntax. procedure调用的时候参数就已经eval. 失去了stream的laziness, 无限流就会卡死循环

用syntax之后, 调用syntax不会对参数a和b求值, 才能写出正常的stream

(define-syntax-rule (stream-cons a b)
  (cons a (delay b)))

多谢指点,不过这是怎么回事

(define-syntax-rule (cons-stream a b)
  (cons a (delay b)))


Exception: variable a is not bound
Type (debug) to enter the debugger.

我用的是chezscheme,好像没有define-syntax-rule这个宏

(define-syntax define-syntax-rule
  (syntax-rules ()
    ((_ (name pat ...) body ...)
     (define-syntax name
       (syntax-rules ()
         ((_ pat ...)
          body ...))))))

define-syntax-rule就是syntax-rules只有一个匹配分支而且没有literal时的简写.Guile和Racket都有.

感谢大佬,我好了 :grin: