Skip to main content

make-random-state

make-random-state Function

Syntax:

make-random-state &optional state → new-state

Arguments and Values:

state—a random state, or nil, or t. The default is nil.

new-state—a random state object.

Description:

Creates a fresh object of type random-state suitable for use as the value of *random-state*.

If state is a random state object, the new-state is a copy5 of that object. If state is nil, the new-state is a copy5 of the current random state. If state is t, the new-state is a fresh random state object that has been randomly initialized by some means.

Examples:

(let\* ((rs1 (make-random-state nil)) 
(rs2 (make-random-state t))
(rs3 (make-random-state rs2))
(rs4 nil))
(list (loop for i from 1 to 10
collect (random 100)
when (= i 5)
do (setq rs4 (make-random-state)))
(loop for i from 1 to 10 collect (random 100 rs1))
(loop for i from 1 to 10 collect (random 100 rs2))
(loop for i from 1 to 10 collect (random 100 rs3))
(loop for i from 1 to 10 collect (random 100 rs4))))
((29 25 72 57 55 68 24 35 54 65)
(29 25 72 57 55 68 24 35 54 65)
(93 85 53 99 58 62 2 23 23 59)
(93 85 53 99 58 62 2 23 23 59)
(68 24 35 54 65 54 55 50 59 49))

Exceptional Situations:

Should signal an error of type type-error if state is not a random state, or nil, or t.

See Also:

random, *random-state*

Notes:

One important use of make-random-state is to allow the same series of pseudo-random numbers to be generated many times within a single program.

Expanded Reference: make-random-state

Copying the current random state

Calling make-random-state with nil (or no argument) creates a copy of the current *random-state*. Both will then produce the same sequence.

(let ((copy (make-random-state nil)))
(list (loop repeat 5 collect (random 100))
(loop repeat 5 collect (random 100 copy))))
;; Both lists will be identical since they started from the same state.

Creating a randomly initialized state

Passing t creates a new random state that has been randomly seeded by the implementation.

(let ((rs (make-random-state t)))
(loop repeat 5 collect (random 100 rs)))
;; Returns 5 random numbers; different each time this form is evaluated.

Copying a specific random state

Passing an existing random state creates an independent copy of it.

(let* ((rs1 (make-random-state t))
(rs2 (make-random-state rs1)))
(list (loop repeat 5 collect (random 100 rs1))
(loop repeat 5 collect (random 100 rs2))))
;; Both lists will be identical since rs2 is a copy of rs1.

Practical use: reproducible random sequences

Save a random state before generating random numbers so you can reproduce the same sequence later.

(let ((saved-state (make-random-state *random-state*)))
;; Generate some random numbers
(let ((first-run (loop repeat 5 collect (random 100))))
;; Restore the saved state
(setf *random-state* saved-state)
;; Generate the same sequence again
(let ((second-run (loop repeat 5 collect (random 100))))
(equal first-run second-run))))
=> T

Snapshot and resume mid-sequence

You can capture the state at any point and replay from there.

(let (snapshot)
(loop repeat 5 do (random 100)) ; skip 5 numbers
(setq snapshot (make-random-state)) ; capture state after 5
(let ((after-5 (loop repeat 3 collect (random 100))))
(setf *random-state* snapshot)
(equal after-5 (loop repeat 3 collect (random 100)))))
=> T