NewLisp has a convenient way of synthesizing
lexical scope behavior whenever you need it.
(define z 3)
(define foo
(let ((y 2))
(expand (lambda (x) (list x y z)) 'y 'z)))
(foo 1) ;; ==> (1 2 3)
The "expand" built-in function takes its first
argument, e.g. the lambda expression here, and
expands all symbols within it to the values
calculated by evaluating the remaining
symbolic arguments.
Since the dynamic scope of "expand" is also the
lexical scope of lambda this results in the
expected behavior. Thus the "foo" above is bound
to the following lambda list:
> foo
(lambda (x) (list x 2 3))
The following convenience macro expand-let lets
you set up lexical scope behavior wherever.
(define z 3)
(define foo
(expand-let
(lambda (x) (list x y z))
(y 2) (z z)))
Now you can whichever scoping strategy you want,
lexical or dynamic.
(define-macro (expand-let )
(eval
(cons 'let
(cons (rest (args))
(list (cons 'expand
(cons (first (args))
(map (fn (arg) (apply quote (list (first arg))))
(rest (args))))))))))