Предположим, я хочу вызвать макрос Scheme для чего-то другого, кроме первого элемента в s-выражении. Например, предположим, что я хочу заменить define
инфиксным стилем :=
, чтобы:
(a := 5) -> (define a 5)
((square x) := (* x x)) -> (define (square x) (* x x))
Фактическое преобразование выглядело довольно просто. Хитрость заключается в том, чтобы заставить Scheme найти выражения :=
и макрорасширить их. Я подумал о том, чтобы окружить большие участки кода, использующие синтаксис инфикса, стандартным макросом, например: (with-infix-define expr1 expr2 ...)
, и использовать стандартный макрос для обхода выражений в его теле и выполнить необходимые преобразования. Я знаю, что если я выберу этот подход, мне придется быть осторожным, чтобы избежать преобразования списков, которые на самом деле должны быть данными, таких как списки в кавычках и определенные разделы списков в квазикавычках. Пример того, что я себе представляю:
(with-infix-define
((make-adder n) := (lambda (m) (+ n m)))
((foo) :=
(add-3 := (make-adder 3))
(add-6 := (make-adder 6))
(let ((a 5) (b 6))
(+ (add-3 a) (add-6 b))))
(display (foo))
(display '(This := should not be transformed))
Итак, мой вопрос состоит из двух частей:
with-infix-define
, должен ли я остерегаться каких-либо камней преткновения, других? чем цитировать и квазицитировать?