Я предполагаю, что ваша исходная программа выглядела примерно так:
#lang racket
(define-syntax myor
(syntax-rules ()
[(myor e) e]
[(myor e1 . es)
(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
Короткая история: используйте синтаксис-регистр вместо синтакс-правила на данный момент; Кажется, есть некоторая ошибка, связанная со степпером Macro и синтаксическими правилами. Я отправил сообщение об ошибке разработчикам Racket, так что, надеюсь, это будет исправлено в ближайшее время. * Синтаксическая версия версии вышеуказанной программы выглядит следующим образом.
#lang racket
(define-syntax (myor stx)
(syntax-case stx ()
[(_ e) #'e]
[(_ e1 . es)
#'(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
Ниже длинная история ...
Когда я запускаю вашу программу под предварительным выпуском 5.2.1, я вижу следующее в Macro Stepper, где для Macro скрыто значение "Standard":
(module anonymous-module racket
(#%module-begin
(define-syntax myor
(syntax-rules () [(myor e) e] [(myor e1 . es) (let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(let:26 ([r:26 (negative? r)]) (if:26 r:26 r:26 (myor:26 (positive? r)))))))
что выглядит неправильно. Он расширяет только одно использование myor до использования , если . Очень странно!
Посмотрим, как будут выглядеть Racket 5.2 ...
(module anonymous-module racket
(#%module-begin
(define-syntax myor
(syntax-rules () [(myor e) e] [(myor e1 . es) (let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r) (let ([r (negative? r)]) (if r r (myor (positive? r)))))))
Ах. Хорошо, я могу подтвердить, что вижу ту же проблему, что и в Racket 5.2, а также предварительную версию.
Ошибка, по-видимому, связана с поведением функции «Скрытие макроса», которая пытается не перегружать вас полным расширением, если для него установлено значение «Стандартный». Если вы установите для него значение «Отключено», вы увидите, что макрос-отладчик покажет расширение в его полной, без прикрас лаке, и оно включает в себя расширение, которое мы ожидаем увидеть:
(module anonymous-module racket
(#%module-begin
(define-syntaxes (myor)
(lambda (x)
; ... I'm omitting the content here: it's way too long.
))
(define-values:20 (nonzero?)
(lambda:21 (r) (let-values:22 (((r) (#%app:23 negative? r))) (if r r (#%app:24 positive? r)))))))
Я напишу отчет об ошибке и отправлю его разработчикам Racket.
Если вы напишите свой макрос, используя синтаксис-регистр , в отличие от синтакс-правила , похоже, он лучше работает с Macro Stepper.
#lang racket
(define-syntax (myor stx)
(syntax-case stx ()
[(_ e) #'e]
[(_ e1 . es)
#'(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
Когда я прохожу через это, кажется, работает намного лучше. Так что, что бы ни вызывало ошибку, это, кажется, некоторое взаимодействие с Macro Stepper и синтаксическими правилами . Поэтому попробуйте вместо этого использовать синтаксис-регистр .