Какое использование синтаксического регистра в этой форме в Racket/Scheme

Меня смущает документация о синтаксисе использования, но что может означать f?

(define-syntax (check stx)
   (syntax-case stx ()
       [(f (x y))
        #'(list 'second: f x y)]))

person Community    schedule 08.03.2011    source источник


Ответы (1)


Этот код взломан довольно тонким способом.

Начать с,

(define-syntax (check stx)
   (syntax-case stx ()
       [(f (x y))
        #'(list 'second: f x y)]))

(check (3 4))

Выдает ошибку: проверьте: неверный синтаксис в: проверить

Проблема, однако, заключается в использовании 'f', которое появляется в расширении. Чтобы увидеть это, попробуйте вынуть его:

(define-syntax (check stx)
   (syntax-case stx ()
       [(f (x y))
        #'(list 'second: 1234 x y)]))

(check (3 4))

Это оценивает отлично, производя '(секунда: 1234 3 4)

Итак, почему первый терпит неудачу? Проблема в том, что в вашем первом примере

(check (3 4))

расширяется в

(list 'second check 3 4)

Однако проблема заключается в том, что «проверка» в расширении является другим использованием макроса «проверка» и, следовательно, должна быть дальше расширена, а это второе расширение не имеет правильной формы. .

Чтобы убедиться в этом, вы можете попробовать расширить свою программу с помощью шагового макроса. Запустите пошаговый макрос, используйте раскрывающееся меню, чтобы выбрать «Стандартное» скрытие макроса, нажмите кнопку «Конец-->», а затем вернитесь на один шаг назад.

Обычным соглашением является использование символа подчеркивания «_» в качестве символа «безразлично» для соответствия имени макроса в шаблоне, например:

(define-syntax (check stx)
   (syntax-case stx ()
       [(_ (x y))
        #'(list 'second: 1234 x y)]))

(check (3 4))

Из любопытства: откуда этот код?

person John Clements    schedule 08.03.2011
comment
Я изучаю синтаксис в ракетке, код для тестирования. Так что, если я заменю f в первом примере на (f (x y)), синтаксис кода будет правильным, хотя в итоге получится бесконечная рекурсия. Спасибо. - person ; 08.03.2011
comment
Джон: Ты должен был упомянуть макростеппер! - person Eli Barzilay; 08.03.2011