Skip to content

Conversation

@jfmontanaro
Copy link
Contributor

As discussed on Zulip, this PR adds an API to generate a random seed.

It uses the Rust crate getrandom - originally I was going to use rand, but I realized that rand uses getrandom under the hood anyway, so there's no need for an extra layer of indirection.

I decided to just stick with a single seed!() function for now that generates a U64. I figure if you want differently-shaped data you can use a library like roc-random and just use this to seed it.

I didn't realize until after I put it all together that roc_random uses 32-bit integers for its seeds, rather than 64-bit. I went with 64 bits because I figured, more randomness better, right? But I'd be happy to change it, or add a variant, if that would be better.

I also realize that 64 bits of entropy isn't generally considered enough for some applications (especially cryptographic ones), but I didn't know if it was worth providing an interface to e.g. getrandom::fil() or anything like that. Again, happy to add/change whatever seems best!

@Anton-4 Anton-4 self-assigned this Oct 8, 2025
Copy link
Collaborator

@Anton-4 Anton-4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great PR @jfmontanaro :)
I left some minor comments, let's add a random_seed_u32! as well.

@jfmontanaro
Copy link
Contributor Author

Thanks, will do! Unfortunately I'm out of time for now, so this might have to wait until this evening or tomorrow, but it shouldn't take long once I can get to it.

I see the CI is failing, it looks like it's looking for ci/expect_scripts/random-seed.exp when I named it ci/expect_scripts/random.exp. Is the problem just that it needs the filenames in examples and expect_scripts to match?

Should I just go ahead and add a random_bytes() function as well that returns a List U8? That way you could generate arbitrary amounts of entropy, e.g. for cryptographic purposes.

@jfmontanaro
Copy link
Contributor Author

Ok, I think this is ready for review.

I added random_u32() and random_bytes(), and renamed random_seed() to random_u64() to bring it in line with the other two. random_bytes() takes a U64, which seemed reasonable to me because what you're really specifying is the size of the list, and other functions that work with list sizes (e.g. List.len(), List.with_capacity()) use U64 for that.

Doc comments now a) link to the getrandom crate, b) explain that this operation involves enough overhead that it's not efficient if you need to generate a lot of random numbers, and c) point out that a single 64 or 32 bit integer isn't enough for cryptographic purposes. Right now the explanation is mostly duplicated between random_u64() and random_u32(), but it would be easy to change that and just point at one from the other, if you'd prefer.

@Anton-4
Copy link
Collaborator

Anton-4 commented Oct 10, 2025

Thanks for the edits @jfmontanaro!

I made some final changes:

  • Removed the random_bytes function. In the roc ecosystem we always avoid providing functionality in anticipation of a need, we wait for a specific real world use case. This reduces the total amount of code we need to maintain. Also, for providing functions for cryptography we would need to set up some CI on all supported platforms to verify it's security, which I don't have time for right now.
  • Changed the function names to random_seed_u32 and random_seed_u64 to nudge users towards truly using this as a seed in combination with roc-random. So we don't end up with someone creating benchmarks that are slow in Roc because they did not thoroughly read the documentation of all functions they used.
  • Minor changes to the doc comments.

@Anton-4 Anton-4 merged commit b1e6bd3 into roc-lang:main Oct 10, 2025
8 checks passed
@jfmontanaro
Copy link
Contributor Author

Sounds good, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants