2

例如,假设 'match 是一个宏,而 'car 不是:

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

2 回答 2

1

大多数方案没有这样的macro?功能。要区分普通函数和宏,您可以使用procedure?RnRS:

> (procedure? car)
#t
于 2020-11-10T08:44:39.510 回答
1

问题是您不能使用 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))
于 2020-11-16T22:35:42.277 回答