Subject: Re: Lis(t|p) comprehensions
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 27 Jun 2006 04:01:36 -0500
Newsgroups: comp.lang.lisp
Message-ID: <1aqdnemWIpltbj3ZnZ2dnUVZ_uudnZ2d@speakeasy.net>
Frank Buss  <fb@frank-buss.de> wrote:
+---------------
| joswig@corporate-world.lisp.de wrote:
| > Often the function to generate integers from 0..n is called IOTA:
| > here is the definition from AIMA:
| > (defun iota (n &optional (start-at 0))
| >   "Return a list of n consecutive integers, by default starting at 0."
| >   (if (<= n 0) nil (cons start-at (iota (- n 1) (+ start-at 1)))))
| 
| This should be written in Common Lisp like this:
| (defun iota (n &optional (start-at 0))
|   "Return a list of n consecutive integers, by default starting at 0."
|   (when (> n 0) (cons start-at (iota (1- n) (1+ start-at)))))
+---------------

Personally, I prefer this version:

    (defun iota (count &optional (start 0) (step 1))
      (loop repeat count for i upfrom start by step collect i))

Besides the obvious uses:

    > (iota 5)

    (0 1 2 3 4)
    > (iota 5 3)

    (3 4 5 6 7)
    > (iota 5 3 3)

    (3 6 9 12 15)
    > 

it can be used for other things as well:

    > (iota 5 3 0)

    (3 3 3 3 3)
    > (iota 5 5 -1)

    (5 4 3 2 1)
    > 

Though note that these latter cases technically violate the CLHS
requirement that LOOP's BY prepositions's value be positive:

    6.1.2.1.1 The for-as-arithmetic subclause
    ...
    BY  The loop keyword BY marks the increment or decrement
	supplied by FORM3. The value of FORM3 can be any
	positive number. The default value is 1.

Both cases work in CMUCL & CLISP. Is there a CL implementation
that does *not* accept zero and/or negative BY values?


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607