protecting macro

Started by Dmi, May 01, 2006, 05:08:24 AM

Previous topic - Next topic

Dmi

Lutz,

Is it a good trick to define a macro as a context default function?

Seems that this can protect internal macro's symbols from interferring with ones that will be passed into macro:
(context 'push-end)
(set 'push-end
  (lambda-macro (_l_push _lst_push)
    "(push-end item list) - push item to the end of the list"
    (eval (list 'push (quote (eval _l_push)) _lst_push -1))))
(context MAIN)
;===================
> (push-end (list 2 3) _lst_push)
(2 3)
> _lst_push
((2 3))
WBR, Dmi

Lutz

#1
Yes, that is also mentioned in the Manual. This ways there is also no need for name conventions like underscore _



Later yoday I will release development version 8.8.6 which has a new 'letex': a combination of 'let' and 'expand'. This together with define-macro will give you full macro power and using the default function mechanism macros are hygienic, and you have finer control with the possibility to do macro-expansion with 'letex' independent from a function definition.



Lutz

rickyboy

#2
Looks good to me -- the debugger indicates that this is safe enough:
> (debug (push-end (list 2 3) _lst_push))

-----

(define-macro (push-end:push-end push-end:_l_push push-end:_lst_push)
  "(push-end item list) - push item to the end of the list"
  #(eval (list 'push (quote (eval push-end:_l_push)) push-end:_lst_push
    -1))#)


[-> 3 ] s|tep n|ext c|ont q|uit > push-end:_lst_push
MAIN:_lst_push


Thanks for the tip!  --Ricky
(λx. x x) (λx. x x)

Dmi

#3
Thanks, Lutz!

8.8.6 has a great improvements!
WBR, Dmi

rickyboy

#4
Quote from: "Lutz"Later yoday I will release development version 8.8.6 which has a new 'letex': a combination of 'let' and 'expand'. This together with define-macro will give you full macro power and using the default function mechanism macros are hygienic, and you have finer control with the possibility to do macro-expansion with 'letex' independent from a function definition.


I don't know know exactly what you mean here; however, be forewarned that, even with the use of 'letex', there is still the possibility that one's macro could suffer from variable capture.  For instance:


(define-macro (testie simble)
  (letex (x 42 y simble)
    (list x y)))

> (set 'x 1)
1
> (testie 1)
(42 1)
> (testie x)
(42 42)


However, in the following instance, if we follow the method of Dmi, 'x' will not get captured.


(context 'testie2)
(define-macro (testie2:testie2 simble)
  (letex (x 42 y simble)
    (list x y)))
(context MAIN)

> (set 'x 1)
1
> (testie2 x)
(42 1)
> (testie2 1)
(42 1)


In the manual, 'letex' does not claim "hygenicity", so we are OK.  I just didn't want anyone to have the wrong idea about 'letex'.  (Hint: I did.) --Rick
(λx. x x) (λx. x x)

Lutz

#5
That is correct, the hygiene of the macros is guaranteed vie the 'context' mechanism or when using 'args' for passing parameters. The 'letex' funtion in itself works just like any other lambda expression localizing variables in a dynamic scope which is not higienic.



Lutz