I need a short equivalent to (concatenate 'list (list a) b). RTFM does
not help.
alternatively if you want to append several items from a
list into another list use append...
(setf newlist (append list1 list2))
If you are getting construction problems and need to use
append for any reason then put youre item in a list i.e.
(setf newlist (append (list item) list1))
Hope this is helpfull
* Sent from AltaVista http://www.altavista.com Where you can also find related Web Pages, Images, Audios, Videos, News, and Shopping. Smart is Beautiful
(defun tappend (l1 l2)
((lambda (c)
(funcall c c l1 l2 ))
(lambda (c l1 l2)
(if (null l1)
l2
(cons (car l1)
(funcall c c (cdr l1) l2))))))
Is not really the answer.
There isn't really anything built in that does things any better than
what you seem to have discovered, although I could offer
(setq a (nconc a (list b)))
The real problem is that any such operation based on lists is fighting
against the lisp data representation. Lists are fundamentally serial
access data structures, so doing anything to the end of a list requires
traversing the entire list.
A data structure that is optimized for operations at both ends is called
a DEQUE and does not exists as a native Lisp type. One could build one
out of either Structs, Conses or CLOS objects. There may even be an
implementation of one in the Lisp archives.
Essentially what you would have to do is create a data structure with
both the list in it, as well as a pointer to the last cons cell of the
list. That allows you to do the RPLACD without having to follow the
list all the way to its end:
(let ((newcons (list b)))
(rplacd <ptr-to-last-cons> newcons)
(setq <ptr-to-last-cons> newcons))
--
Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu
>I need a short equivalent to (concatenate 'list (list a) b). RTFM does
>not help.
Sorry, i RTFM too much and make a mistake. Actually i need something
like push, but unlike push it have to insert new item to the end of
list. So, i need an equivalent to
>> I need a short equivalent to (concatenate 'list (list a) b). RTFM does
>> not help.
>
>(defun tappend (l1 l2)
> ((lambda (c)
> (funcall c c l1 l2 ))
> (lambda (c l1 l2)
> (if (null l1)
> l2
> (cons (car l1)
> (funcall c c (cdr l1) l2))))))
Is it usual lisp programming style ?!
No, it's an entry for the Obfuscated Lisp Programming
Contest :-)
--
Raymond Wiker, Orion Systems AS
+47 370 61150
Norvig and Russell's Paradigms of AI Programming provides an implementation
of list-based queues. It can be found at:
<http://www.norvig.com/paip/auxfns.lisp>
It provides the following functions:
(queue-contents q) -> contents of queue
(make-queue) -> q "Build a new queue, with no elements."
(enqueue item q) -> q "Insert item at the end of the queue."
(dequeue q) -> q "Remove an item from the front of the queue."
(front q) -> item "First object in queue, or NIL"
(empty-queue-p q) -> boolean "Is queue empty?"
(queue-nconc q list) "Add the elements of LIST to the end of the queue."
if you don't need a list, consider VECTOR-PUSH.
| So, i need an equivalent to
|
| (setq a (concatenate 'list a (list b)))
(append a (list b))
| (rplacd (last a) (list b))
(setf (setf tail (cdr tail)) (cons b nil))
is better, once you keep two variables to point into the list:
(setf tail (cons nil nil))
(setf head (cdr tail))
you might want to do this in a structure or class to capture it in a
unit, but most of the time, you can use this technique in a short piece
of code without the overhead of extra datatypes and their accessors.
however, the most common way to do this is to collect the items in a list
in reverse, and then reverse the list (destructively, with NREVERSE).
this won't work if you need access to the list elements along the way, in
which case only the HEAD/TAIL approach outlined above will do.
#:Erik
Use push and then nreverse the list when you're finished adding items;
that's the usual idiom. Alternatively you could use vectors instead of
lists and, if memory serves, vector-push-extend. Or use map or a for
loop with a collect to form the list.