number-sequence

From:

Luc Teirlinck

Subject:

number-sequence

Date:

Wed, 19 Nov 2003 21:39:16 -0600 (CST)

The function number-sequence in its present form is dangerous. If the
increment accidentally winds up being 0 or negative and FROM is less
than TO, Emacs will start to construct an infinite list and keep
chewing up CPU and worse, memory. Just try:
(number-sequence 1 3 -1) or (number-sequence 1 3 0)
If nothing else, if number-sequence can not handle negative increments
correctly, it should signal an error instead of trying to construct
the infinite sequence. However, I believe there is better. A zero
increment definitely should throw an error, except in some harmless
cases. If TO is less than FROM however, negative increments do make
perfect sense and they are trivial to handle. Hence, it seems stupid
to throw an error instead of doing the logical and expected thing.
The included version of number-sequence does that:
===File ~/number-sequence.el================================
(defun number-sequence (from &optional to inc)
"Return a sequence of numbers from FROM to TO (both inclusive) as a list.
INC is the increment used between numbers in the sequence.
So, the Nth element of the list is (+ FROM (* N INC)) where N counts from
zero.
If INC is nil, it defaults to 1 (one).
If TO is nil or numerically equal to FROM, return (FROM).
If INC is positive and TO is less than FROM, or INC is negative
and TO is larger than FROM, return nil.
If INC is zero and TO is neither nil nor numerically equal to
FROM, signal an error.
Note that FROM, TO and INC can be integer or float."
(if (or (not to) (= from to))
(list from)
(or inc (setq inc 1))
(when (zerop inc) (error "The increment can not be zero"))
(let (seq)
(if (> inc 0)
(while (<= from to)
(setq seq (cons from seq)
from (+ from inc)))
(while (>= from to)
(setq seq (cons from seq)
from (+ from inc))))
(nreverse seq))))
============================================================