Hi Andy. Thanks for following through on this. As you probably noticed, my motivation to work on `local-eval' has largely dissipated, so it's great that you finished this up in time for 2.0.4.
I haven't yet had time to fully review these patches, but for now, a quick scan reveals a few remaining problems. See below: Andy Wingo <wi...@pobox.com> writes: > +(define-syntax the-environment > + (lambda (x) > + (syntax-case x () > + ((the-environment) > + #'(the-environment the-environment)) > + ((the-environment scope) > + (call-with-values (lambda () > + (analyze-identifiers > + (syntax-locally-bound-identifiers #'scope))) > + (lambda (capture formals wrappers patterns) > + (define (wrap-expression x) > + (let lp ((x x) (wrappers wrappers)) > + (if (null? wrappers) > + x > + (lp ((car wrappers) x) (cdr wrappers))))) > + (with-syntax ((module (datum->syntax #'here (module-name > (current-module)))) ***** Again, the module must be the one embedded in `scope', not the (current-module). I guess this is a reminder that I need to add a more thorough set of regression tests for `local-eval'. > +(define (local-eval x e) > + "Evaluate the expression @var{x} within the lexical environment @var{e}." > + (cond ((lexical-environment? e) > + (apply (eval (local-expand x e) (lexenv-module e)) > + (lexenv-boxes e))) > + ((module? e) > + ;; Here we evaluate the expression within `lambda', and then > + ;; call the resulting procedure outside of the dynamic extent > + ;; of `eval'. We do this because `eval' sets (current-module) > + ;; within its dynamic extent, and we don't want that. Also, > + ;; doing it this way makes this a proper tail call. > + ((eval #`(lambda () #,x) e))) ***** Again, there should be an `#f' before `#,x' here, to force expression context (my mistake). > + (else (error "local-eval: invalid lexical environment" e)))) > + > +(define* (local-compile x e #:key (opts '())) > + "Compile and evaluate the expression @var{x} within the lexical > environment @var{e}." > + (cond ((lexical-environment? e) > + (apply (compile (local-expand x e) > + #:env (lexenv-module e) > + #:from 'scheme #:opts opts) > + (lexenv-boxes e))) > + ((module? e) > + ;; Here we compile the expression within `lambda', and then > + ;; call the resulting procedure outside of the dynamic extent > + ;; of `compile'. We do this because `compile' sets > + ;; (current-module) during evaluation, and we don't want that. > + ((compile #`(lambda () #,x) ***** Ditto. > + #:env e #:from 'scheme #:opts opts))) > + (else (error "local-compile: invalid lexical environment" e)))) I'll try to do a more thorough review later. Thanks, Mark