I am learning Elisp by reading others' code. Then I found people use both delete and remove to delete element from sequence. I checked the document and the code of remove it seams just a wrapper for delete which when the sequence is a list, do a copy-sequence.
Is it really matter to copy list to do the delete? Or I can just use delete which is a C command which should be more efficient I think.
remove returns
a copy of seq with all occurrences of elt removed.
whereas delete
delete[s] by side effect any occurrences of elt as a member of seq.
so it modifies the original sequence. (Unless the first element is a hit, so pleasee consult C-hf delete for full details.)
Related
Hi I am trying append a simple element to a lisp list.
(append queue1 (pop stack1))
I thought the above code would append the first element of stack1 to queue1. Does queue1 need to be non nil? Thanks.
Append returns the concatenated list (queue1 with the first element of stack1 appended). It does not modify queue1.
The destructive equivalent of append is nconc: this appends to the list "in place."
You did not specify which Lisp do you mean, but in Common Lisp at least:
APPEND concatenates lists, so all its arguments has to be lists, not atoms. If you really wanted to append an element to the list you would have to do (append list1 (list element)). This is not a good idea because in most Lisps lists are single linked, and an entire list will have to be traversed to append to the end. Usually one would append to the front with CONS and then reverse the list when done, but this obviously will not work for queues.
APPEND does not modify its arguments. NCONC is a destructive function. While I believe that NCONC in particular is specified to do more or less what one would expect, most destructive functions are allowed to destroy their arguments, to reuse their memory, but no necessarily leave anything coherent behind.
Lists in Common Lisp are implemented as chains of cons cells or nil, which means that their behaviour has some quirks relating to the latter. If you want a list acting more as you would expect from other languages then use a list abstract data structure. More so if you want a queue with constant append to the end. There are many imperative data structures available in cl-containers system, and functional data structures in FSet.
In all the docs I'm reading about org mode it seems that numbered lists will auto number when moving to next list item but it seems that I can't trigger it. So, I'm not understanding how [#50] (to start at 50 instead of 1) works.
Am I just missing some thing about numbered lists?
Assuming that org mode is in fact enabled (either with editing a file with the .org extension, or by manually triggering it with org-mode), you can auto-increment a numbered list by hitting M-<RET> after a list item.
1. First entry (M-<RET>)
2.
Edit: Looking back, seems I may have misunderstood your question. This is how to trigger the autoincrementing of the list items, but are you instead asking how to start at number other than 1?
(Keeping this as an answer because it does provide a solution, at least to the assumed question.)
This passage from On Lisp is genuinely confusing -- it is not clear how returning a quoted list such as '(oh my) can actually alter how the function behaves in the future: won't the returned list be generated again in the function from scratch, the next time it is called?
If we define exclaim so that its return value
incorporates a quoted list,
(defun exclaim (expression)
(append expression ’(oh my)))
Then any later 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)
could alter the list within the function:
(exclaim ’(fixnums and bignums and floats))
-> (FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS)
To make exclaim proof against such problems, it should be written:
(defun exclaim (expression)
(append expression (list ’oh ’my)))
How exactly is that last call to exclaim adding the word goodness to the result? The function is not referencing any outside variable so how did the separate call to nconc actually alter how the exclaim function works?
a) the effects of modifying literal lists is undefined in the Common Lisp standard. What you here see as an example is one possible behavior.
(1 2 3 4) is a literal list. But a call to LIST like in (list 1 2 3 4) returns a freshly consed list at runtime.
b) the list is literal data in the code of the function. Every call will return exactly this data object. If you want to provide a fresh list on each call, then you need to use something like LIST or COPY-LIST.
c) Since the returned list is always the same literal data object, modifying it CAN have this effect as described. One could imagine also that an error happens if the code and its objects are allocated in a read-only memory. Modifying the list then would try to write to read-only memory.
d) One thing to keep in mind when working with literal list data in source code is this: the Lisp compiler is free to optimize the storage. If a list happens to be multiple times in the source code, a compiler is allowed to detect this and to only create ONE list. All the various places would then point to this one list. Thus modifying the list would have the effect, that these changes could be visible in several places.
This may also happen with other literal data objects like arrays/vectors.
If your data structure is a part of the code, you return this internal data structure, you modify this data structure - then you try to modify your code.
Note also that Lisp can be executed by an Interpreter. The interpreter typically works on the Lisp source structure - the code is not machine code, but interpreted Lisp code as Lisp data. Here you might be able to modify the source code at runtime, not only the data embedded in the source code.
I'm trying to implement a Towers of Hanoi recursively with Common Lisp. I know what the recursive calls are and how they work, but I'm just lost with how I would go about moving something from the end of one list, to the end of another list. I was trying to do some research on how to do this, but I couldn't find anything online.
Any help would be greatly appreciated.
Thanks!
You can remove the last element of a list with butlast, get last element with last, and you cat append a list to another list with append (you just cons your element to be added so that it's a one element list). Working on the end of lists in CL are not optimal as every function needs to traverse the list in order to find the last one, but it is done when you need to add/remove in both ends.
With Tower of Hanoi you are stacking disks on top of each other and the last one put is the first one out. In Common Lisp (in fact any Lisp cousin) you can easily add to front and remove from front with doing (cdr pole-a) in the recursive call to remove the top element from pole-a and add to pole-b with (cons (car pole-a) pole-b) in the recursive call.
I imagine you need this to actually be able to see which disk is moved in each stage, since you need no such structure to calculate the moves needed. In such a scenario you only need the names of the poles and the level the recursion and the number of disks you want to move in this round.
Hi I am trying append a simple element to a lisp list.
(append queue1 (pop stack1))
I thought the above code would append the first element of stack1 to queue1. Does queue1 need to be non nil? Thanks.
Append returns the concatenated list (queue1 with the first element of stack1 appended). It does not modify queue1.
The destructive equivalent of append is nconc: this appends to the list "in place."
You did not specify which Lisp do you mean, but in Common Lisp at least:
APPEND concatenates lists, so all its arguments has to be lists, not atoms. If you really wanted to append an element to the list you would have to do (append list1 (list element)). This is not a good idea because in most Lisps lists are single linked, and an entire list will have to be traversed to append to the end. Usually one would append to the front with CONS and then reverse the list when done, but this obviously will not work for queues.
APPEND does not modify its arguments. NCONC is a destructive function. While I believe that NCONC in particular is specified to do more or less what one would expect, most destructive functions are allowed to destroy their arguments, to reuse their memory, but no necessarily leave anything coherent behind.
Lists in Common Lisp are implemented as chains of cons cells or nil, which means that their behaviour has some quirks relating to the latter. If you want a list acting more as you would expect from other languages then use a list abstract data structure. More so if you want a queue with constant append to the end. There are many imperative data structures available in cl-containers system, and functional data structures in FSet.