如何使宏观卫生的一部分

发布于 2024-09-09 02:49:32 字数 1535 浏览 12 评论 0原文

我想要一个名为 lambda-rlambda 版本,您可以在其中返回。示例:

(+ ((lambda-r ()
    (return 1)
    2)) 5)

这将给出值 6。尽管您可能期望该值为 7,但实际上是 6,因为 lambda 表达式在达到 2 之前返回了 1。

这是我正在寻找的转变的一个例子。假设要使用 lambda-r 如下:

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

我希望它像这样转换:

(call/cc (lambda (k)
       (define return (lambda (v)
                        (k (lambda (a b)
                             v))))
       (lambda (a b)
         (return a)
         (+ a b))))

也可以用 let 表达式而不是内部定义来表达,但我使用的是为了清楚起见定义。

请注意,上面的代码实际上确实按预期工作。 问题是我无法将lambda-r表达为。原因是我希望 kv 卫生,但我不希望 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)) 给出一个错误,指出 return 不是有效的标识符。


编辑:感谢内森·桑德斯的回答,我更接近理解我在这里必须做什么。但是我不完全理解以下过程,因此还无法使其正常工作。如果您能解释/引导我找到解释以下内容的资源,我将非常感激:

  • syntax 过程
  • datum->syntax/syntax->; datum 程序

编辑:没关系 - 我现在已经得到了:)

I'd like to have a version of lambda, called lambda-r, from within which you can return. An example:

(+ ((lambda-r ()
    (return 1)
    2)) 5)

This would give the value 6. Although you might expect the value to be 7, it's 6 because 1 is returned from the lambda-expression before 2 is reached.

Here's an example of the kind of transformation I'm looking for. Let's say one were to use lambda-r as follows:

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

I want it to be transformed like this:

(call/cc (lambda (k)
       (define return (lambda (v)
                        (k (lambda (a b)
                             v))))
       (lambda (a b)
         (return a)
         (+ a b))))

That could also be expressed with a let-expression instead of an internal define, but I'm using the define for clarity's sake.

Note that the above code does actually work as expected. The problem is that I'm having trouble expressing lambda-r as a macro. The reason is that I want k and v to be hygienic, but I don't want return to be hygienic.

My macro at the moment is this:

(define-syntax lambda-r
  (syntax-rules (return)
    [(_ (var ...) body ...)
     (call/cc (lambda (k)
           (define return (lambda (v)
                            (k (lambda (var ...)
                                 v))))
           (lambda (var ...)
             body ...)))
     ]))

Which doesn't work because return is treated hygienically, and as a result isn't directly visible when using lambda-r. So (lambda-r () (return 1)) gives an error which says that return isn't a valid identifier.


Edit: Thanks to Nathan Sanders' answer, I'm closer to understanding what I have to do here. However I don't fully understand the following procedures, and as a result haven't been able to get this working yet. I'd really appreciate if you could explain/direct me to resources which explain the following:

  • the syntax procedure
  • the datum->syntax/syntax->datum procedures

Edit: Nevermind - I've got it now :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陈甜 2024-09-16 02:49:32

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

R6RS 定义给出了一些示例,特别是语法部分-对象和数据转换,这就是你想要的。您应该能够将带有 breakloop 示例调整为您的 return

What you want is syntax-case instead of syntax-rules.

The R6RS definition gives some examples, notably a section on syntax-object and datum conversions, which is what you want. You should be able to adapt the loop w/ break example to your return.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文