Some very non-random Lisp
For a long time, I've had this nagging feeling that I should invest some time into learning Lisp. More and more I've been noticing posts on reddit talking about how great a language it is, and how much more productive it is than pretty much any other language. Well, I'm not sure about that; there are a lot of great languages and it's your familiarity with it that makes you productive. But anyway, I'm not a complete novice having done plenty of work with Monk (SeeBeyond's proprietary Scheme implementation from some years back) and I understand the basic concepts and know that it can be used to produce some really elegant code.
So I armed myself with a couple of good books and found some little projects to work on.
Last night I came across a bit of a shocker.
I have a need to generate a short sequence of random numbers. Lisp has a function for generating them. Perfect. Hmmm. Not quite.
Here's a bit of code to print 5 random numbers between 0 and 9. There's nothing complicated about it.
(dotimes (x 5) (print (random 10)))
Feeding this short program into GNU Common Lisp produces the following output:
2
2
4
5
3
So far, so good. Let's run the program again and see what random numbers it comes up with this time:
2
2
4
5
3
Wait a minute... didn't it print those the last time?
OK, so maybe there's something I'm missing. Off I go into the Common Lisp specification. A-ha! There's a global variable called *random-state* which acts as the seed. Promising. But there's no function for setting it to some other value and its structure is implementation-dependent so if you did manage to hack its internal structure directly, you would end up with something non-portable.
The specification does acknowledge this but defends it by saying that "there is no simple way to guarantee that any user-specified seed value will be random enough."
In other words, Lisp knows better than you what you want. Then it goes on to say that to avoid repeated invocations of the same program producing the same values, you should write the *random-state* variable to a file periodically and read it in again every time the program starts. Really? I don't recall ever having to do that in any other programming language.
Now I don't know about you, but I still don't think what Lisp calls random is in fact random. I call it predictable.
(setf *random-state* (make-random-state t))
Posted by foo on June 27, 2008 at 01:58 PM BST #
OK - you got me. I'm going back to my books :-)
Posted by AdamT on June 27, 2008 at 02:59 PM BST #
Now I feel so reassured that we have such enlightened individuals in tha FAST team...
Posted by sys on August 08, 2008 at 05:21 PM BST #
But you often WANT the random state to start the same at every program invocation. Your premise of correctness at "Wait a minute... didn't it print those the last time?" is faulty.
Suppose you run a Monte Carlo simulation several times. To see what difference code changes make, it's essential to use the same random series. Lisp's default behavior is good!
Although you can re-seed as pointed out by foo.
Posted by Ron Dom on September 12, 2009 at 12:24 AM BST #