Scheme 功能直到->;(球拍)

Scheme 功能直到->;(球拍),scheme,lisp,racket,Scheme,Lisp,Racket,给一个特殊的表格直到 (until exp1 ... expn test) exp1,依次计算expn,然后计算test。如果为false,将再次计算值exp1、…、expn等。如果test的值为true,则计算以未定义的值#void结束。您需要编写一个函数,直到->转换,它将一个特殊的表单转换为表单的表达式 (let () (define (loop) exp1 ... expn (if test (void) (loop))) (loop)) 我不太明白怎么做。我定义了一个名为until

给一个特殊的表格直到

(until
exp1
...
expn
test)
exp1,依次计算expn,然后计算test。如果为false,将再次计算值exp1、…、expn等。如果test的值为true,则计算以未定义的值#void结束。您需要编写一个函数,直到->转换,它将一个特殊的表单转换为表单的表达式

(let ()
(define (loop)
exp1
...
expn
(if test (void) (loop)))
(loop))
我不太明白怎么做。我定义了一个名为until->transformed的函数和参数exp1..expn,但是如何编写函数体来获得上面的表达式呢?帮我弄清楚

(define (until->transformed exp1 ... expn)
( //function body )
)

为了防止您将此作为答案直接提交:

  • 故意不转换成你需要生产的东西,而是转换成不同的和更安全的东西
  • 使用一些你可能不想使用的球拍
但我认为它应该给你一个想法。这也应该有助于解释为什么在没有hygenic宏的lisp中编写安全宏是一件痛苦的事情

(define (until-transformed form)
  (match form
    [(list 'until exps ... test)
     (let ([loopn (string->uninterned-symbol "loop")])
       `(let ,loopn ()
          ,@exps
          (if ,test (void) (,loopn))))]
    [x
     (error 'until-transformed "~A is bogus" x)]))
现在

但是


它们可能意味着它被称为
(until->transformed'(until A B C…N test))
,使用一个符号表达式,我们可以使用引用列表作为参数来模拟它。@WillNess,问题的解决方案将是
(define(until->transformed'(until exp1…expn test))(let()(define(loop)exp1…expn(if test)(void)(循环)))(循环))
试着写下来并运行它,例如在定义它之后试着像
(直到->转换](直到(换行)(set!a(+a 1))(>a 10))那样调用它。
> (until-transformed '(until (print 1) (print 2) (x? p)))
'(let loop () (print 1) (print 2) (if (x? p) (void) (loop)))
> (until-transformed '(until a))
'(let loop () (if a (void) (loop)))
> (eqv? (second (until-transformed '(until a))) 'loop)
#f