Variable name clashes

Started by jopython, November 28, 2012, 01:45:06 PM

Previous topic - Next topic

jopython


> (module "macro.lsp")
MAIN
>
(macro (square-sum X Y)
   (letn ((First X)
          (Second Y)
          (Sum (+ First Second)))
      (* Sum Sum)))

(lambda-macro (X Y) (expand '(letn ((First X) (Second Y) (Sum (+ First Second)))
   (* Sum Sum))))

> (let ((First 9)) (square-sum 1 First))
4
>



Instead of getting a 100 , i get a 4.

How do newlispers solve this issue?

johu

#1
(macro (square-sum First Second)
   (let ((Sum (+ First Second)))
      (* Sum Sum)))

or


(macro (square-sum X Y)
  (pow (+ X Y) 2))

Lutz

#2
You have a clash between "First" on the caller level and "First" inside a 'define-macro statement generated by 'macro.



You could put 'square-sum in its own namespace:



(module "macro.lsp")

(context 'mymacros)

(macro (square-sum X Y)
   (letn ((First X)
          (Second Y)
          (sum (+ First Second)))
      (* sum sum)))

(context MAIN)

(let ((First 9)) (mymacros:square-sum 1 First)) => 100


Unfortunately a default functor as used in one of the examples in http://www.newlisp.org/downloads/newlisp_manual.html#define-macro">http://www.newlisp.org/downloads/newlis ... fine-macro">http://www.newlisp.org/downloads/newlisp_manual.html#define-macro will not work together with the macro.lsp module.  UPDATE: a new macro.lsp, now online, also allows default functors.



On a general note:

Use expansion macros generated using the macro.lsp only for small one-liners. The function/fexpr call overhead saved when using macro.lsp is not worth it with any code longer than a line.



Almost always using 'define-macro with 'letex or 'evel is the better choice. Fexprs generated with 'define-macro work well as context default functions and load faster when newLISP is reading source.

jopython

#3
Thanks for the reply. I should have worded my question appropriately.



How to use variables/symbols in macros, so that in future these don't interfere with the user defined variables? In these case it is the 'First' and 'Second' variables.

jopython

#4
Lutz,



Thank you for the 'context' solution.

I also accept your advice for using macros.lsp for one liners only in future.

jopython

#5
Lutz,

The NEW macro.lsp has the same variable clash issue when I use default functors.



newLISP v.10.4.5 on Linux IPv4/6 UTF-8 libffi, execute 'newlisp -h' for more info.

> (load "http://www.newlisp.org/code/modules/macro.lsp")

MAIN
>
>
(macro (square-sum:square-sum X Y)
   (letn ((First X)
          (Second Y)
          (sum (+ First Second)))
      (* sum sum)))

(lambda-macro (X Y) (expand '(letn ((First X) (Second Y) (sum (+ First Second)))
   (* sum sum))))
> (context MAIN)
MAIN
>
> (define (callsq a b) (square-sum a b))
(lambda (a b)
 (letn ((First a) (Second b) (sum (+ First Second)))
  (* sum sum)))
> (square-sum 1 9)
100
> (let (First 9) (square-sum 1 First))
4

Lutz

#6
the whole definition must go into the 'square-sum name space:

newLISP v.10.4.5 on OSX IPv4/6 UTF-8 libffi, execute 'newlisp -h' for more info.

>
(load "http://www.newlisp.org/code/modules/macro.lsp")
(context 'square-sum)
(macro (square-sum:square-sum X Y)
   (letn ((First X)
          (Second Y)
          (sum (+ First Second)))
      (* sum sum)))
(context MAIN)

MAIN
square-sum
(lambda-macro (X Y) (expand '(letn ((First X) (Second Y) (sum (+ First Second)))
   (* sum sum))))
MAIN
> (let (First 9) (square-sum 1 First))
100
>


now all variables used in the definition are protected.