Thanks for contributing your thoughts @paul! :) I don't think I'm doing anything weird with this code per se. The official documentation for rand <http://erlang.org/doc/man/rand.html> says this:
This random number generator is not cryptographically strong. If a strong cryptographic random number generator is needed, use one of functions in the crypto <http://erlang.org/doc/man/crypto.html> module, for example, crypto:strong_rand_bytes/1 <http://erlang.org/doc/man/crypto.html>. And perhaps by extension we should include this type of message in `Enum.random` which is, as far as I know, the only place using `:rand`. I could not find any additional official documentation on the matter and that's the only way I found to seed rand with `crypto:strong_rand_bytes/1` as suggested. On Wednesday, September 21, 2016 at 9:59:28 PM UTC-5, Paul Schoenfelder wrote: > > This code above just doesn't seem like the spirit of Elixir which focuses >> on developer productivity and happiness by simplicity. >> It sends people to learn the intricacies of erlang for something that >> should be simple and is simple in a lot of other languages. >> > > The first thing that pops out to me about that code is that it's odd that > you are providing a constant seed, the typical use of the :rand API for me > is usually just a call like so `:rand.seed(:exsplus)` (or whatever > algorithm you choose). Basically, your example is complicated because you > are doing something extra to seed the random number generator in a > particular way. > > I have to add my +1 to disliking wrapping Erlang standard library > functions when there is no clear benefit to doing so. Adding `Kernel.rand` > or whatever would still have to expose more or less the same complexity, so > there is little benefit to wrapping it. Erlang has a rich standard library, > and if Elixir tried to wrap all of it to avoid making people dip into the > Erlang APIs, it would be a huge effort, and a wasted one for the most part. > I don't think one has to learn the intricacies of Erlang to use the vast > majority of the APIs, they are generally well documented, and if you know > Elixir, you can use the Erlang APIs with little understanding of Erlang > itself - in my opinion, if you know Elixir, there isn't much of a leap to > knowing Erlang anyway, other than learning the syntax. The biggest pain > point of course is that the Elixir and Erlang documentation is separated, > and one can't access the Erlang docs in the shell, etc - but I don't think > the solution to that is wrapping everything. > > Just my two cents, > > Paul > > > On Wed, Sep 21, 2016 at 9:39 PM, Dorian Karter <[email protected] > <javascript:>> wrote: > >> Thanks @josevalim, I'll definetly send a PR to the Elixir guide as you >> suggested. I had no idea this page existed. >> >> I tend to agree with @eksperimental. >> >> The other point I have (oops had) in favor of implementing Kernel.seed is >> that @josevalim recently implemented Kernel.rand. >> Scratch that just saw this commit from 5hrs ago >> https://github.com/elixir-lang/elixir/commit/8e2a1e58510dbefb5c707071fcba1584ba3b614f >> >> Regardless, I think there should be a more idiomatic way to seed rand >> that does not involve sending the user down the path I've gone down in my >> blog post. >> >> << i1 :: unsigned-integer-32, i2 :: unsigned-integer-32, i3 :: >> unsigned-integer-32>> = :crypto.strong_rand_bytes(12):rand.seed(:exsplus, >> {i1, i2, i3}) >> >> >> This code above just doesn't seem like the spirit of Elixir which focuses >> on developer productivity and happiness by simplicity. >> It sends people to learn the intricacies of erlang for something that >> should be simple and is simple in a lot of other languages. >> >> I think we can take a hint from Ruby and Java and their SecureRandom >> libraries: >> >> Java: >> https://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html >> Ruby: >> https://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html >> >> Particularly I like Ruby's SecureRandom because it provides helpful >> methods such as `urlsafe_base64`, `uuid`, `random_bytes` and `hex`. I >> remember this being the first thing I looked for when I was building my >> first Elixir application (url shortener) and was surprised at how many >> hoops I had to jump through as a beginner to get something so simple done. >> >> On Wednesday, September 21, 2016 at 2:39:13 PM UTC-5, eksperimental wrote: >>> >>> there is a single particularity in this proposal, and it could solve >>> something I have been bitten >>> by some time ago when improving *.random functions in Elixir core. >>> I couldn't figure out why all tests related to random functions were not >>> working, and that's becuase >>> when creating Integer.random (a function that never made it to core) I >>> used :random.seed instead >>> of :rand.seed. >>> Believe me it took me a while and a lot of head scratches to figure out >>> what was going on. >>> >>> Having two modules so similar it's a source of confusion, and being this >>> function a critical >>> function when generating randon values could be a source of security >>> bugs: so I don't think it >>> would be a bad idea to have a Kernel.seed funcion >>> >>> >>> On Wed, 21 Sep 2016 21:01:23 +0200 >>> José Valim <[email protected]> wrote: >>> >>> > We typically avoid only wrapping Erlang functions because in the long >>> term >>> > we will just end-up duplicating all the efforts already done in the >>> Erlang >>> > community. For example, even for a simple case such as Kernel.seed, we >>> need >>> > to document the tuple format, the meaning of exsplus, etc. And unless >>> we >>> > wrap all the functionality in rand, at some point you will still need >>> to >>> > use rand directly. >>> > >>> > So I would like to propose other initiatives: >>> > >>> > * We should continue to focus on better documenting those entry >>> points, >>> > which we already do in places such as the Getting Started guides >>> > <http://elixir-lang.org/getting-started/erlang-libraries.html>. In >>> fact, >>> > your article is a great exploration of the rand module and, if you >>> send a >>> > pull request to the guides linking to your article in the rand >>> section, we >>> > would love to merge it! >>> > >>> > * Send a pull request to Erlang/OTP that improves their documentation. >>> For >>> > example, including an example of using the crypto module for a >>> > cryptographically secure example would probably be very welcome. >>> > >>> > * Send a pull request to Erlang/OTP that adds the functionality you >>> would >>> > like to see Elixir wrapping. >>> > >>> > If you or anyone else need help in contributing to Erlang, please ping >>> me >>> > any time, either on IRC or by e-mail and I would love to provide >>> guidance. >>> > Improving Erlang is our responsibility too! :D >>> > >>> > >>> > *José Valim* >>> > www.plataformatec.com.br >>> > Skype: jv.ptec >>> > Founder and Director of R&D >>> > >>> > On Wed, Sep 21, 2016 at 8:47 PM, Dorian Karter <[email protected]> >>> wrote: >>> > >>> > > I recently wrote a blog post about my explorations into random >>> number >>> > > generation from Elixir and Erlang. You can find it here: >>> > > https://hashrocket.com/blog/posts/the-adventures-of- >>> > > generating-random-numbers-in-erlang-and-elixir >>> > > >>> > > This led me to question why `:rand.seed` is not exposed from Elixir >>> > > without hitting Erlang directly. I think every time we send a user >>> to learn >>> > > something about the intricacies of Erlang we are introducing a >>> mental >>> > > overhead. >>> > > >>> > > I would be happy to submit a pull request that will attempt to wrap >>> > > `:rand.seed` but figured I'd check with the core team first. My >>> questions: >>> > > >>> > > 1. Why is `:rand.seed` not exposed from Elixir? is that by design? >>> > > 2. If it should be exposed by Elixir where do you imagine it living? >>> > > `Kernel.seed`? or should we create a new `Random` module. >>> > > 3. Would it make sense to provide a method that will just securly >>> seed >>> > > rand like so >>> > > >>> > > << i1 :: unsigned-integer-32, i2 :: unsigned-integer-32, i3 :: >>> unsigned-integer-32>> >>> > > = :crypto.strong_rand_bytes(12):rand.seed(:exsplus, {i1, i2, i3}) >>> > > >>> > > 4. Anything else I should consider if I submit a pull request other >>> than >>> > > obvious testing and documentation >>> > > >>> > > >>> > > Thanks so much for your attention and feedback! >>> > > >>> > > Dorian >>> > > >>> > > -- >>> > > You received this message because you are subscribed to the Google >>> Groups >>> > > "elixir-lang-core" group. >>> > > To unsubscribe from this group and stop receiving emails from it, >>> send an >>> > > email to [email protected]. >>> > > To view this discussion on the web visit >>> https://groups.google.com/d/ >>> > > msgid/elixir-lang-core/577910ae-2a52-49f4-9e77- >>> > > 670639106a3c%40googlegroups.com >>> > > < >>> https://groups.google.com/d/msgid/elixir-lang-core/577910ae-2a52-49f4-9e77-670639106a3c%40googlegroups.com?utm_medium=email&utm_source=footer> >>> >>> >>> > > . >>> > > For more options, visit https://groups.google.com/d/optout. >>> > > >>> > >>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/5607dd04-eaf2-499e-8182-3789a44ebded%40googlegroups.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/5607dd04-eaf2-499e-8182-3789a44ebded%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/d7a71dc1-0fce-47e7-836f-291e7c1ca415%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
