Этот вопрос по своему охвату аналогичен: В схеме R6RS есть способ получить текущую среду для использования с eval? но я хотел бы пойти дальше и спросить, как бы вы исправили что-то вроде это.
Моя проблема еще больше осложняется тем, что в моем случае '(+ x y)
является произвольным неоцененным лямбда-выражением. Без оценки, потому что он может содержать вызовы переменных, которые являются частью let (и поскольку Scheme не верит в то, что процедура будет вызываться в среде, содержащей эти переменные, когда текущая нет, она вызывает ошибку неопределенного идентификатора) . Таким образом, возникает вопрос: как я могу реструктурировать свой код, чтобы этот кошмар определения области видимости больше не был проблемой? Я хотел бы по-прежнему иметь возможность использовать переменные среды из let всякий раз, когда вызывается лямбда.
Я использую Pretty Big
Намерение состоит в том, чтобы создать классы в Scheme. Мой подход пока довольно обширен (без каламбура), но выглядит так:
(define (dispatch msg methods args)
(if (null? methods) (display "Method signature not found.")
(let (
(m-name (caar methods))
(m-args (cadar methods))
(m-body (caddar methods)))
(if (and (eq? msg (caar methods)) (eq? (length args) (length (cadar methods))))
`(lambda ,m-args ,m-body)
(dispatch msg (cdr methods) args)))))
(define (build-lets c-def)
(let (
(i-vars (cadr c-def))
(meths (caddr c-def)))
(eval `(append ',i-vars (list (list 'methods '',meths))))))
(define (new c-def . args)
(apply (eval `(lambda ,(map cadr (cadr c-def))
(let* ,(build-lets c-def)
(lambda (msg . args)
(letrec ((meth (dispatch msg methods args)))
(apply meth args))))))
args))
Где c-def - это класс def формы (скажем, для точки)
'(();Name of parent
((yvalue y) (xvalue x)) ;Instance variables: (i-var constructor-arg)
((getx () xvalue) ;Methods, ((name args body) ...)
(setx (x) (set! xvalue x)))))