Как определить функцию в схеме scm, которая проверяет, является ли ее параметр макросом?

Например, предположим, что совпадение - макрос, а автомобиль - нет:

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

2 ответа

У большинства схем нет таких macro?функция. Чтобы отличить обычные функции от макросов, вы можете использовать procedure? от РнРС:

> (procedure? car)
#t

Проблема в том, что вы не можете назвать ключевое слово, используя синтаксис схемы:

> (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))
Другие вопросы по тегам