2010-07-10 3 views
1

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

Edit: Nevermind - У меня есть это сейчас :)

ответ

2

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

The R6RS definition дает некоторые примеры, в частности a section on syntax-object and datum conversions, что и есть то, что вы хотите. Вы должны уметь адаптировать пример loop w/break к вашему return.

+0

Спасибо, я думаю, это то, что я ищу. Я читал эту страницу, и ее сложно переварить; можете ли вы объяснить, что делает процедура 'синтаксиса'? Также полезно было бы более понятное описание 'with-syntax' и' datum-> syntax'/'syntax-> datum'. – Cam

+0

На самом деле, неважно - я знаю, что поняли эти термины. Благодаря! – Cam

+0

Я больше не могу отредактировать этот комментарий, но это все еще раздражает меня: я теперь понимаю эти термины :) – Cam

Смежные вопросы