rand - Clojure Standard Library
For a quick intro to this series of blog posts check out Clojure Standard Library - Intro. It includes a lot of useful info, including notes about presentation of examples and more.
This posts function:
clojure.core/rand returns a random floating point number between 0 and n. n defaults to 1. The floor (0) is inclusive, the ceiling (n) is exclusive.
(rand) ; => 0.9407334856674624 (rand 0.5) ; => 0.4980440876410518 (rand 100) ; => 89.32519939060609
How To Use
Parameters and Return Values
rand is a multiple-arity function – it can handle up to two parameters. It behaves differently based on the number of parameters (arity overloading).
When no arguments are passed to
rand, the max value defaults to 1 (exclusive).
(rand) ; => 0.6406672762806542
n is the max value (exclusive) and can be any number (e.g. integer, ratio, float).
(rand 1) ; => 0.2266087778297684 (rand 0.5) ; => 0.37420219989082226 (rand 0.0001) ; => 8.15349627855515E-6 (rand 1/10) ; ratio ; => 0.014023261151774514 (rand 100/10) ; ratio ; => 7.264691617874032 (rand 54) ; => 4.956227170370221
Examining Simplified Source Code
Below is a simplified version of the source code for
rand. This simplified version is called
smpl-rand and the main difference is that I’ve made it a single-arity function (vs multiple-arity) – it has only one parameter, meaning that it will only accept one argument. I made this change in order reduce the number of parts involved and to make it easier to understand. 1
(defn smpl-rand "Simplified version of rand." [n] (* n (. Math (random))))
Breaking It Down:
(* n (. Math (random)))
This expression multiplies the output of
(. Math (random)) by n – the argument supplied to
(. Math (random))
This is the part that actually produces the random number.
If you don’t care that much about where these random numbers come from then just read the
(. Math (random)) expression as
(some-java-thing-that-is-like-rand-with-no-arguments) and move along.
On the other hand if you do care about how the random numbers are produced, here is a quick explanation (that only goes as deep as the java definition):
.The dot is a special form that provides access to a method from a Java class. In this example the dot special form is used to access the
randommethod from the
MathIs a core Java language class.
The pseudorandom number generator used in
random only approximates a Uniform Distribution (UD). The below plot shows a histogram of a sample of 100,000 numbers (floats between 0.0 and 1.0) produced using
rand (blue bars) and a perfect UD (black line). The plot does a decent job of showing how the random number generator only approximates a UD. If it produced a perfect UD then the bars of the histogram would all align at 1.0, and they would perfectly fit the area under the UD curve (black line). Even thought it’s not perfect, it is good enough for most use cases. Do note that it is not suitably random for use in cryptography.
For more info on the algorithm used by
random to generate pseudorandom numbers, check out the Wikipedia page Linear congruential generator and the Java docs for the class
Reproducibility might be a must depending on whether you are needing to write tests or you are using clojure for science/data-analysis. If you do need reproducibility, consider using
double uses the same seed every time, so it always provides the same stream of pseudorandom numbers. Because it does use the same seed every time, be careful where you use this.
For reference here is a plot for
generators/double that is the same as the one above for
Copyright (C) 2016 Steven Cutting - License