gpt4 book ai didi

macros - 在 Racket 宏中使用新关键字

转载 作者:行者123 更新时间:2023-12-02 08:31:56 25 4
gpt4 key购买 nike

作为 Racket 中的练习,我尝试创建一个类似 C 的函数,接受 return 关键字。

当我定义function宏时:

(require (for-syntax syntax/parse))
(define-syntax (function stx)
(syntax-parse stx
#:datum-literals (return)
[(_ (func-id arg-id ...) body ...)
#'(define (func-id arg-id ...)
(call/cc (lambda (return) body ...)))]))

并创建一个带有 return 语句的函数 f:

(function (f x) (return 100) (+ 1 x))
(f 2)

我得到:

return: undefined;
cannot reference an identifier before its definition

但是,扩展function宏:

(require macro-debugger/expand)
(syntax->datum (expand-only
#'(function (f x) (return 100) (+ 1 x))
(list #'function)))

返回:

'(define (f x) (call/cc (lambda (return) (return 100) (+ 1 x))))

事实上:

(define (f x) (call/cc (lambda (return) (return 100) (+ 1 x))))
(f 2)
> 100

按预期工作。

对于我的虚拟案例,可以替换 function 定义中的模式匹配,如下所示:

[(_ (func-id arg-id ...) (return x-expr) body ...)
#'(define (func-id arg-id ...)
(call/cc (lambda (return) (return x-expr) body ...)))]

但一般来说,return 关键字可以出现在函数体中的任何位置。

我该怎么做?

最佳答案

我认为您误解了datum-literals的含义。 datum-literals 用于模式匹配输入语法,而不是用于输出模板/语法。

您尝试做的事情不能纯粹通过重写规则来完成,因为 Racket 的卫生宏系统会将您的 return 重命名为其他名称以避免名称冲突。

通常的方法是使用语法参数。 Fear of Macros已经解释得很清楚了,所以我不再重复。

关于macros - 在 Racket 宏中使用新关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57750081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com