Andy Wingo <wi...@pobox.com> writes: > What are the meanings of these expressions:
I found it amusing to see what my definitions using with-current-continuation will produce here. > ;; Toplevel > (local-eval '(define foo 42) (the-environment)) guile> (my-eval '(define foo 42) (my-env)) guile> foo 42 > ;; Lexical, tail context > (local-eval '(define foo 42) (let ((x 100)) (the-environment))) guile> (my-eval '(define foo 42) (let ((x 100)) (my-env))) Backtrace: In standard input: 1: 0* [my-eval (define foo 42) ... 1: 1* (let* ((x 100)) (#<continuation 1401 @ 9253970> (define foo 42))) 1: 2 (begin #<continuation 1581 @ 9252000>) 1: 3 [#<continuation 1401 @ 9253970> ... 1: 4* (define foo 42) standard input:1:11: In procedure memoization in expression (define foo 42): standard input:1:11: In file "standard input", line 0: Bad define placement (define foo 42). ABORT: (syntax-error) guile> > ;; Lexical, tail context -- but with a definition > (local-eval '(begin (define foo 42) foo) (let ((x 100)) (the-environment))) guile> (my-eval '(begin (define foo 42) foo) (let ((x 100)) (my-env))) Backtrace: In standard input: 6: 0* [my-eval (begin (define foo 42) foo) ... 6: 1* (let* ((x 100)) (#<continuation 1401 @ 9219b38> (begin # foo))) 6: 2 (begin #<continuation 1581 @ 9259a80>) 6: 3 [#<continuation 1401 @ 9219b38> ... 6: 4* (begin (define foo 42) foo) 6: 5* (define foo 42) standard input:6:18: In procedure memoization in expression (define foo 42): standard input:6:18: In file "standard input", line 5: Bad define placement (define foo 42). ABORT: (syntax-error) guile> > ;; Lexical, tail context -- but with a definition, and nested reference > (local-eval '(begin (define foo 42) (bar)) > (let ((x 100)) (define (bar) foo) (the-environment))) guile> (my-eval '(begin (define foo 42) (bar)) (let ((x 100)) (define (bar) foo) (my-env))) Backtrace: In standard input: 13: 0* [my-eval (begin (define foo 42) (bar)) ... 13: 1* (let* ((x 100)) (letrec (#) (# #))) In unknown file: ?: 2 (letrec ((bar #)) (#<continuation 1401 @ 925e7c0> (begin # #))) In standard input: ... 13: 3 [#<continuation 1401 @ 925e7c0> ... 13: 4* (begin (define foo 42) (bar)) 13: 5* (define foo 42) standard input:13:18: In procedure memoization in expression (define foo 42): standard input:13:18: In file "standard input", line 12: Bad define placement (define foo 42). ABORT: (syntax-error) > ;; Lexical, not a definition context > (local-eval '(define foo 42) (let ((x 100)) not-a-definition > (the-environment))) guile> (my-eval '(define foo 42) (let ((x 100)) "hello" (my-env))) Backtrace: In standard input: 12: 0* [my-eval (define foo 42) ... 12: 1* (let* ((x 100)) "hello" (#<continuation 1401 @ 9253970> (define foo 42))) 12: 2 (begin #<continuation 1581 @ 9252000>) 12: 3 [#<continuation 1401 @ 9253970> ... 12: 4* (define foo 42) standard input:12:11: In procedure memoization in expression (define foo 42): standard input:12:11: In file "standard input", line 11: Bad define placement (define foo 42). ABORT: (syntax-error) guile> > What about this one: > > ;; Keeping in mind that `or' expands to (let ((t ...)) (if t t ...)), > ;; hygienically > (local-eval 't '(let ((t 42)) (or #f (the-environment)))) Assuming that the second quote mark is a typo. guile> (my-eval 't (let ((t 42)) (or #f (my-env)))) 42 guile> Now of course, the continuation based approach that just hijacks the expander and jumps in and out of it is not really a measure of how things should work. But it makes clear that (the-environment) is a bit of a chimera: it captures content at a level conceptually relevant for (define), but returns a value and has to be placed accordingly, like in a function call or at the providing side of a binding construct. If those different syntactic aspects prove to be too hard to conciliate, it might help to look at the kind of interface that some other chimeras like call-with-values or call-with-current-continuation have taken. -- David Kastrup