Raj*_*hat 3 macros scheme racket
我正在尝试在DrRacket中为while循环创建一个宏.这是我写的:
(require mzlib/defmacro)
(define-macro my-while
(lambda (condition body)
(list 'local (list (list 'define (list 'while-loop)
(list 'if condition
(list body (list 'while-loop))
'(void))))
'(while-loop))))
(define x 0)
(my-while (< x 10)
(begin
(display x)
(newline)
(set! x (+ x 1))))
Run Code Online (Sandbox Code Playgroud)
该程序的输出是:
0
1
2
3
4
5
6
7
8
9
error: procedure application: expected procedure, given: #<void>; arguments were: #<void>
Run Code Online (Sandbox Code Playgroud)
有人可以帮我弄这个吗?为什么这个宏不会终止并返回void.似乎当条件不为真时,系统会尝试将void作为参数应用于某个过程.
哎哟:
while
循环方式会鼓励过度使用命令式编程.define-macro
创建不卫生的宏,这是Scheme中的噩梦.虽然我不鼓励编写命令式循环宏,供您参考,但这define-macro
是同一个宏的非版本:
(define-syntax-rule (my-while condition body ...)
(let loop ()
(when condition
body ...
(loop))))
Run Code Online (Sandbox Code Playgroud)
它使用syntax-rules
,创建卫生的宏,并且比你拥有的更容易阅读.
现在,对于您的问题的实际答案,首先,让我们以更易读的方式编写您的原始宏:
(define-macro my-while
(lambda (condition body)
`(local ((define (while-loop)
(if ,condition
(,body (while-loop))
(void))))
(while-loop))))
Run Code Online (Sandbox Code Playgroud)
一旦你用这种方式写出来,你就可以看出真正的问题所在:(,body (while-loop))
在行中,应该是这样的(begin ,body (while-loop))
.