Hal9000
Random - based on :rand (not :random)
Here is my first stab at this. README pasted below.
https://github.com/Hal9000/elixir_random
Comments and critiques are welcome.
Thanks,
Hal
The Random module is based on Erlang’s rand module. (See http://erlang.org/doc/man/rand.html ).
This in turn is a newer replacement for Erlang’s deprecated random.
All functionality of rand is preserved here. The primary differences are:
- The preferred function name is
rand(althoughuniformandnormalwill still work, for people accustomed to those). -
randtakes a parameter:normalfor normal-distribution results. - The
_sfunctions are unnecessary, as state is passed (as needed) by means of an optional parameter. - Any function that accepts a state also returns the new state (second item in tuple); other functions simply return a number.
- A distinction is made between
seedandseed3(the latter of which takes a tuple of three integers rather than a state). - The functions
export_seedandexport_seed_sare not really needed any longer. - The
randfunction can take a range, e.g.rand(50..60). - The
Randommodule addssample(which takes a second parameter, a number defaulting to 0); this callsEnum.take_randomwhich works on any enumerable. - The
Randommodule addsshuffle(which simply callsEnum.shuffleand thus can take any enumerable. - The PRNG is seeded on module load (default algorithm is
:exsplusjust as with:rand); you may of course reseed at any time.
Examples
x = Random.rand # Random number between 0.0 and 1.0
x = Random.rand(:normal) # Random number in normally-distributed range, -1..1 is one sigma
n = Random.rand(5) # Random integer between 1 and 5
n = Random.rand(10..20) # Random integer between 10 and 20
state = Random.seed(:exsplus) # Use the explus algorithm (default), Xorshift116+, 58 bits, period = 2^116-1
state = Random.seed(:exs64) # Use the exs64 algorithm, Xorshift64, 64 bits, period = 2^64-1
state = Random.seed(:exs1024) # Use the exs1024 algorithm, Xorshift1024, 64 bits, period = 2^1024-1
state = Random.seed3(:exsplus, {1, 2, 3}) # Seed using the three integers 1, 2, 3
state = Random.seed(:exsplus, state) # Seed using the specified state
x = Random.uniform # Same as Random.rand
x = Random.normal # Same as Random.rand(:normal)
{x, state} = Random.rand(state) # Specify state and return number and a new state
{x, state} = Random.rand(:normal, state) # Specify state and return number (normal distribution) and new state
item = Random.sample(enum) # Grab one random item from any enumerable (such as a list)
list = Random.sample(enum, 3) # Grab 3 random items from any enumerable (such as a list)
list = Random.shuffle(enum) # Randomize (shuffle) an enumerable (such as a list)
Notes
The sample and shuffle functions do not have state-sensitive variants.
Most Liked
josevalim
I really like this too! I would love to hijack the rand function and make it part of Elixir’s Kernel. Would you be interested in sending a proposal or a PR to elixir for the rand/0 and rand/1 functions? It sounds like a perfect gateway to link developers to Erlang’s :rand. 
The only change I would possibly do is to drop support for rand(integer) since rand(0..5) is much more explicit than rand(5).
josevalim
As said above, it is already part of the language: Enum.random(1..3). 
josevalim
You can clone the Elixir repo and then run:
make compile
Then you can add the code implementation around here:
And the tests around here:
After writing code or tests, you can run the line below inside the Elixir repo to run one particular test:
elixirc lib/elixir/lib/kernel.ex -o lib/elixir/ebin && elixir lib/elixir/test/elixir/kernel_test.exs
If the tests pass, we are golden! If you would prefer to send the code and tests and not a PR, please just open up an issue!
josevalim
No worries, I have incorporated your changes to master here: https://github.com/elixir-lang/elixir/commit/786da1ffe075d50a26af885f4baf9589978c45c2
hubertlepicki
Is it boring for me to repeat that you are increadibly good in making people contribute to Elixir? I mean, you don’t even have to know pull request flow to do so, awesome!
@Hal9000 for the future you may want to learn the procedure however. It’s both easier for the maintainer and you get some respect badge in the hood by being listed on official contributor’s list (as in here: https://github.com/elixir-lang/elixir/graphs/contributors). If maintainer just copies the code, you are not listed (although in this particular case @josevalim was kind enough to mention you in the commit description!). Some people may care about this detail, others not, just letting you know 







