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:
rand
Quick Overview
Description
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.
Example
(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).
-
No Arguments
(rand)
When no arguments are passed to
rand
, the max value defaults to 1 (exclusive).Ex:
(rand)
; => 0.6406672762806542
-
One Argument:
(rand n)
n is the max value (exclusive) and can be any number (e.g. integer, ratio, float).
Ex:
(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
Expanded Description
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 smpl-rand
.
(. 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 therandom
method from theMath
class. -
Math
Is a core Java language class. -
random
Is a method of the Java classMath
. It produces pseudorandom floats that are at least 0 but less than 1. It’s like usingrand
with n equal to 1.
More about random
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 Random
.
Reproducibility
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 generators/double
. 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 forrand
.
Copyright (C) 2016 Steven Cutting - License