Example Bizarre Listed From On Lisp

This excerpt from On Lisp really confused - it is not clear how returning a quoted list such as '(oh my) can actually change the way the function functions in the future: will the returned list be returned to the function again from scratch, on the next call?

If we define an exclamation so that its return value includes a quotation list,

 (defun exclaim (expression) (append expression '(oh my))) 

Then any subsequent destructive modification of the return value

 (exclaim '(lions and tigers and bears)) -> (LIONS AND TIGERS AND BEARS OH MY) (nconc * '(goodness)) -> (LIONS AND TIGERS AND BEARS OH MY GOODNESS) 

can change the list inside the function:

 (exclaim '(fixnums and bignums and floats)) -> (FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS) 

To exclaim against such problems, you should write:

 (defun exclaim (expression) (append expression (list 'oh 'my))) 

How exactly does the last exclaim call add the word goodness to the result? The function does not refer to any external variable, so how did a separate call to nconc really change the operation of the exclaim function?

+7
lisp common-lisp on-lisp
source share
1 answer

a) The effects of modifying undefined literal lists in the Lisp standard. What you see here as an example is one possible behavior.

(1 2 3 4) is a literal list. But calling LIST , as in (list 1 2 3 4) , returns a freshly linked list at run time.

b) a list is literal data in a function code. Each call will return this particular data object. If you want to provide a new list for each call, you need to use something like a LIST or a COPY LIST.

c) Since the returned list is always the same literal object, modifying it can have this effect, as described. It can also be assumed that an error occurred if the code and its objects were allocated in read-only memory. Then the list change will be attempted to be written to read-only memory.

d) One thing to keep in mind when working with list literal data in source code is this: the Lisp compiler can optimize storage. If the list has several times in the source code, the compiler is allowed to detect this and create only one list. Then all the different places pointed to this list. Thus, changing the list will result in these changes being visible in several places.

This can happen with other data objects such as arrays / vectors.

If your data structure is part of the code, you return this internal data structure, you change this data structure - then you are trying to change your code.

Note that Lisp can be executed by the interpreter. The interpreter usually works with the original Lisp structure - the code is not machine code, but is interpreted as Lisp as Lisp. Here you can change the source code at run time, not just the data embedded in the source code.

+8
source share

All Articles