[emacs-w3m:13188] reversed and copied lists

Boruch Baum <[email protected]>
Newsgroups gmane.emacs.w3m
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.