[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).

	Tim McNerney