From: Huy V. Le
Subject: How can I swap?
Date: 
Message-ID: <01bd3fb7$60e494c0$a6f360cf@le>
I'm looking to find an efficient way to swap two entries of a list with 
Allegro CL 4.2

For example, given the following list, (a b c d), swap 1th entry with 3rd
entry will give me (a d c b).

Sincerely,

Huy.

From: Barry Margolin
Subject: Re: How can I swap?
Date: 
Message-ID: <xK$H.1$nf2.268727@cam-news-reader1.bbnplanet.com>
In article <··························@le>,
Huy V. Le <······@horslimites.qc.ca> wrote:
>For example, given the following list, (a b c d), swap 1th entry with 3rd
>entry will give me (a d c b).

(rotatef (nth 1 list) (nth 3 list))

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.
From: David D. Smith
Subject: Re: How can I swap?
Date: 
Message-ID: <dds-0403980252020001@p66.bit-net.com>
In article <··························@le>, "Huy V. Le"
<······@horslimites.qc.ca> wrote:

> I'm looking to find an efficient way to swap two entries of a list with 
> Allegro CL 4.2
> 
> For example, given the following list, (a b c d), swap 1th entry with 3rd
> entry will give me (a d c b).

? ((lambda (x) (rotatef (nth 1 x) (nth 3 x)) x) '(a b c d)) 
(A D C B)
? 

d
From: Kent M Pitman
Subject: Re: How can I swap?
Date: 
Message-ID: <sfwogzdwuwe.fsf@world.std.com>
···@flavors.com (David D. Smith) writes:

> 
> In article <··························@le>, "Huy V. Le"
> <······@horslimites.qc.ca> wrote:
> 
> > I'm looking to find an efficient way to swap two entries of a list with 
> > Allegro CL 4.2
> > 
> > For example, given the following list, (a b c d), swap 1th entry with 3rd
> > entry will give me (a d c b).
> 
> ? ((lambda (x) (rotatef (nth 1 x) (nth 3 x)) x) '(a b c d)) 
> (A D C B)
> ? 

This is concise but not necessarily as efficient as it could be.  For
many situations, the above may be fine; but if the list is long and
the indices are large and performance is critical, it's best not to
traverse the tails twice if you don't have to, and ROTATEF is not
obliged to be smart about that.  Something like the following (only
very lightly tested; use at own risk) is the kind of thing that's more
efficient...

 (defun swap-elts (L i j)
   (unless (= i j)
     (when (> i j) (rotatef i j))
       (let* ((taili (nthcdr i L))
	      (tailj (nthcdr (- j i) taili)))
         (unless tailj 
	   (error "Index out of range: ~D" (if taili j i)))
	 (rotatef (car taili) (car tailj))
	 t)))

This also doesn't try the swap (and doesn't notice length overruns)
when the indexes are the same.  That may or may not be a feature 
for any given application.

(Personally, I think it's unfortunate that NTH is SETFable.
Not only does it lead one to set it without thinking of the
efficiency issues in finding and holding the cell for other
uses, but it also has the problem of CDR'ing off the end.)