I'm trying to come up with a conceptual model of how
define-macro works.
>(define-macro (foo _x _x) (list _x _y))
(lambda-macro (_x _y) (list _x _y))
> (foo 1 2)
(1 2)
> (foo a b)
(a b)
So far so good. Conceptually I'm thinking the macro
invocation is a two step process.
> (foo a b)
((lambda-macro (_x _x) (list _x _y)) 'a 'b)
which returns
(list 'a 'b)
which is then interpreted normally returning
(a b)
But now when I define bar
> (define-macro (bar _x _y) (fn () (list _x _y))
(lambda-macro (_x _y) (lambda () (list _x _y)))
and apply it to
> (bar a b)
(lambda () (list _x _y))
But I expected from my obviously wrong conceptual
model for
> (bar a b)
> ((lambda-macro (_x _y) (lambda () (list _x _y)) 'a 'b)
to have returned
(lambda () (list 'a 'b))
But it returned instead
(lambda () (list _x _y))
It appears that the internally defined lambda expression
is evaluated without substituting 'a and 'b in place
of _x and _y formal arguments.
What's happening? Where is my thinking wrong?
Thanks
Struggling to grasp newlisp macros
Eureka - I understand - lambda-macro is really lambda-lazy
define-macro is really define-lazy and not a macro at all.
Thus
> (define-lazy (bar _x _y) (fn () (list _x _y)))
(lambda-lazy (_x _y) (lambda-strict () _x _y))
and
> (bar a b)
> ((lambda-lazy (_x _y) (lambda-strict () _x _y)) 'a 'b)
(lambda-strict() _x _y)
which models the behavior of define-macro perfectly.
And it also explains the example
>(define-macro (my-setq x y) (set x (eval y)))
(lambda-macro (x y) (set x (eval y))
>(my-setq x 123)
123
> x
nil
Because
>(define-lazy (my-setq x y) (set x (eval y))
(lambda-lazy (x y) (set x (eval y))
> (my-setq x 123)
> ((lambda-lazy (x y) (set x (eval y)) 'x 123)
123
Because x is a local to lambda-lazy it can't set x in
the otherwise dynamic outer scope.
Thus
> (define-lazy (bar _x _y) (fn () (list _x _y)))
(lambda-lazy (_x _y) (lambda-strict () _x _y))
and
> (bar a b)
> ((lambda-lazy (_x _y) (lambda-strict () _x _y)) 'a 'b)
(lambda-strict() _x _y)
which models the behavior of define-macro perfectly.
And it also explains the example
>(define-macro (my-setq x y) (set x (eval y)))
(lambda-macro (x y) (set x (eval y))
>(my-setq x 123)
123
> x
nil
Because
>(define-lazy (my-setq x y) (set x (eval y))
(lambda-lazy (x y) (set x (eval y))
> (my-setq x 123)
> ((lambda-lazy (x y) (set x (eval y)) 'x 123)
123
Because x is a local to lambda-lazy it can't set x in
the otherwise dynamic outer scope.
(expand ...) in lambda-macros "lists"
So the following would define bar as interned in the first email of thisLutz wrote:You can also have variable expansion in macros using the newLISP function 'expand'
Lutz
thread:
> (define-macro (bar _x _y) (expand (fn () (list _x _y) '_x '_y))
> (foo 1 2)
(lambda () (list 1 2))
I'm beginning to appreciate the expressive power of lambda
lists and lambda-macro lists.
Thanks!