newbie question

Started by nikus80, November 21, 2006, 10:06:40 AM

Previous topic - Next topic

nikus80

hi, I'm a newbie to lisp in general, though I know a few things about scheme and common lisp (I've read SICP, OnLisp, Practical Common Lisp, and Scheme The Programming Language, though I've finished none).

I still don't understand a few things about newLISP. But I've tried writing a few routines.

Now, this routine (which works in scheme, with a few variations) doesn't seem to work on newLISP. I'll need a lil' bit of help here.



(define (shuffle2 lst , acc)

   (set 'acc '())

   (dolist (e lst)

      (push e acc (rand $idx)))

   acc)

This is the shuffle routine. It receives a list and shuffles it (not the best algorithm ever, and I think it doesn't shuffle the first element, but it should work). I've tried to step over it, but I get nothing but errors about expecting a value "true". I've tried to rewrite it using a few different styles but it didn't work. What I'm missing?

Lutz

#1
when $idx is 0 then (rand 0) returns 'true'. When passing 0 'rand' initilaize the internal generator.



It works on 9.0.2 because $idx is broken on 9.0.2 starting with 1 instead of 0. But newLISP also has a randomize function doing the same:



> (randomize '(1 2 3 4 5))
(2 3 5 1 4)
> (randomize '(1 2 3 4 5))
(4 3 5 1 2)
> (randomize '(1 2 3 4 5))
(1 3 4 2 5)
>


Lutz

nikus80

#2
wow, thanks for the quick response.

But I think that (rand 0) should always return 0, and to restart the counter one should have to write (rand 'restart) or something like that, 'cause it could be useful, I think... Just an opinion (of course, I can always write my own rand...).

Of course in this case the actual function should be:



(define (shuffle2 lst , acc)

(set 'acc '())

(dolist (e lst)

(push e acc (rand (+ 1 $idx))))

acc)



BTW, I guess that thing about the broken $idx explains why I was debugging it once and it worked anyway.

cormullion

#3
Hi Nikus80, hope you're enjoying newLISP - you'll have to unlearn some of the other Lisps, but the ideas will be useful.



You were unlucky in accidentally trying (rand 0)... the only number that doesn't generate an integer!



On page 24 of the Introduction to newLISP, I wrote this:


(for (c 1 10)
  (push c number-list (rand 10))
  (println number-list))


which I thought - at the time - was interesting for two reasons: rand 10 doesn't cause an error, even when it produces an integer longer than the list, and you don't have to initialize number-list either.


(define (shuffle2 lst, acc)
(dolist (e lst)
(push e acc (rand (+ 1 $idx))))
acc)


For more shuffling, look at http://www.newlisp.org/index.cgi?anagrams_generator">//http://www.newlisp.org/index.cgi?anagrams_generator

nikus80

#4
I just thought (rand 0) returned 0. Actually (rand 1) always returns 0, so it could be argued it is the true base case.

That code seems fine, but I wonder how good it is at shuffling. For example, when you insert a 2, it is much more likely that you'll end up with (1 2) than with (2 1), which kinda retracts from its randomness.

I actually wrote a permutation algorithm when trying to solve a logic exercise of SICP without using the amb evaluator (note: it's nothing like the amb evaluator of newLISP). It was kinda different, of course. I'm having a hard time trying to figure out how the (anagrams) procedure works, I guess I'm not used to that idiom (one idiom I find very easy to understand is the common lisp (loop) macro, I don't know why... it's very un-newLISPy, but I think it rocks :)