例如,假设 'match 是一个宏,而 'car 不是:
> (macro? 'match)
#t
> (macro? 'car)
#f
大多数方案没有这样的macro?
功能。要区分普通函数和宏,您可以使用procedure?
RnRS:
> (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))