# reversed and copied lists

• From: Boruch Baum <boruch_baum@xxxxxxx>
• Date: Mon, 18 Feb 2019 05:27:33 -0500
• X-ml-name: emacs-w3m
• X-mail-count: 13188

```I decided to scan the code for unnecessary nreverse operations, and came
acrosss a situation that looks ripe for taking an axe to, but I wasn't
sure if there wasn't some subtle lisp consequence that I was missing.
Even after performing some tests, I'm still not confident in myself, so
I thought to share it on the list for feedback, and maybe improve my
lisp abilities.

The function in question is:

(defun w3m-sub-list (list n)
"Return a list of the first N elements of LIST.
If N is negative, return a list of the last N elements of LIST."
(if (integerp n)
(if (< n 0)
;; N is negative, extract the last items
(if (>= (- n) (length list))
(copy-sequence list)
(nthcdr (+ (length list) n) (copy-sequence list)))
;; N is positive, extract the first items
(if (>= n (length list))
(copy-sequence list)
(nreverse (nthcdr (- (length list) n) (reverse list)))))
(copy-sequence list)))

What seems to me more sensible is:

(defun w3m-sub-list (list n)
"Return a list of the first N elements of LIST.
If N is negative, return a list of the last N elements of LIST."
(if (integerp n)
(cond
((< n 0)
(last list (- n)))
((> n 0)
(butlast list (- (length list) n)))
(t list))
list))

Here are some basic tests:

(w3m-sub-list '(a b c d e f g) 4)
(w3m-sub-list '(a b c d e f g) -4)
(w3m-sub-list '(a b c d e f g) t)
(w3m-sub-list '(a b c d e f g) nil)
(w3m-sub-list '(a b c d e f g) 12)
(w3m-sub-list '(a b c d e f g) -12)

BTW, there's a bug in the original version when n=0
(w3m-sub-list '(a b c d e f g) 0)

What's bothering me is the documentation for function copy-sequence
which seems unclear to me whether it really is creating a copy or just
another symbol pointing to the same objects.

"Return a copy... are not copied; they are shared...
may return the same empty object instead of its copy"

So I tried a few attempts at destructive tests:

(let ((this '(a b c d e f g)) that)
(setq that
(prog1
(last this 12)
(setq this nil)))
(setq this "aa")
that)
(let ((this '(a b c d e f g)) that)
(setq that
(prog1
(copy-sequence this)
(setq this nil)))
(push "aa" this)
that)

And some attempts at destructive tests, using w3m-sub-list:

(let ((this '(a b c d e f g)) that)
(setq that (w3m-sub-list this 4))
(setq this nil)
that)
(let ((this '(a b c d e f g)) that)
(prog1
(setq that (w3m-sub-list this 4))
(setq this nil)))

In any case, there is the n=0 bug to address.

--
hkp://keys.gnupg.net
CA45 09B5 5351 7C11 A9D1  7286 0036 9E45 1595 8BC0
```

• Namazu Search: [Help]