Я бы хотел иметь версию 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
процедуры
Редактировать: Неважно - теперь я понял:)