Variables locais e globais en autolisp

Cando creamos unha función en autolisp deberemos de ser coidadosos de non empregar variables globais. Estas xeran conflitos noutras funcións, e procurar o erro as veces resulta tedioso. En autolisp, se non declaramos a función como local, por defecto será global. Para declarar unha variable como local deberemos de facelo nos parámetros da función. Na seguinte función suma, os parámetros n1 e n2 serven para introducir eses datos na función. A variables n3 é local da función suma. Aínda que queiramos ler o seu valor desde outra función, non será posible.

(defun suma (n1 n2 / n3)
(setq n1 (+ n1 1))
(setq n3 (- n1 n2))
(setq n4 (+ n1 n2))
)

Vexamos o seguinte exemplo. Na función suma introducimos dos valores a través das variables n1 e n2. Concretamente á variable n1 asignámoslle o valor de a e a n2 asignámoslle o valor de b (definidas na función principal io), e a función suma sumámoslle unha unidade a n1, é dicir ao valor de a (2) sumámoslle 1 e quedará 3 . A variable n3 é local, fronte a n4 que é global, e polo tanto un punto crítico na programación

(defun suma (n1 n2 / n3)
(setq n1 (+ n1 1))
(setq n3 (- n1 n2))
(setq n4 (+ n1 n2))
)

(defun c:io(/ a b resultado)
(setq n3 nil)
(setq resultado nil)
(setq a 2)
(setq b 3)
(setq resultado (suma a b))
(princ "\n valor de n3:")
(princ n3)
(princ "\n resultado: ")
(princ resultado)
(princ)
)

Na función principal, o primeiro que facemos é resetear os posibles valores de n3 e n4. Asiámoslle valores a a e b. Non hai motivo ningún polo que deixalas como variables globais, polo tanto definímolas como locais na cabeceira da función, colocándooas á dereita da barra inclinada.

Seguidamente chamamdos a función suma (suma a b), e resultado da mesma gardámolo en resultado:

(setq resultado (suma a b))

Pero que valor gardamos?. Noutras linguaxes de programación pódese definir que parámetro queremos que devolva unha función con return n3, por exemplo. En autolisp non dispoñemos de return, e o resultado dunha función será o último setq que teñamos definido na función:

(defun suma (n1 n2 / n3)
(setq n1 (+ n1 1))
(setq n3 (- n1 n2))
(setq n4 (+ n1 n2))
)

Neste exemplo, o resultado da fucnión é n4, pois é o último setq que se definiu na función. Deste xeito o valor de n4 gardarese na variable resultado, que imprimos posteriormente. Se desde a función principal queremos acceder a unha variable definida como local noutra función, neste caso n3, veremos que non poderemos e a súa vez, teremos claro que o valor que colla non nos vai producir interferencias na variable da función principal no caso de que coincida o nome. Vemos aquí a saída do programa:

Comando: IO

 valor de n3:nil
 resultado: 6

No caso de que queiramos imprimir n4 desde a función principal (ou cambiar o seu valor), poderemos facelo, xa que non especificamos que fose unha variable local, e polo tanto é global. Isto, repito é unha fonte de problemas.

(defun c:io(/ a b resultado)
(setq n3 nil)
(setq resultado nil)
(setq a 2)
(setq b 3)
(setq resultado (suma a b))
(princ "\n valor de n3:")
(princ n3)
(princ "\n valor de n4:")
(princ n4)
(princ "\n resultado: ")
(princ resultado)
(princ)
)

Execución da rutina:

Comando: IO

valor de n3:nil
valor de n4:6
resultado: 6