[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Side effecting constants inside functions
In CLtL, I can't find any mention of the issue of side effecting
internal constants. In Maclisp, NIL, Zetalisp, and presumably most
Common Lisp implementations, the function:
(defun withdraw (amount)
(let ((balance '(1000)))
(decf (first balance) amount)))
acts much like a lexical closure with a local state variable.
Thus, (withdraw 100) => 900, then (withdraw 100) => 800, etc. This
behaviour has always bothered me. Is this rather questionable style
condoned by Common Lisp?
Efficiency aside, it would be cleaner for the semantics of a function
which side effects its internal constants to be as though a fresh copy
were made each time the function was evaluated, effectively making
'(1000) == (list 1000) and #(1 2 3) == (vector 1 2 3), etc. This way,
the above function would always return 900.
If such a function is to behave as it does in Maclisp, there is a subtle
issue having to do with the interaction between the interpreter and the
compiler: Should COMPILE reset the local state of such a function?
(In NIL and Zetalisp it doesn't, but one can imagine that a "digested"
copy of the original lambda expression might be cached by the interpreter,
and that the compiler uses the original unscathed version).