From: NS
Subject: random-list function
Date: 
Message-ID: <39D7F19D.D7A26A57@aol.com>
Hi,
I hope you all don't mind sparing your time looking at my code here:

(defun random-list (len range)
 (let ((lst (make-lst len)))
           (fill-random-list (lst range)))
(defun fill-random-list (lst range)
      (if (null lst)
          nil
          (progn
              (setf (first lst) (random range))
              (fill-random-list (rest lst) range))))

So far, a couple of very cool Lisp programmers from this news group
showed me much more efficient ways to do it (and I also would like to
acknowledge them here).  I would like to see more coding "styles" from
the Lisp gurus out there.  This will help my learning a lot.

Thanks in advance,
Shen

From: David Bakhash
Subject: Re: random-list function
Date: 
Message-ID: <c297l7s0wtb.fsf@nerd-xing.mit.edu>
NS <···········@aol.com> writes:

> Hi,
> I hope you all don't mind sparing your time looking at my code here:
> 
> (defun random-list (len range)
>  (let ((lst (make-lst len)))
>            (fill-random-list (lst range)))
                               ^^^^^^^^^^^

is `lst' a function?  If not, this is wrong.  But let's assume you
meant:

(fill-random-list last range)

> (defun fill-random-list (lst range)
>       (if (null lst)
>           nil
>           (progn
>               (setf (first lst) (random range))
>               (fill-random-list (rest lst) range))))
> 

how about:

(defun random-list (len range)
  (loop
    repeat len
    collect (random range)))

is that what your function wants to do?

dave
From: Coby Beck
Subject: Re: random-list function
Date: 
Message-ID: <9aUB5.97399$47.1199257@news.bc.tac.net>
"NS" <···········@aol.com> wrote in message
······················@aol.com...
> Hi,
> I hope you all don't mind sparing your time looking at my code here:
>
> (defun random-list (len range)
>  (let ((lst (make-lst len)))
>            (fill-random-list (lst range)))
> (defun fill-random-list (lst range)
>       (if (null lst)
>           nil
>           (progn
>               (setf (first lst) (random range))
>               (fill-random-list (rest lst) range))))
>

Small point:
       (if (null lst)
           nil
           (progn
               (setf (first lst) (random range))
               (fill-random-list (rest lst) range))))

might be more clearly expressed:
       (when lst
               (setf (first lst) (random range))
               (fill-random-list (rest lst) range))))

Coby
From: Erik Naggum
Subject: Re: random-list function
Date: 
Message-ID: <3179472571310961@naggum.net>
* NS <···········@aol.com>
| So far, a couple of very cool Lisp programmers from this news group
| showed me much more efficient ways to do it (and I also would like
| to acknowledge them here).  I would like to see more coding "styles"
| from the Lisp gurus out there.  This will help my learning a lot.

  It might also help your learning process to explain why you did what
  you did.  For instance, why pre-allocate the list, then fill it?
  Why use a recursive helper function to traverse (create) a list?
  Why name your variable "lst"?  (Some of these indicate a Scheme
  background, specifically one that tried to highlight difference
  between Scheme and "all other" languages, but which failed to
  communicate that you can write more "normal" code in Scheme, too.)

  As long as you want recursion, here's one for educational purposes:

(defun random-list (length range)
  (if (plusp length)
      (cons (random range) (random-list (1- length) range))
    nil))

  It might help your learning process to explain why this is insane for
  production purposes.

  You can solve the problem in many different ways, obviously, but I
  favor those that require a minimum of my own code, i.e., that use
  the rich language that is Common Lisp to its fullest, hoping for (or
  counting on) very efficient, error-free implementations of the
  functions specified in the language.

(mapcar #'random (make-list length :initial-element range))

  If you don't intend to call random-list a lot or with huge values of
  length, you won't notice the double space requirements of this one.

  Incidentally, your version with "fill" is very similar to what
  Common Lisp calls "map-into", which saves on the space usage:

(let ((list (make-list length :initial-element range)))
  (map-into list #'random list))

#:Erik
-- 
  If this is not what you expected, please alter your expectations.
From: Colin Walters
Subject: Re: random-list function
Date: 
Message-ID: <87wvfreuau.church.of.emacs@meta.verbum.org>
How about:

(defun random-list (len range)
  (let ((result '()))
    (dotimes (i len result)
      (push (random range) result))))
From: Thomas A. Russ
Subject: Re: random-list function
Date: 
Message-ID: <ymiwvfo45ti.fsf@sevak.isi.edu>
NS <···········@aol.com> writes:

> 
> Hi,
> I hope you all don't mind sparing your time looking at my code here:
> 
> (defun random-list (len range)
>  (let ((lst (make-lst len)))
>            (fill-random-list (lst range)))
> (defun fill-random-list (lst range)
>       (if (null lst)
>           nil
>           (progn
>               (setf (first lst) (random range))
>               (fill-random-list (rest lst) range))))


Well, for starters, the style of this is much more C-like than
Lisp-like.  The main tipoff is that one generally does not create lists
in Lisp and then destructively modify them to fill them.  The standard
way of doing this would be to construct the list element by element and
then just return the result.

David Bakhash provided the simplest LOOP-based result.  I can offer to
other possibilities:

;; Recursive:

(defun random-list (len range)
  (if (< len 1)
      nil
      (cons (random range) (random-list (- len 1) range))))

;; Tail Recursive:

(defun random-list (len range)
  (random-list-tr len range nil))

(defun random-list-tr (len range result)
  (if (< len 1)
      result
      (random-list-tr (- len 1) range (cons (random range) result))))

;; Iterative

(defun random-list (len range)
  (let ((result nil))
    (dotimes (i len)
	(push (random range) result))
    result))
        

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Tim Bradshaw
Subject: Re: random-list function
Date: 
Message-ID: <ey37l7n4lth.fsf@cley.com>
* Thomas A Russ wrote:

> Well, for starters, the style of this is much more C-like than
> Lisp-like.  The main tipoff is that one generally does not create lists
> in Lisp and then destructively modify them to fill them.  The standard
> way of doing this would be to construct the list element by element and
> then just return the result.


Just to be perverse, there are a couple of reasons why the
create-then-modify-the-cars approach might be good for large lists:

* in a cdr-coded implementation you use half the storage (but there
  probably aren't many of those now)

* the list will be localised in memory (but the GC will probably
  localise it on the first copy anyway, *however* the GC may have to
  do more work to localise it -- chasing random pointers causing possible cache
  thrashing &c -- and if it;'s a really large object you may be
  arranging life such that the GC never touches it).

On the other hand creating the object then modifying it requires two
walks through memory, whereas creating it right requires only one.

--tim