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.