如何在scm方案中定义一个函数来测试其参数是否为宏



例如,假设"match"是宏,而"car"不是:

> (macro? 'match)
#t
> (macro? 'car)
#f

大多数方案都没有这样的macro?函数。要区分正常函数和宏,可以使用RnRS:中的procedure?

> (procedure? car)
#t

问题是无法使用Scheme语法命名关键字:

> (procedure? let)
Exception: invalid syntax let

所以你必须使用一个符号,比如'let来指代它。考虑到eval需要能够区分关键字和其他标识符,你可以尝试这样的方法:

(define keyword?
(lambda (symbol)
(guard (x [else (syntax-violation? x)])
(eval symbol)
#f)))
(keyword? 'let) ⇒ #t
(keyword? 'car) ⇒ #f
(keyword? 'does-not-exist) ⇒ #f

但这无疑是一把相当大的锤子。eval的这种单参数形式是Chez Scheme的扩展,提供(interaction-environment)作为默认环境。它也不完全安全,因为它挂起:

(let-syntax ([foo (lambda (x) (raise "oops"))])
(keyword? 'foo))

相关内容

  • 没有找到相关文章

最新更新