Макро степпер в DrRacket - PullRequest
       59

Макро степпер в DrRacket

3 голосов
/ 22 января 2012

По ссылке http://www.ccs.neu.edu/home/ryanc/macro-stepper/tutorial.html есть инструкции по работе с макро-степпером.

Однако, когда я собираюсь попробовать это, я не могу получить второе расширение myor вопределение ненулевое?функция только первая.Кроме того, у меня нет кнопок «Предыдущий термин» и «Следующий термин».

Так что мой вопрос: как мне настроить макрос шаговый, чтобы получить второе расширение, как в учебнике?

Ответы [ 2 ]

6 голосов
/ 23 января 2012

Я предполагаю, что ваша исходная программа выглядела примерно так:

#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 и синтаксическими правилами . Поэтому попробуйте вместо этого использовать синтаксис-регистр .

1 голос
/ 22 января 2012

Это сработало для меня без необходимости делать что-то дополнительное.Попробуйте использовать новейшую версию Racket, также попробуйте выбрать другой язык из меню и убедитесь, что для выбранного языка выбран debugging.

...