【发布时间】:2019-04-29 06:04:22
【问题描述】:
我正在尝试制作一个小外壳来对 csv 文件执行类似 sql 的查询(出于好奇和尝试学习 Racket)。为此,我想用这种粗略的结构实现一个 select 宏(我计划让 x 成为 db 的列,但现在只传递了一行):
(define-syntax select
(syntax-rules (* from where)
((_ col1 ... from db where condition)
(filter (lambda (x) condition) <minutiae>))))
(其中细节是文件 IO 和管道代码)
x 的范围不是我想的那样:
x: undefined;
cannot reference an identifier before its definition
我找到this example of a let-like macro:
(define-syntax my-let*
(syntax-rules ()
((_ ((binding expression) ...) body ...)
(let ()
(define binding expression) ...
body ...))))
然后我继续尝试像这样生成 lambda:
(define-syntax my-lambda
(syntax-rules ()
((_ body)
(lambda (x)
body))))
然后尝试模仿 let 示例的结构:
(define-syntax my-lambda
(syntax-rules ()
((_ body)
(lambda (x_)
(let ()
(define x x_)
body)))))
这两个在调用((my-lambda (+ x 1)) 0)时给了我同样的错误:
x: undefined;
cannot reference an identifier before its definition
根据我的阅读,这是由于卫生问题,但我似乎无法很好地掌握它来自己解决这个问题。我做错了什么,如何定义这些宏?为什么 let 示例有效,而 lambda 示例无效?
【问题讨论】:
标签: lambda macros racket hygiene