Struggling to grasp newlisp macros

Started by jsmall, September 23, 2004, 08:19:18 PM

Previous topic - Next topic

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

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

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



Lutz

jsmall

#3
Quote from: "Lutz"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!