|
|
|
|
|
by kazinator
1366 days ago
|
|
We can analyze lexical scoping through quote. Here is TXR Lisp doing it: 1> (defmacro free-vars (expr :env e)
(if-match (quote @qexp) expr ;; unwrap quote if it occurs
(set expr qexp))
(tree-bind (expansion free-vars free-funs . rest) (expand-with-free-refs expr e)
^(quote ,free-vars)))
free-vars
2> (let ((a 42)) (free-vars '(lambda () (+ a b))))
(b)
Roughly speaking, this is the basis for doing things like back-referencing against an existing lexical variable in pattern matching: 3> (let ((x 1))
(match (@x @y) '(1 2) y))
2
4> (let ((x 1))
(match (@x @y) '(2 2) y))
** match: (@x @y) failed to match object (2 2)
match is nothing but a macro; application code could supply an equivalent, depending only on what is publicly documented.Syntactically, the variable terms in (@x @y) are in the same category. Yet x is interpreted by the pattern matcher as a bound variable, whose value matches the corresponding object; whereas y is interpreted as a free variable to be lexically bound to the corresponding object. You just need a macro system with environment parameters, and a defined API into them. With help from the macro system, we could write an interpreter such that (let ((a 1) (b 2)) (interpret '(list a b))) will yield (1 2). interpret can't be a function; it has to be a macro which analyzes the argument for variables and creates a bridge between those variables and the surrounding lexicals at the point where interpret finds itself. The interpret macro transforms the code somehow and then hands it to an interpreter function. |
|