Я предполагаю, что ваша исходная программа выглядела примерно так:
#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)))
Краткая история: на данный момент используйте syntax-case, а не syntax-rules; кажется, что есть некоторая ошибка, связанная с шаговым механизмом макросов и синтаксическими правилами. Я отправил отчет об ошибке разработчикам Racket, поэтому надеюсь, это скоро будет исправлено. Версия syntax-case приведенной выше программы выглядит следующим образом.
#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, где скрытие макросов установлено на «Стандартный»:
(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 до использования if. Очень странный!
Посмотрим, как обстоят дела под 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. .
Если вы пишете свой макрос, используя syntax-case, а не syntax-rules, он лучше работает с 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 и правилами синтаксиса. Поэтому попробуйте вместо этого использовать syntax-case.
person
dyoo
schedule
23.01.2012