DELETE is destructive -- but not always? - common-lisp

I'm a little confused about Common Lisp's destructive DELETE function. It seems to work as expected, except for if the item is the first item on the list:
CL-USER> (defvar *test* (list 1 2 3))
*TEST*
CL-USER> (delete 1 *test*)
(2 3)
CL-USER> *test*
(1 2 3)
CL-USER> (delete 2 *test*)
(1 3)
CL-USER> *test*
(1 3)

Keep in mind that DELETE is supposed to work on the list, and not on a variable. DELETE gets passed the list (a pointer to the first cons) and not the variable.
Since delete does not have access to the variable *test*, it can't change it. 'It' here means its bindings. *test* will point to the same cons cell as before. The only thing that can be changed is the contents of the cons cell or the contents of other cons cells the first cons cell is pointing to.
One thing is sure, no matter what DELETE does, *test* will always point to the same cons cell.
What follows from that? If you want to have *test* point to the result of the delete operation, then you explicitly have to say so:
(setq *test* (delete 1 *test*))

"Destructive" does not mean "operates in place". It means that the structure of the value operated on might be modified in some arbitrary and often undefined way. This can in some instances, implementations and cases have an effect as if it was "in place". This can generally not be relied upon, however.
If you use a destructive operator, you are telling the compiler that you are not interested in the previous value of the variable after the operation is complete. You should assume that that value is garbled beyond recognition afterwards and not use it anymore. Instead, you should use the return value of the operation.
(let ((a (list 1 2 3)))
(let ((b (delete 2 a)))
(frob b))
a)
=> You were eaten by a grue.
If you are unsure of the safety of destructive operations, use their non-destructive counterparts (remove in this case).
(let ((a (list 1 2 3)))
(let ((b (remove 2 a)))
(frob b))
a)
=> (1 2 3)
If you really want to modify the contents of a variable, set them to the return value of the operation:
(let ((a (list 1 2 3)))
(setf a (delete 2 a))
a)
=> (1 3)

