如何使宏观卫生的一部分

时间:2010-07-10 20:02:13

标签: lambda scheme callcc r6rs hygiene

我想要一个名为lambda的{​​{1}}版本,您可以在其中lambda-r。一个例子:

return

这将给出值(+ ((lambda-r () (return 1) 2)) 5) 。虽然您可能期望该值为7,但它是6,因为在达到2之前从lambda表达式返回1。

以下是我正在寻找的那种转型的例子。假设有人使用6如下:

lambda-r

我想让它像这样转变:

(lambda-r (a b)
    (return a)
    (+ a b))

也可以用let-expression而不是内部定义表示,但为了清晰起见我使用了define。

请注意,上面的代码确实按预期工作。 问题是因为我无法将(call/cc (lambda (k) (define return (lambda (v) (k (lambda (a b) v)))) (lambda (a b) (return a) (+ a b)))) 表示为。原因是我希望lambda-rk保持卫生,但我不希望v保持卫生。

目前我的宏是这样的:

return

哪个不起作用,因为(define-syntax lambda-r (syntax-rules (return) [(_ (var ...) body ...) (call/cc (lambda (k) (define return (lambda (v) (k (lambda (var ...) v)))) (lambda (var ...) body ...))) ])) 被卫生处理,因此在使用return时无法直接看到。因此lambda-r会出现错误,指出(lambda-r () (return 1))不是有效的标识符。


编辑:感谢Nathan Sanders的回答,我更接近理解我在这里要做的事情。但是我不完全理解以下程序,因此还没有能够使这个工作。如果您能解释/指导我解释以下内容的资源,我真的很感激:

  • return程序
  • syntax / datum->syntax程序

编辑:没关系 - 我现在已经知道了:)

1 个答案:

答案 0 :(得分:2)

您想要的是syntax-case而不是syntax-rules

The R6RS definition提供了一些示例,特别是a section on syntax-object and datum conversions,这就是您想要的。您应该能够将loop w / break示例调整为return