1

I have the following code:

let rand = System.Random()
let gold = [ for i in years do yield rand.NextDouble()]

However I cannot collapse it into one line as

let gold = [ for i in years do yield System.Random.NextDouble()]

Why?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
İrem Erten
  • 137
  • 1
  • 11
  • 3
    Because you need to create a random object - you could do `(System.Random()).NextDouble` but you would get the same answer every time – John Palmer Apr 25 '15 at 02:14
  • @JohnPalmer you would *probably* get the same answer every time. It stays the same unless the coarse-grained time used for seeding changes. Generally, the automatic seeding is not nice to rely on; it is neither sufficiently indeterministic nor deterministic. – Vandroiy Apr 25 '15 at 13:10
  • Combinators for generating random structures: https://gist.github.com/eulerfx/9808911 – eulerfx Apr 25 '15 at 14:54

3 Answers3

4

Your two code examples are not equivalent. The first one creates an object, and then repeatedly calls NextDouble() on that object. The second one appears to call a static method on the Random class, but I'd be surprised if it even compiles, since NextDouble() is not actually declared as static.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
4

You can combine the creation of the Random instance and its usage in a couple of ways, if desired:

let gold =
    let rand = Random()
    [for i in 1..10 do yield rand.NextDouble()]

or

let gold = let rand = Random() in [for i in 1..10 do yield rand.NextDouble()]
latkin
  • 16,402
  • 1
  • 47
  • 62
  • This is subtly dangerous. Try making three identical definitions `gold1` `gold2` and `gold3` in sequence: .NET's current implementation will probably yield at least two identical results. I would not advise to use more than one instance of `System.Random` – beginners will stumble over the seeding, and threaded programs that need multiple instances should really afford a better solution. (`System.Random` has some [quality issues](http://stackoverflow.com/a/6842191/4191347).) – Vandroiy Apr 25 '15 at 12:37
1

Most random numbers generated by computers, such as in the case of your code, are not random in the true sense of the word. They are generated by an algorithm, and given the algorithm and seed (like a starting point for the algorithm), deterministic.

Essentially, when you want a series of random numbers, you select a seed and an algorithm, and then that algorithm starts generating random numbers for you using the seed as the starting point and iterating he algorithm from there.

In the old days, people would produce books of "random numbers". These books used a seed and algorithm to produce the random series of numbers ahead of time. If you wanted a random number, then you would select one from the book.

Computers work similarly. When you call

Let rand = System.Random()

You are initializing the random number generator. It is like you are creating a book full of random numbers. Then to iteratively draw random numbers from the series, you do

rand.NextDouble()

That is like picking the first number from the series (book). Call it again and you pick the second number from the series, etc.

What is the point of F#/.NET having you initialize the random number generator? Well, what if you wanted repeatable results where the random series would contain the same numbers every time you ran the code? Well, doing it this way allows you to set the seed so you are guaranteed to have the same "book of random numbers" each time:

let rand = System.Random(1)

Or, what if you wanted to different series of random numbers?

let rand1 = System.Random(1)
let rand2 = System.Random(2)
nh2
  • 610
  • 3
  • 10