Как сделать только часть макроса гигиенической - PullRequest
1 голос
/ 11 июля 2010

Я бы хотел иметь версию lambda, которая называется lambda-r, из которой вы можете return.Пример:

(+ ((lambda-r ()
    (return 1)
    2)) 5)

Это даст значение 6.Хотя вы можете ожидать, что значение будет равно 7, оно равно 6, потому что 1 возвращается из лямбда-выражения до того, как будет достигнуто значение 2.

Вот пример типа преобразования, которое я ищу.Допустим, нужно было использовать lambda-r следующим образом:

(lambda-r (a b)
    (return a)
    (+ a b))

Я хочу, чтобы оно было преобразовано так:

(call/cc (lambda (k)
       (define return (lambda (v)
                        (k (lambda (a b)
                             v))))
       (lambda (a b)
         (return a)
         (+ a b))))

Это также можно выразить с помощью выражения let вместовнутреннего определения, но я использую определение для ясности.

Обратите внимание, что приведенный выше код на самом деле работает, как ожидалось. Проблема в том, что у меня возникают проблемы с выражением lambda-r в виде макроса .Причина в том, что я хочу, чтобы k и v были гигиеничными, но я не хочу, чтобы return был гигиеничными.

Мой макрос на данный момент таков:

(define-syntax lambda-r
  (syntax-rules (return)
    [(_ (var ...) body ...)
     (call/cc (lambda (k)
           (define return (lambda (v)
                            (k (lambda (var ...)
                                 v))))
           (lambda (var ...)
             body ...)))
     ]))

Что не работает, потому что return обрабатывается гигиенически, и в результате не отображается непосредственно при использовании lambda-r.Поэтому (lambda-r () (return 1)) выдает ошибку, которая говорит о том, что return не является допустимым идентификатором.


Редактировать: Благодаря ответу Натана Сандерса, я ближе к пониманию того, что я должен сделать здесь,Однако я не полностью понимаю следующие процедуры, и в результате я еще не смог заставить это работать.Я был бы очень признателен, если бы вы могли объяснить / направить меня к ресурсам, которые объясняют следующее:

  • syntax процедура
  • datum->syntax / syntax->datum процедуры

Редактировать: Неважно - теперь я понял:)

1 Ответ

2 голосов
/ 11 июля 2010

То, что вы хотите, это syntax-case вместо syntax-rules.

Определение R6RS дает несколько примеров, в частности раздел о синтаксических объектах и ​​базовых преобразованиях , который вам нужен. Вы должны быть в состоянии приспособить пример loop w / break к вашему return.

...