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

时间:2020-10-07 16:00:58

标签: scheme chez-scheme bigloo

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

throw new Error('Unexpected import statement in CJS module.');
            ^
Error: Unexpected import statement in CJS module.

2 个答案:

答案 0 :(得分:1)

大多数方案没有这样的macro?功能。要将普通功能与宏区分开来,可以使用RnRS中的procedure?

> (procedure? car)
#t

答案 1 :(得分: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))