Struggling to grasp newlisp macros

Pondering the philosophy behind the language
Locked
jsmall
Posts: 26
Joined: Mon Sep 20, 2004 1:44 am

Struggling to grasp newlisp macros

Post by jsmall »

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

jsmall
Posts: 26
Joined: Mon Sep 20, 2004 1:44 am

Eureka - I understand - lambda-macro is really lambda-lazy

Post by jsmall »

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.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

You can also have variable expansion in macros using the newLISP function 'expand'

Lutz

jsmall
Posts: 26
Joined: Mon Sep 20, 2004 1:44 am

(expand ...) in lambda-macros "lists"

Post by jsmall »

Lutz wrote:You can also have variable expansion in macros using the newLISP function 'expand'

Lutz
So the following would define bar as interned in the first email of this
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!

Locked