Globals are good; they stop you having to pass around big parameter lists.
Globals are bad; side-effects from one function can ruin another.
With LISP's local-global trick you can have it both ways. A global is copied to a local temporary that can be referenced by called functions called from some master function. BUT, and here's the the trick, all changes made by this sub-functions just go away when they terminate.
Here's how it works. First, define global parameter:
(defparameter *x* 1)
Now, define a main function that calls some worker function.
(defun main() (format t "before ~a~%" *x*) (worker) (format t "after ~a~%" *x*) )The worker changes the scope of the global using the "&optional" command, then calls some underlings to get the job done.
(defun worker (&optional (*x* *x*)) (underling) ) (defun underling () (format t "during1 ~a~%" *x*) (dotimes (i 3) (incf *x* i) (format t "during2 ~a~%" *x*)))
Now, when the worker is call, all the changes made by the underlings disappear when the work is done. Observe in the following how the underling makes many changes to "*x*" which are gone when the worker terminates:
CL-USER> (main) before 1 during1 1 during2 1 during2 2 during2 4 after 1