この質問の範囲は似ています: In R6RS Scheme, is there a way to get the current environment for use with 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 はフォームのクラス定義です (たとえば、ポイント)
'(();Name of parent
((yvalue y) (xvalue x)) ;Instance variables: (i-var constructor-arg)
((getx () xvalue) ;Methods, ((name args body) ...)
(setx (x) (set! xvalue x)))))