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.
Related
After googling for about an hour, I have to confess, that while I find a lot of documentation about functions operating on bit arrays, I cannot find a single reference on how to actually create a bit array.
Right now, it seems to me that either, some arrays with other element types can be handled as bit arrays OR that one could use (make-array :element-type (???)) where I could not find any explanation as to what to put where I wrote the "???".
So, while it is probably obvious to anyone else, I have no idea how to create a bit array. I know about how to write a literal bit array - but if I need a bit array with, say 2^16 bits - how would I do it?
You are right about using make-array, just use 'bit as the element type. Try
(make-array initial-size :element-type 'bit).
The symbol BIT names the bit type and could be replaced with any other type specifier to make an array holding objects of that type. In this example initial-size is just a variable holding a whole number.
Another way to create a bit vector:
> (make-sequence '(vector bit) 10)
#*0000000000
There's also a literal syntax using the #* reader macro, and notice that the concrete type may differ between using make-array and make-sequence, though I am not sure if performance may be different depending on that...
Tested with SBCL:
CL-USER> (defvar arr (make-array 10 :element-type 'bit :fill-pointer 0))
ARR
CL-USER> (type-of arr)
(VECTOR T 10)
CL-USER> (defvar arr3 (make-sequence '(vector bit) 10))
ARR3
CL-USER> (type-of arr3)
(SIMPLE-BIT-VECTOR 10)
CL-USER> (type-of #*0101010100)
(SIMPLE-BIT-VECTOR 10)
How about this:
(setq x 10)
10
(setq y (read-from-string (format nil "#*~7,'0b" x)))
#*0001010
The 7 is an arbitrary length, which could be set by
(setq z 8)
8
(setq y (read-from-string (format nil (concatenate 'string "#*~" (write-to-string z) ",'0b") x)))
#*00001010
A large bit array may be better handled as an unsigned integer.
I've written two versions of a lisp function. The main difference between the two is that one is done with recursion, while the other is done with iteration.
Here's the recursive version (no side effects!):
(defun simple-check (counter list)
"This function takes two arguments:
the number 0 and a list of atoms.
It returns the number of times the
atom 'a' appears in that list."
(if (null list)
counter
(if (equal (car list) 'a)
(simple-check (+ counter 1) (cdr list))
(simple-check counter (cdr list)))))
Here's the iterative version (with side effects):
(defun a-check (counter list)
"This function takes two arguments:
the number 0 and a list of atoms.
It returns the number of times the
atom 'a' appears in that list."
(dolist (item list)
(if (equal item 'a)
(setf counter (+ counter 1))
(setf counter (+ counter 0))))
counter)
As far as I know, they both work. But I'd really like to avoid side-effects in the iterative version. Two questions I'd like answered:
Is it possible to avoid side effects and keep iteration?
Assuming the answer to #1 is a yes, what are the best ways to do so?
For completeness, note that Common Lisp has a built-in COUNT:
(count 'a list)
In some ways, the difference between side-effect or no side-effect is a bit blurred. Take the following loop version (ignoring that loop also has better ways):
(loop :for x :in list
:for counter := (if (eq x 'a) (1+ counter) counter)
:finally (return counter))
Is counter set at each step, or is it rebound? I. e., is an existing variable modified (like in setf), or is a new variable binding created (as in a recursion)?
This do version is very much like the recursive version:
(do ((list args (rest list))
(counter 0 (+ counter (if (eq (first list) 'a) 1 0))))
((endp list) counter))
Same question as above.
Now the “obvious” loop version:
(loop :for x :in list
:count (eq x 'a))
There isn't even an explicit variable for the counter. Are there side-effects?
Internally, of course there are effects: environments are created, bindings established, and, especially if there is tail call optimization, even in the recursive version destroyed/replaced at each step.
I see as side effects only effects that affect things outside of some defined scope. Of course, things appear more elegant if you can also on the level of your internal definition avoid the explicit setting of things, and instead use some more declarative expression.
You can also iterate with map, mapcar and friends.
https://lispcookbook.github.io/cl-cookbook/iteration.html
I also suggest a look at remove-if[-not] and other reduce and apply:
(length (remove-if-not (lambda (x) (equal :a x)) '(:a :b :a))) ;; 2
Passing counter to the recursive procedure was a means to enable a tail recursive definition. This is unnecessary for the iterative definition.
As others have pointed out, there are several language constructs which solve the stated problem elegantly.
I assume you are interested in this in a more general sense such as when you cannot find
a language feature that solves a problem directly.
In general, one can maintain a functional interface by keeping the mutation private as below:
(defun simple-check (list)
"return the number of times the symbol `a` appears in `list`"
(let ((times 0))
(dolist (elem list times)
(when (equal elem 'a)
(incf times)))))
Imagine I have a class:
(defclass person () ())
And then I make some instances:
(setf anna (make-instance 'person))
(setf lisa (make-instance 'person))
How can I get either the objects themselves or the symbol names they were assigned to?
I want to be able to say something like (find-instances 'person) and get something like (anna lisa) or at least (#<PERSON {100700E793}> #<PERSON {100700E793}>).
What I am search for is the equivalent of each_object in ruby.
I very much want to be able to do it without an external library.
There is nothing like that built-in in Common Lisp.
Recording instances
For finding all instances of a class, one would usually make it that the class records the instance upon instance creation. One can imagine various mechanisms for that. Sometimes one would still want instances to be garbage collected - then one needs some kind of non-standard weak datastructure to do so. I would expect, that there are some libraries which implement similar things for CLOS instances.
Iterating over symbols of a package
If you would like to know which symbols of some or all packages have CLOS instances as a value, you could iterate over them (DO-SYMBOLS, DO-ALL-SYMBOLS, ...) and check if the have a symbol value and if that symbol value is an instance of a certain class.
There is no portable solution for this, as far as I know. If you are working on CCL, then map-heap-objects may do, what you are looking for
(defclass foo () ())
(defvar *x* (make-instance 'foo))
(defvar *y* (list (make-instance 'foo)))
(defun find-instances (n class)
(let ((buffer (make-array n :fill-pointer 0 :initial-element nil)))
(ccl:map-heap-objects (lambda (x)
(when (and (typep x class) (< (fill-pointer buffer) n))
(setf (aref buffer (fill-pointer buffer)) x)
(incf (fill-pointer buffer)))))
buffer))
(find-instances 2 'foo)
==> (#<FOO #x30200126F40D> #<FOO #x30200126634D>)
Similar solutions may exist for other Common Lisp implementations. Note, that you have to have an initial hunch as to how many instances the traversal may find. The reason is, that (as Rainer Joswig noted), the callback function should avoid consing. In order to achieve that, this implementation allocates a buffer up-front, and collects at most that many instances.
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.
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.