Шаговый макрос в DrRacket

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

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

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


person Racket Noob    schedule 22.01.2012    source источник
comment
Возможно, вы захотите попробовать irc-канал #racket freenode. Такого рода вопросы выиграют от двусторонней беседы, которую StackOverflow на самом деле не обеспечивает.   -  person Dan Burton    schedule 23.01.2012
comment
Да, Дэн, я знаю это. Но, к сожалению, я не могу задавать свои вопросы там, потому что я забанен в группе пользователей Racket (Шрирам Кришнамурти ненавидит меня, потому что я критиковал их веб-фреймворк).   -  person Racket Noob    schedule 23.01.2012
comment
@Greg H: да, я очень благодарен dyoo, и я выразил это, проголосовав за его ответ. Я не знаю, как пометить его ответ как принятый (не смог найти эту кнопку)   -  person Racket Noob    schedule 25.01.2012
comment
Рядом с кнопками «за»/«против» вы видите очертание галочки? Если вы щелкнете по нему, он станет сплошным зеленым, и вы приняли ответ.   -  person Greg Hendershott    schedule 25.01.2012


Ответы (2)


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

#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
comment
Прохладный. Если ответ приемлем, отметьте этот вопрос как отвеченный, чтобы исключить его из списка неотвеченных на SO. - person dyoo; 23.01.2012

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

person Óscar López    schedule 22.01.2012
comment
Я запускаю DrRacket 5.2 в Windows 7, язык #lang racket Вот скриншот: uploadscreenshot.com/ изображение/705182/3970725 - person Racket Noob; 22.01.2012
comment
@RacketNoob: Похоже, вы пытаетесь выполнить расширение модуля, а не расширение макроса. - person leppie; 22.01.2012
comment
Извините, я не могу получить второе расширение myor (кнопка Шаг -> после первого нажатия становится серой, что бы я ни делал). Может кто-нибудь дать подробную пошаговую инструкцию, как пройти все шаги раскрытия макроса до конца? - person Racket Noob; 23.01.2012