在Scheme中实现While
June 26, 2020
在ChezScheme中没有关于循环的语法。
最近在看数据结构和算法的东西,使用scheme来实现。打算使用单元测试+docker的方式进行,却发现无法使用死循环来维持容器生存。
没有的话,实现一个就好了,lisp的自由度很高,一个while自然不在话下。
定义语法
我们使用的是define-syntax
关键字,来源于R6RS标准。本质上是创建一个宏(Macro),只不过lisp的宏比C系语言更强大一些。
(define-syntax <keyword> <expression>)
这里需要注意下和define
的区别。两者都可以创建一个函数,但是define
使用的参数是形参,而define-syntax
可以对参数进行修改影响到外部,这也是实现循环的一个必要条件。
(library (libs customsyntax)
(export while)
(import (chezscheme))
(define-syntax while
(syntax-rules ()
((_ pred proc1 ...)
(let loop () (when pred proc1 ... (loop))))))
)
while的内部的实现其实就是递归的自我调用,结合when对条件进行判断来决定什么时候结束递归。
下面是使用示范:
(import (chezscheme)
(libs customsyntax))
(let ((i 0)
(a-second (make-time 'time-duration 0 1)))
(while (> 5 i)
(display (current-time 'time-utc))
(newline)
(sleep a-second)
(set! i (+ i 1)))
)
每隔一秒输出一次utc时间,循环5次