Как сделать только часть макроса гигиенической

Я хотел бы иметь версию 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 процедуры

Редактировать: Nevermind - у меня есть это сейчас:)

1 ответ

Решение

Что вы хотите syntax-case вместо syntax-rules,

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

Другие вопросы по тегам