我编写了一个程序,在调用时显示消息“msg0”“freq0”次和“msg1”“freq1”次,并且会定期执行此操作。
这是我的代码:
(define (make-counter n)
(lambda () (set! n (+ n 1)) n))
(define counter1 (make-counter -1))
(define (rotating-msg msg0 msg1 freq0 freq1)
(let ([period (+ freq0 freq1)]
[count (counter1)])
(cond ((< (remainder count period) freq0) msg0)
(else msg1))))
只要我按照以下方式调用它,这就像我预期的那样:
> (rotating-msg 'foo 'bar 1 2)
foo
> (rotating-msg 'foo 'bar 1 2)
bar
> (rotating-msg 'foo 'bar 1 2)
bar
> (rotating-msg 'foo 'bar 1 2)
foo
但是,以下情况不起作用:
> (define foobar (rotating-msg 'foo 'bar 1 2))
> foobar
foo
> foobar
foo
> foobar
foo
这个与前一个完全不同的是什么?
答案 0 :(得分:0)
在您的第一个示例中,您每次都会调用counter1
,这会将n加1。在第二个示例中,counter1
仅被调用一次,因此n保持在值0。
这种规范方式如下:
(define (rotating-message msg0 msg1 freq0 freq1)
(let ((n 0) (total (+ freq0 freq1)))
(lambda ()
(let ((nn (modulo n total)))
(begin0
(if (< nn freq0) msg0 msg1)
(set! n (+ n 1)))))))
(define r (rotating-message 'foo 'bar 1 2))
(for/list ((i (in-range 10))) (r))
=>'(foo bar bar foo bar bar foo bar bar foo)