Как определить функцию в схеме 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))