DELETE works by changing the CDR of the previous cons cell of the list to point to the one past the element(s) being deleted. But if you're deleting the first element of the list, there is no previous cons cell to modify.
Although this implementation isn't actually specified by the language standard, it's the way practically every implementation works.
Since there's no previous cons cell to modify when deleting the first element of the list, it simply returns the second cons cell. So even though DELETE is permitted to modify the list, you still must assign the result to your variable to handle this case. Also, it should be emphasized that destructive behavior is only allowed by the standard, not required. So there's a remote possibility that some implementation might not implement it destructively at all, and you must allow for that as well.
And even if DELETE worked by modifying CARs instead of CDRs, there's still a case that it can't do destructively: deleting all the elements of a list, e.g.
(setq *test* (list 'a 'a))
(delete 'a *test*)
This results in an empty list, i.e. NIL. But *test* still contains the cons cell that was the head of the original list, and there's no way for DELETE to change that. So you must do:
(setq *test* (delete 'a *test*))
to set *test* to NIL.

Related

Why mutating the list to be only its first element with this approach does not work in Common Lisp?

I am trying to learn Common Lisp with the book Common Lisp: A gentle introduction to Symbolic Computation. In addition, I am using SBCL, Emacs, and Slime.
By the end of chapter 10, on the advanced section there is this question:
10.9. Write a destructive function CHOP that shortens any non-NIL list to a list of one element. (CHOP '(FEE FIE FOE FUM)) should return
(FEE).
This is the answer-sheet solution:
(defun chop (x)
(if (consp x) (setf (cdr x) nil))
x)
I understand this solution. However, before checking out the official solution I tried:
(defun chop (xs)
(cond ((null xs) xs)
(t (setf xs (list (car xs))))))
Using this as a global variable for tests:
(defparameter teste-chop '(a b c d))
I tried on the REPL:
CL-USER> (chop teste-chop)
(A)
As you can see, the function returns the expected result.
Unfortunately, the side-effect to mutate the original list does not happen:
CL-USER> teste-chop
(A B C D)
Why it did not change?
Since I was setting the field (setf) of the whole list to be only its car wrapped as a new list, I was expecting the cdr of the original list to be vanished.
Apparently, the pointers are not automatically removed.
Since I have very strong gaps in low-level stuff (like pointers) I thought that some answer to this question could educate me on why this happens.
The point is about how parameters to functions are passed in Common Lisp. They are passed by value. This means that, when a function is called, all arguments are evaluated, and their values are assigned to new, local variables, the parameters of the function. So, consider your function:
(defun chop (xs)
(cond ((null xs) xs)
(t (setf xs (list (car xs))))))
When you call it with:
(chop teste-chop)
the value of teste-chop, that is the list (a b c d) is assigned to the function parameter xs. In the last line of the body of function, by using setf, you are assigning a new value, (list (car xs)) to xs, that is you are assigning the list (a) to this local variable.
Since this is the last expression of the function, such value is also returned by the function, so that the evaluation of (chop test-chop) returns the value (a).
In this process, as you can see, the special variable teste-chop is not concerned in any way, apart from calculating its value at the beginning of the evaluation of the function call. And for this reason its value is not changed.
Other forms of parameter passing are used in other languages, like for instance by name, so that the behaviour of function call could be different.
Note that instead, in the first function, with (setf (cdr x) nil) a data structure is modified, that is a part of a cons cell. Since the global variable is bound to that cell, also the global variable will appear modified (even if, in a certain sense, it is not modified, since it remains bound to the same cons cell).
As a final remark, in Common Lisp it is better not to modify constant data structures (like those obtained by evaluating '(a b c d)), since it could produce an undefined behaviour, depending on the implementation. So, if some structure should be modifiable, it should be built with the usual operators like cons or list (e.g. (list 'a 'b 'c 'd)).

SETQ or SETF With Defensive Copy

I am wondering about how one could do something as follows in Common Lisp. Suppose I have an object (entity) in memory that is unique at a certain time. What I would like to do is set some variable to be the state of that object, as snapshot at a certain time. The original entity may then evolve. However, I would like to make sure that the variable still points to the state of that entity in the past.
It appears that what I need is something along of the lines of a deep-copy + a setter. The complicating factor is that, at times, the nature of the entity is unknown. It may be an array or it may be a hashtable. It may likewise be an object.
Any advice is appreciated.
The only thing you need is immutable objects and only update the bindings. setq (and setf with a symbol as first argument) does this perfectly. Here are some examples:
(defparameter *test* '(1 2))
(defparameter *test2* *test*) ; a copy
(setf *test* (cdr *test*)) ; *test* is (2), but *test2* is still (1 2)
(defparameter *test3* *test*) ; a new copy
(setf *test* (cons 3 *test*)) ; *test* is (3 2), but *test2* is still (1 2) and *test3* is still (2)
push and pop does this for you. Here is the same code:
(defparameter *test* '(1 2))
(defparameter *test2* *test*) ; a copy
(pop *test*) ; *test* is (2), but *test2* is still (1 2)
(defparameter *test3* *test*) ; a new copy
(push 3 *test*) ; (3 2), but *test2* is still (1 2) and *test3* is still (2)
What I do not do here is (setf (car *test*) 3) since that mutates the object and all references will get the same object since they point at the object I changed.
So if you have some sort of state that is more complex, like a hash table, you would need to turn it into a tree so that you can change log(n) nodes per update and it will work in the same manner, that old references still have the same state.

Specification of conses

The Wikipedia-page about car and cdr says that a cons is a pair of pointers.
The following code seems to confirm that:
(progn
(setq a '(1 . 2))
(setq b a)
(setf (car b) 10)
(print a))
The evaluation of that form gives the cons (10 . 2). Setting the car of b changes the car of a. You can try that in the online repl at compileonline.com.
Where is that behavior defined in the Common Lisp specification?
(I've read some of the text but couldn't find the section pin-pointing that behavior.)
Interestingly the Wikipedia page on conses says "cons constructs memory objects which hold two values or pointers to values". If the atom 1 would directly be stored in the cons object then changing b wouldn't change a, would it?
I assume above that a and b hold the cons objects and not pointer to conses.
Even if the actual lisp implementation works with pointers this should not be visible on repl-level or should it according to the spec? One could achieve a similar effect when one assumes that a and b hold pointers that both point to the same cons.
Consing, i.e., the construction of lists through repeated application of cons, supports the assumption that conses are represented by pointers in symbol values.
The following two forms are equivalent:
(let ((a '(1)))
(setq b (cons 2 a)))
(setq b '(2 1))
Setting the car of b changes the car of a.
You are not setting the car of b. You are setting the car of the same cons cell which is referenced by b and a.
CL-USER 1 > (let (a b)
(setq a (cons 1 2))
(setq b a)
(eq a b))
T
Explanation:
we have variables a and b.
(cons 1 2) returns a cons cell
(setq a (cons 1 2)) sets a to the result of (cons 1 2), a cons cell.
(setq b a) evaluates a, which returns above cons cell and sets b to that cons cell.
The key to understand is that evaluation of variables and functions returns non-primitive (that is other than primitive numbers, characters, ...) objects as themselves - not as a copy.
I assume above that a and b hold the cons objects and not pointer to conses.
That's wrong. a and b are variables, which just point to both the same single cons cell.
"cons constructs memory objects which hold two values or pointers to values"
In a Common Lisp implementation something like small numbers (fixnums) might be stored directly in a cons cell. One can not reliably compare numbers by identity (using EQ) and has to do numeric comparison (EQL, =, ...).
OTOH, cons cells can't be stored inside cons cells and thus are referenced by pointers internally.
The operations you use:
SETQ : First form1 is evaluated and the result is stored in the variable var1. -> Notice how it says: result and not copy of the result.
RPLCA - this is what (setf CAR) actually uses. : rplaca replaces the car of the cons with object and The cons is modified -> thus it modifies the cons object it gets passed as an argument.
Evaluation - since you execute your code, the rules for evaluation apply.
Further useful to understand the execution model of Lisp:
An old Lisp book: 'Anatomy of LISP' by John Allen. (amazon)
A Scheme spec like R5RS.
Lisp in small pieces, a book explaining the execution models of Scheme/Lisp and their implementation.
First of all, your code is invalid because you're not allowed to modify constant lists. It should be:
(progn
(setq a (cons 1 2))
(setq b a)
(setf (car b) 10)
(print a))
When you perform an assignment like (setq b a), it sets the value of b to be the same as the value of a. The specification of SETQ says nothing about making a copy of the value, so the two variables contain the same value, which in this case is a cons cell.
Setting the car of that cons cell modifies that object -- again, there's no copying being done. So you'll see the change through any variable that refers to the cons cell, or any other reference (it could be in a structure slot, an array element, another cons cell, etc.).
I don't think the specification ever actually comes out and says that these things are all the same, it's just implicit in the fact that we're passing around abstract objects, and no copying is done unless you call a function that's explicitly defined to do so (e.g. COPY-TREE).
The specification doesn't talk about pointers, but that's generally what's going on under the covers. A cons cell is like a C structure:
typedef struct cons {
lisp_object car,
lisp_object cdr
} cons;
lisp_object would probably be a union of various types (some immediate types for things like FIXNUM, and pointers for other types). When a variable contains a cons, it actually contains a pointer to the above structure, and the assignment copies the pointer, not the structure. So the Lisp code is analogous to C code like:
cons *a = make_cons(1, 2);
cons *b = a;
b->car = 10;
printf("%d\n", a->car);

SICP 2.64 order of growth of recursive procedure

I am self-studyinig SICP and having a hard time finding order of growth of recursive functions.
The following procedure list->tree converts an ordered list to a balanced search tree:
(define (list->tree elements)
(car (partial-tree elements (length elements))))
(define (partial-tree elts n)
(if (= n 0)
(cons '() elts)
(let ((left-size (quotient (- n 1) 2)))
(let ((left-result (partial-tree elts left-size)))
(let ((left-tree (car left-result))
(non-left-elts (cdr left-result))
(right-size (- n (+ left-size 1))))
(let ((this-entry (car non-left-elts))
(right-result (partial-tree (cdr non-left-elts)
right-size)))
(let ((right-tree (car right-result))
(remaining-elts (cdr right-result)))
(cons (make-tree this-entry left-tree right-tree)
remaining-elts))))))))
I have been looking at the solution online, and the following website I believe offers the best solution but I have trouble making sense of it:
jots-jottings.blogspot.com/2011/12/sicp-exercise-264-constructing-balanced.html
My understanding is that the procedure 'partial-tree' repeatedly calls three argument each time it is called - 'this-entry', 'left-tree', and 'right-tree' respectively. (and 'remaining-elts' only when it is necessary - either in very first 'partial-tree' call or whenever 'non-left-elts' is called)
this-entry calls : car, cdr, and cdr(left-result)
left-entry calls : car, cdr, and itself with its length halved each step
right-entry calls: car, itself with cdr(cdr(left-result)) as argument and length halved
'left-entry' would have base 2 log(n) steps, and all three argument calls 'left-entry' separately.
so it would have Ternary-tree-like structure and the total number of steps I thought would be similar to 3^log(n). but the solution says it only uses each index 1..n only once. But doesn't 'this-entry' for example reduce same index at every node separate to 'right-entry'?
I am confused..
Further, in part (a) the solution website states:
"in the non-terminating case partial-tree first calculates the number
of elements that should go into the left sub-tree of a balanced binary
tree of size n, then invokes partial-tree with the elements and that
value which both produces such a sub-tree and the list of elements not
in that sub-tree. It then takes the head of the unused elements as the
value for the current node"
I believe the procedure does this-entry before left-tree. Why am I wrong?
This is my very first book on CS and I have yet to come across Master Theorem.
It is mentioned in some solutions but hopefully I should be able to do the question without using it.
Thank you for reading and I look forward to your kind reply,
Chris
You need to understand how let forms work. In
(let ((left-tree (car left-result))
(non-left-elts (cdr left-result))
left-tree does not "call" anything. It is created as a new lexical variable, and assigned the value of (car left-result). The parentheses around it are just for grouping together the elements describing one variable introduced by a let form: the variable's name and its value:
(let ( ( left-tree (car left-result) )
;; ^^ ^^
( non-left-elts (cdr left-result) )
;; ^^ ^^
Here's how to understand how the recursive procedure works: don't.
Just don't try to understand how it works; instead analyze what it does, assuming that it does (for the smaller cases) what it's supposed to do.
Here, (partial-tree elts n) receives two arguments: the list of elements (to be put into tree, presumably) and the list's length. It returns
(cons (make-tree this-entry left-tree right-tree)
remaining-elts)
a cons pair of a tree - the result of conversion, and the remaining elements, which are supposed to be none left, in the topmost call, if the length argument was correct.
Now that we know what it's supposed to do, we look inside it. And indeed assuming the above what it does makes total sense: halve the number of elements, process the list, get the tree and the remaining list back (non-empty now), and then process what's left.
The this-entry is not a tree - it is an element that is housed in a tree's node:
(let ((this-entry (car non-left-elts))
Setting
(right-size (- n (+ left-size 1))
means that n == right-size + 1 + left-size. That's 1 element that goes into the node itself, the this-entry element.
And since each element goes directly into its node, once, the total running time of this algorithm is linear in the number of elements in the input list, with logarithmic stack space use.

Permuting output of a tree of closures

This a conceptual question on how one would implement the following in Lisp (assuming Common Lisp in my case, but any dialect would work). Assume you have a function that creates closures that sequentially iterate over an arbitrary collection (or otherwise return different values) of data and returns nil when exhausted, i.e.
(defun make-counter (up-to)
(let ((cnt 0))
(lambda ()
(if (< cnt up-to)
(incf cnt)
nil))))
CL-USER> (defvar gen (make-counter 3))
GEN
CL-USER> (funcall gen)
1
CL-USER> (funcall gen)
2
CL-USER> (funcall gen)
3
CL-USER> (funcall gen)
NIL
CL-USER> (funcall gen)
NIL
Now, assume you are trying to permute a combinations of one or more of these closures. How would you implement a function that returns a new closure that subsequently creates a permutation of all closures contained within it? i.e.:
(defun permute-closures (counters)
......)
such that the following holds true:
CL-USER> (defvar collection (permute-closures (list
(make-counter 3)
(make-counter 3))))
CL-USER> (funcall collection)
(1 1)
CL-USER> (funcall collection)
(1 2)
CL-USER> (funcall collection)
(1 3)
CL-USER> (funcall collection)
(2 1)
...
and so on.
The way I had it designed originally was to add a 'pause' parameter to the initial counting lambda such that when iterating you can still call it and receive the old cached value if passed ":pause t", in hopes of making the permutation slightly cleaner. Also, while the example above is a simple list of two identical closures, the list can be an arbitrarily-complicated tree (which can be permuted in depth-first order, and the resulting permutation set would have the shape of the tree.).
I had this implemented, but my solution wasn't very clean and am trying to poll how others would approach the problem.
Thanks in advance.
edit Thank you for all the answers. What I ended up doing was adding a 'continue' argument to the generator and flattening my structure by replacing any nested list with a closure that permuted that list. The generators did not advance and always returned the last cached value unless 'continue' was passed. Then I just recursively called each generator until I got to the either the last cdr or a nil. If i got to the last cdr, I just bumped it. If I got to a NIL, I bumped the one before it, and reset every closure following it.
You'll clearly need some way of using each value returned by a generator more than once.
In addition to Rainer Joswig's suggestions, three approaches come to mind.
Caching values
permute-closures could, of course, remember every value returned by each generator by storing it in a list, and reuse that over and over. This approach obviously implies some memory overhead, and it won't work very well if the generated sequences can be infinite.
Creating new generators on each iteration
In this approach, you would change the signature of permute-closures to take as arguments not ready-to-use generators but thunks that create them. Your example would then look like this:
(permute-closures (list (lambda () (make-counter 3))
(lambda () (make-counter 3))))
This way, permute-closures is able to reset a generator by simply recreating it.
Making generator states copyable
You could provide a way of making copies of generators along with their states. This is kind of like approach #2 in that permute-closures would reset the generators as needed except the resetting would be done by reverting to a copy of the original state. Also, you would be able to do partial resets (i.e., backtrack to an arbitrary point rather than just the beginning), which may or may not make the code of permute-closures significantly simpler.
Copying generator states might be a bit easier in a language with first-class continuations (like Scheme), but if all generators follow some predefined structure, abstracting it away with a define-generator macro or some such should be possible in Common Lisp as well.
I would add to the counter either one of these:
being able to reset the counter to the start
letting the counter return NIL when the count is done and then starting from the first value again on the next call

Resources