From 0835ba2a31a20f459e347659463ac9f30c1c964c Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Wed, 8 Oct 2025 08:22:27 -0400 Subject: [PATCH 1/3] add random seed generation --- Cargo.lock | 263 ++++++++++++++++++++++------------- Cargo.toml | 3 + ci/expect_scripts/random.exp | 19 +++ crates/roc_host/Cargo.toml | 3 +- crates/roc_host/src/lib.rs | 8 +- crates/roc_random/Cargo.toml | 13 ++ crates/roc_random/src/lib.rs | 10 ++ examples/random-seed.roc | 15 ++ platform/Host.roc | 3 + platform/Random.roc | 20 +++ platform/main.roc | 1 + 11 files changed, 258 insertions(+), 100 deletions(-) create mode 100644 ci/expect_scripts/random.exp create mode 100644 crates/roc_random/Cargo.toml create mode 100644 crates/roc_random/src/lib.rs create mode 100644 examples/random-seed.roc create mode 100644 platform/Random.roc diff --git a/Cargo.lock b/Cargo.lock index 86494348..2eee2cc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "arrayvec" @@ -23,12 +23,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - [[package]] name = "backtrace" version = "0.3.75" @@ -46,9 +40,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bytes" @@ -58,18 +52,19 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" dependencies = [ + "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "convert_case" @@ -82,9 +77,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -155,14 +150,20 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.12" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" + [[package]] name = "fnv" version = "1.0.7" @@ -204,13 +205,25 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] @@ -264,9 +277,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" @@ -326,9 +339,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "libc" @@ -349,31 +362,30 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litrs" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.22" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "memchr" @@ -392,23 +404,23 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", - "wasi", - "windows-sys 0.52.0", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] @@ -422,21 +434,21 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -444,15 +456,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-link", ] [[package]] @@ -469,33 +481,39 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] @@ -508,7 +526,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -560,6 +578,7 @@ dependencies = [ "roc_file", "roc_http", "roc_io_error", + "roc_random", "roc_sqlite", "roc_std", "roc_std_heap", @@ -601,6 +620,15 @@ dependencies = [ "roc_std_heap", ] +[[package]] +name = "roc_random" +version = "0.0.1" +dependencies = [ + "getrandom 0.3.3", + "roc_io_error", + "roc_std", +] + [[package]] name = "roc_sqlite" version = "0.0.1" @@ -614,7 +642,7 @@ dependencies = [ [[package]] name = "roc_std" version = "0.0.1" -source = "git+https://github.com/roc-lang/roc.git#fbf448cac882ed9f81cb68242e0091a75f4f202d" +source = "git+https://github.com/roc-lang/roc.git#caaae472ee1e2d3ecca29168ca9292ed268e302a" dependencies = [ "arrayvec", "static_assertions", @@ -623,7 +651,7 @@ dependencies = [ [[package]] name = "roc_std_heap" version = "0.0.1" -source = "git+https://github.com/roc-lang/roc.git#fbf448cac882ed9f81cb68242e0091a75f4f202d" +source = "git+https://github.com/roc-lang/roc.git#caaae472ee1e2d3ecca29168ca9292ed268e302a" dependencies = [ "memmap2", "roc_std", @@ -639,28 +667,28 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustix" -version = "1.0.7" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.27" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "once_cell", "ring", @@ -693,9 +721,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.3" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -704,11 +732,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -719,9 +747,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.2.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags", "core-foundation", @@ -732,9 +760,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -748,9 +776,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" dependencies = [ "libc", "signal-hook-registry", @@ -769,24 +797,24 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", @@ -806,9 +834,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -850,9 +878,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -876,9 +904,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", ] @@ -891,9 +919,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-segmentation" @@ -924,9 +952,27 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "winapi" @@ -950,6 +996,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.52.0" @@ -968,6 +1020,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1032,8 +1093,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" diff --git a/Cargo.toml b/Cargo.toml index f0b3b7ef..943ca0ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "crates/roc_stdio", "crates/roc_env", "crates/roc_sqlite", + "crates/roc_random", ] [workspace.package] @@ -37,6 +38,7 @@ roc_http = { path = "crates/roc_http" } roc_io_error = { path = "crates/roc_io_error" } roc_stdio = { path = "crates/roc_stdio" } roc_env = { path = "crates/roc_env" } +roc_random = { path = "crates/roc_random" } roc_sqlite = { path = "crates/roc_sqlite" } memchr = "=2.7.4" hyper = { version = "=1.6.0", default-features = false, features = [ @@ -61,3 +63,4 @@ libc = "=0.2.172" backtrace = "=0.3.75" libsqlite3-sys = { version = "=0.33.0", features = ["bundled"] } thread_local = "=1.1.8" +getrandom = { version = "0.3.3", features = [ "std" ] } diff --git a/ci/expect_scripts/random.exp b/ci/expect_scripts/random.exp new file mode 100644 index 00000000..10539f4c --- /dev/null +++ b/ci/expect_scripts/random.exp @@ -0,0 +1,19 @@ +#!/usr/bin/expect + +# uncomment line below for debugging +# exp_internal 1 + +set timeout 7 + +source ./ci/expect_scripts/shared-code.exp + +spawn $env(EXAMPLES_DIR)random-seed + +expect -re "Seed is: \\d+" { + expect eof { + check_exit_and_segfault + } +} + +puts stderr "\nExpect script failed: output was different from expected value. uncomment `exp_internal 1` to debug." +exit 1 diff --git a/crates/roc_host/Cargo.toml b/crates/roc_host/Cargo.toml index 174e387f..882b0178 100644 --- a/crates/roc_host/Cargo.toml +++ b/crates/roc_host/Cargo.toml @@ -27,10 +27,11 @@ roc_io_error.workspace = true roc_http.workspace = true roc_stdio.workspace = true roc_env.workspace = true +roc_random.workspace = true roc_sqlite.workspace = true hyper.workspace = true hyper-rustls.workspace = true tokio.workspace = true bytes.workspace = true http-body-util.workspace = true -hyper-util.workspace = true \ No newline at end of file +hyper-util.workspace = true diff --git a/crates/roc_host/src/lib.rs b/crates/roc_host/src/lib.rs index 8409b017..067f8c48 100644 --- a/crates/roc_host/src/lib.rs +++ b/crates/roc_host/src/lib.rs @@ -349,6 +349,7 @@ pub fn init() { roc_fx_temp_dir as _, roc_fx_get_locale as _, roc_fx_get_locales as _, + roc_fx_random_seed as _, roc_fx_sqlite_bind as _, roc_fx_sqlite_column_value as _, roc_fx_sqlite_columns as _, @@ -658,7 +659,7 @@ async fn async_send_request(request: hyper::Request> let client: Client<_, http_body_util::Full> = Client::builder(TokioExecutor::new()).build(https); - + let response_res = client.request(request).await; match response_res { @@ -809,6 +810,11 @@ pub extern "C" fn roc_fx_get_locales() -> RocList { roc_env::get_locales() } +#[no_mangle] +pub extern "C" fn roc_fx_random_seed() -> RocResult { + roc_random::seed() +} + #[no_mangle] pub extern "C" fn roc_fx_sqlite_bind( stmt: RocBox<()>, diff --git a/crates/roc_random/Cargo.toml b/crates/roc_random/Cargo.toml new file mode 100644 index 00000000..637edb45 --- /dev/null +++ b/crates/roc_random/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "roc_random" +description = "Common functionality for Roc to interface with rand" +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +version.workspace = true + +[dependencies] +roc_std.workspace = true +roc_io_error.workspace = true +getrandom.workspace = true diff --git a/crates/roc_random/src/lib.rs b/crates/roc_random/src/lib.rs new file mode 100644 index 00000000..528b567a --- /dev/null +++ b/crates/roc_random/src/lib.rs @@ -0,0 +1,10 @@ +use roc_std::RocResult; +use roc_io_error::IOErr; + + +pub fn seed() -> RocResult { + getrandom::u64() + .map_err(|e| std::io::Error::from(e)) + .map_err(|e| IOErr::from(e)) + .into() +} diff --git a/examples/random-seed.roc b/examples/random-seed.roc new file mode 100644 index 00000000..6fb8a7a5 --- /dev/null +++ b/examples/random-seed.roc @@ -0,0 +1,15 @@ +app [main!] { pf: platform "../platform/main.roc" } + +# To run this example: check the README.md in this folder + +# Demo of basic-cli Random functions + +import pf.Stdout +import pf.Random +import pf.Arg exposing [Arg] + +main! : List Arg => Result {} _ +main! = |_args| + seed = Random.seed!({})? + + Stdout.line!("Seed is: ${Inspect.to_str(seed)}") diff --git a/platform/Host.roc b/platform/Host.roc index 97c72812..ccf5c3fa 100644 --- a/platform/Host.roc +++ b/platform/Host.roc @@ -33,6 +33,7 @@ hosted [ hard_link!, path_type!, posix_time!, + random_seed!, send_request!, set_cwd!, sleep_millis!, @@ -146,3 +147,5 @@ env_dict! : {} => List (Str, Str) env_var! : Str => Result Str {} exe_path! : {} => Result (List U8) {} set_cwd! : List U8 => Result {} {} + +random_seed! : {} => Result U64 InternalIOErr.IOErrFromHost diff --git a/platform/Random.roc b/platform/Random.roc new file mode 100644 index 00000000..19c4c5a8 --- /dev/null +++ b/platform/Random.roc @@ -0,0 +1,20 @@ +module [ + IOErr, + seed!, +] + +import InternalIOErr +import Host + + +## Tag union of possible errors when getting a random seed. +## +## > This is the same as [`File.IOErr`](File#IOErr). +IOErr : InternalIOErr.IOErr + +## Generate a random U64 using the system's source of randomness. +## This uses the Rust crate `getrandom`. +seed! : {} => Result U64 [RandomErr IOErr] +seed! = |{}| + Host.random_seed!({}) + |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) diff --git a/platform/main.roc b/platform/main.roc index 63846ce0..08d8adeb 100644 --- a/platform/main.roc +++ b/platform/main.roc @@ -18,6 +18,7 @@ platform "cli" Tty, Locale, Sqlite, + Random, ] packages {} imports [] From 567fb859f086ae26c42cc842a826e5f344a86e3d Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Thu, 9 Oct 2025 06:52:50 -0400 Subject: [PATCH 2/3] add `random_u32` and `random_bytes`, rename `seed` to `random_u64` --- ci/expect_scripts/random.exp | 10 ++++++-- crates/roc_host/src/lib.rs | 18 ++++++++++--- crates/roc_random/Cargo.toml | 2 +- crates/roc_random/src/lib.rs | 20 +++++++++++++-- examples/random-seed.roc | 15 ----------- examples/random.roc | 20 +++++++++++++++ platform/Host.roc | 8 ++++-- platform/Random.roc | 49 ++++++++++++++++++++++++++++++++---- 8 files changed, 112 insertions(+), 30 deletions(-) delete mode 100644 examples/random-seed.roc create mode 100644 examples/random.roc diff --git a/ci/expect_scripts/random.exp b/ci/expect_scripts/random.exp index 10539f4c..8b6bdc68 100644 --- a/ci/expect_scripts/random.exp +++ b/ci/expect_scripts/random.exp @@ -7,9 +7,15 @@ set timeout 7 source ./ci/expect_scripts/shared-code.exp -spawn $env(EXAMPLES_DIR)random-seed +spawn $env(EXAMPLES_DIR)random -expect -re "Seed is: \\d+" { +set expected_output [normalize_output " +Random U64 is: \\\d+ +Random U32 is: \\\d+ +Random bytes are: \\\[\\\d+, \\\d+, \\\d+, \\\d+\\\] +"] + +expect -re $expected_output { expect eof { check_exit_and_segfault } diff --git a/crates/roc_host/src/lib.rs b/crates/roc_host/src/lib.rs index 067f8c48..4b547ec4 100644 --- a/crates/roc_host/src/lib.rs +++ b/crates/roc_host/src/lib.rs @@ -349,7 +349,9 @@ pub fn init() { roc_fx_temp_dir as _, roc_fx_get_locale as _, roc_fx_get_locales as _, - roc_fx_random_seed as _, + roc_fx_random_u64 as _, + roc_fx_random_u32 as _, + roc_fx_random_bytes as _, roc_fx_sqlite_bind as _, roc_fx_sqlite_column_value as _, roc_fx_sqlite_columns as _, @@ -811,8 +813,18 @@ pub extern "C" fn roc_fx_get_locales() -> RocList { } #[no_mangle] -pub extern "C" fn roc_fx_random_seed() -> RocResult { - roc_random::seed() +pub extern "C" fn roc_fx_random_u64() -> RocResult { + roc_random::random_u64() +} + +#[no_mangle] +pub extern "C" fn roc_fx_random_u32() -> RocResult { + roc_random::random_u32() +} + +#[no_mangle] +pub extern "C" fn roc_fx_random_bytes(count: u64) -> RocResult, IOErr> { + roc_random::random_bytes(count) } #[no_mangle] diff --git a/crates/roc_random/Cargo.toml b/crates/roc_random/Cargo.toml index 637edb45..5bfe5dbf 100644 --- a/crates/roc_random/Cargo.toml +++ b/crates/roc_random/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "roc_random" -description = "Common functionality for Roc to interface with rand" +description = "Common functionality for Roc to interface with getrandom" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/crates/roc_random/src/lib.rs b/crates/roc_random/src/lib.rs index 528b567a..d5e5e0cd 100644 --- a/crates/roc_random/src/lib.rs +++ b/crates/roc_random/src/lib.rs @@ -1,10 +1,26 @@ -use roc_std::RocResult; +use roc_std::{RocList, RocResult}; use roc_io_error::IOErr; -pub fn seed() -> RocResult { +pub fn random_u64() -> RocResult { getrandom::u64() .map_err(|e| std::io::Error::from(e)) .map_err(|e| IOErr::from(e)) .into() } + +pub fn random_u32() -> RocResult { + getrandom::u32() + .map_err(|e| std::io::Error::from(e)) + .map_err(|e| IOErr::from(e)) + .into() +} + +pub fn random_bytes(count: u64) -> RocResult, IOErr> { + let mut buf = RocList::from_iter((0..count).map(|_| 0u8)); + getrandom::fill(buf.as_mut_slice()) + .map(|_| buf) + .map_err(|e| std::io::Error::from(e)) + .map_err(|e| IOErr::from(e)) + .into() +} diff --git a/examples/random-seed.roc b/examples/random-seed.roc deleted file mode 100644 index 6fb8a7a5..00000000 --- a/examples/random-seed.roc +++ /dev/null @@ -1,15 +0,0 @@ -app [main!] { pf: platform "../platform/main.roc" } - -# To run this example: check the README.md in this folder - -# Demo of basic-cli Random functions - -import pf.Stdout -import pf.Random -import pf.Arg exposing [Arg] - -main! : List Arg => Result {} _ -main! = |_args| - seed = Random.seed!({})? - - Stdout.line!("Seed is: ${Inspect.to_str(seed)}") diff --git a/examples/random.roc b/examples/random.roc new file mode 100644 index 00000000..69308605 --- /dev/null +++ b/examples/random.roc @@ -0,0 +1,20 @@ +app [main!] { pf: platform "../platform/main.roc" } + +# To run this example: check the README.md in this folder + +# Demo of basic-cli Random functions + +import pf.Stdout +import pf.Random +import pf.Arg exposing [Arg] + +main! : List Arg => Result {} _ +main! = |_args| + random_u64 = Random.random_u64!({})? + Stdout.line!("Random U64 is: ${Inspect.to_str(random_u64)}")? + + random_u32 = Random.random_u32!({})? + Stdout.line!("Random U32 is: ${Inspect.to_str(random_u32)}")? + + random_bytes = Random.random_bytes!(4)? + Stdout.line!("Random bytes are: ${Inspect.to_str(random_bytes)}") diff --git a/platform/Host.roc b/platform/Host.roc index ccf5c3fa..5b96b033 100644 --- a/platform/Host.roc +++ b/platform/Host.roc @@ -33,7 +33,9 @@ hosted [ hard_link!, path_type!, posix_time!, - random_seed!, + random_u64!, + random_u32!, + random_bytes!, send_request!, set_cwd!, sleep_millis!, @@ -148,4 +150,6 @@ env_var! : Str => Result Str {} exe_path! : {} => Result (List U8) {} set_cwd! : List U8 => Result {} {} -random_seed! : {} => Result U64 InternalIOErr.IOErrFromHost +random_u64! : {} => Result U64 InternalIOErr.IOErrFromHost +random_u32! : {} => Result U32 InternalIOErr.IOErrFromHost +random_bytes! : U64 => Result (List U8) InternalIOErr.IOErrFromHost diff --git a/platform/Random.roc b/platform/Random.roc index 19c4c5a8..6debcadd 100644 --- a/platform/Random.roc +++ b/platform/Random.roc @@ -1,6 +1,8 @@ module [ IOErr, - seed!, + random_u64!, + random_u32!, + random_bytes!, ] import InternalIOErr @@ -13,8 +15,45 @@ import Host IOErr : InternalIOErr.IOErr ## Generate a random U64 using the system's source of randomness. -## This uses the Rust crate `getrandom`. -seed! : {} => Result U64 [RandomErr IOErr] -seed! = |{}| - Host.random_seed!({}) +## +## This uses Rust's [getrandom](https://crates.io/crates/getrandom) crate to produce +## a single random 64-bit integer. Note that this is a direct interface to the +## system's source of randomness, meaning that each call introduces a significant +## amount of overhead. If you need to generate a lot of random numbers, consider +## calling this function once to generate a single "seed", then using a library +## such as [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate +## additional random numbers. +## +## > Note that 64 bits is NOT considered sufficient randomness for cryptographic +## applications such as encryption keys. Prefer using `random_bytes()` to generate +## larger random values for security-sensitive applications. +random_u64! : {} => Result U64 [RandomErr IOErr] +random_u64! = |{}| + Host.random_u64!({}) + |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) + +## Generate a random U32 using the system's source of randomness. +## +## This uses Rust's [getrandom](https://crates.io/crates/getrandom) crate to produce +## a single random 32-bit integer. Note that this is a direct interface to the +## system's source of randomness, meaning that each call introduces a significant +## amount of overhead. If you need to generate a lot of random numbers, consider +## calling this function once to generate a single "seed", then using a library +## such as [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate +## additional random numbers. +## +## > Note that 32 bits is NOT considered sufficient randomness for cryptographic +## applications such as encryption keys. Prefer using `random_bytes()` to generate +## larger random values for security-sensitive applications. +random_u32! : {} => Result U32 [RandomErr IOErr] +random_u32! = |{}| + Host.random_u32!({}) + |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) + +## Generate an arbitrary number of bytes using the system's source of randomness. +## For additional details on the specific source of randomness used on various +## platforms, see the Rust crate [getrandom](https://docs.rs/getrandom/0.3.3/getrandom/index.html). +random_bytes! : U64 => Result (List U8) [RandomErr IOErr] +random_bytes! = |count| + Host.random_bytes!(count) |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) From 1255c29a4d00ec6a627fe26a4240ff0fe323b73a Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 10 Oct 2025 16:16:50 +0200 Subject: [PATCH 3/3] misc changes --- ci/expect_scripts/random.exp | 7 ++-- crates/roc_host/src/lib.rs | 6 --- crates/roc_random/src/lib.rs | 9 ----- examples/random.roc | 12 +++--- platform/Host.roc | 2 - platform/Random.roc | 77 ++++++++++++++++-------------------- 6 files changed, 44 insertions(+), 69 deletions(-) diff --git a/ci/expect_scripts/random.exp b/ci/expect_scripts/random.exp index 8b6bdc68..a6073fad 100644 --- a/ci/expect_scripts/random.exp +++ b/ci/expect_scripts/random.exp @@ -10,9 +10,8 @@ source ./ci/expect_scripts/shared-code.exp spawn $env(EXAMPLES_DIR)random set expected_output [normalize_output " -Random U64 is: \\\d+ -Random U32 is: \\\d+ -Random bytes are: \\\[\\\d+, \\\d+, \\\d+, \\\d+\\\] +Random U64 seed is: \\\d+ +Random U32 seed is: \\\d+ "] expect -re $expected_output { @@ -22,4 +21,4 @@ expect -re $expected_output { } puts stderr "\nExpect script failed: output was different from expected value. uncomment `exp_internal 1` to debug." -exit 1 +exit 1 \ No newline at end of file diff --git a/crates/roc_host/src/lib.rs b/crates/roc_host/src/lib.rs index 4b547ec4..b9fe3b69 100644 --- a/crates/roc_host/src/lib.rs +++ b/crates/roc_host/src/lib.rs @@ -351,7 +351,6 @@ pub fn init() { roc_fx_get_locales as _, roc_fx_random_u64 as _, roc_fx_random_u32 as _, - roc_fx_random_bytes as _, roc_fx_sqlite_bind as _, roc_fx_sqlite_column_value as _, roc_fx_sqlite_columns as _, @@ -822,11 +821,6 @@ pub extern "C" fn roc_fx_random_u32() -> RocResult { roc_random::random_u32() } -#[no_mangle] -pub extern "C" fn roc_fx_random_bytes(count: u64) -> RocResult, IOErr> { - roc_random::random_bytes(count) -} - #[no_mangle] pub extern "C" fn roc_fx_sqlite_bind( stmt: RocBox<()>, diff --git a/crates/roc_random/src/lib.rs b/crates/roc_random/src/lib.rs index d5e5e0cd..8187b5b4 100644 --- a/crates/roc_random/src/lib.rs +++ b/crates/roc_random/src/lib.rs @@ -15,12 +15,3 @@ pub fn random_u32() -> RocResult { .map_err(|e| IOErr::from(e)) .into() } - -pub fn random_bytes(count: u64) -> RocResult, IOErr> { - let mut buf = RocList::from_iter((0..count).map(|_| 0u8)); - getrandom::fill(buf.as_mut_slice()) - .map(|_| buf) - .map_err(|e| std::io::Error::from(e)) - .map_err(|e| IOErr::from(e)) - .into() -} diff --git a/examples/random.roc b/examples/random.roc index 69308605..b539f9c8 100644 --- a/examples/random.roc +++ b/examples/random.roc @@ -10,11 +10,11 @@ import pf.Arg exposing [Arg] main! : List Arg => Result {} _ main! = |_args| - random_u64 = Random.random_u64!({})? - Stdout.line!("Random U64 is: ${Inspect.to_str(random_u64)}")? + random_u64 = Random.random_seed_u64!({})? + Stdout.line!("Random U64 seed is: ${Inspect.to_str(random_u64)}")? - random_u32 = Random.random_u32!({})? - Stdout.line!("Random U32 is: ${Inspect.to_str(random_u32)}")? + random_u32 = Random.random_seed_u32!({})? + Stdout.line!("Random U32 seed is: ${Inspect.to_str(random_u32)}") - random_bytes = Random.random_bytes!(4)? - Stdout.line!("Random bytes are: ${Inspect.to_str(random_bytes)}") + # See the example linked below on how to generate a sequence of random numbers using a seed + # https://github.com/roc-lang/examples/blob/main/examples/RandomNumbers/main.roc \ No newline at end of file diff --git a/platform/Host.roc b/platform/Host.roc index 5b96b033..4e83fdc7 100644 --- a/platform/Host.roc +++ b/platform/Host.roc @@ -35,7 +35,6 @@ hosted [ posix_time!, random_u64!, random_u32!, - random_bytes!, send_request!, set_cwd!, sleep_millis!, @@ -152,4 +151,3 @@ set_cwd! : List U8 => Result {} {} random_u64! : {} => Result U64 InternalIOErr.IOErrFromHost random_u32! : {} => Result U32 InternalIOErr.IOErrFromHost -random_bytes! : U64 => Result (List U8) InternalIOErr.IOErrFromHost diff --git a/platform/Random.roc b/platform/Random.roc index 6debcadd..ac11df2b 100644 --- a/platform/Random.roc +++ b/platform/Random.roc @@ -1,8 +1,7 @@ module [ IOErr, - random_u64!, - random_u32!, - random_bytes!, + random_seed_u64!, + random_seed_u32!, ] import InternalIOErr @@ -14,46 +13,40 @@ import Host ## > This is the same as [`File.IOErr`](File#IOErr). IOErr : InternalIOErr.IOErr -## Generate a random U64 using the system's source of randomness. -## -## This uses Rust's [getrandom](https://crates.io/crates/getrandom) crate to produce -## a single random 64-bit integer. Note that this is a direct interface to the -## system's source of randomness, meaning that each call introduces a significant -## amount of overhead. If you need to generate a lot of random numbers, consider -## calling this function once to generate a single "seed", then using a library -## such as [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate -## additional random numbers. -## -## > Note that 64 bits is NOT considered sufficient randomness for cryptographic -## applications such as encryption keys. Prefer using `random_bytes()` to generate -## larger random values for security-sensitive applications. -random_u64! : {} => Result U64 [RandomErr IOErr] -random_u64! = |{}| +## Generate a random `U64` seed using the system's source of randomness. +## A "seed" is a starting value used to deterministically generate a random sequence. +## +## > !! This function is NOT cryptographically secure. +## +## This uses the [`u64()`](https://docs.rs/getrandom/latest/getrandom/fn.u64.html) function +## of the [getrandom crate](https://crates.io/crates/getrandom) to produce +## a single random 64-bit integer. +## +## For hobby purposes, you can just call this function repreatedly to get random numbers. +## In general, we recommend using this seed in combination with a library like +## [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate additional +## random numbers quickly. +## +random_seed_u64! : {} => Result U64 [RandomErr IOErr] +random_seed_u64! = |{}| Host.random_u64!({}) |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) -## Generate a random U32 using the system's source of randomness. -## -## This uses Rust's [getrandom](https://crates.io/crates/getrandom) crate to produce -## a single random 32-bit integer. Note that this is a direct interface to the -## system's source of randomness, meaning that each call introduces a significant -## amount of overhead. If you need to generate a lot of random numbers, consider -## calling this function once to generate a single "seed", then using a library -## such as [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate -## additional random numbers. -## -## > Note that 32 bits is NOT considered sufficient randomness for cryptographic -## applications such as encryption keys. Prefer using `random_bytes()` to generate -## larger random values for security-sensitive applications. -random_u32! : {} => Result U32 [RandomErr IOErr] -random_u32! = |{}| +## Generate a random `U32` seed using the system's source of randomness. +## A "seed" is a starting value used to deterministically generate a random sequence. +## +## > !! This function is NOT cryptographically secure. +## +## This uses the [`u32()`](https://docs.rs/getrandom/0.3.3/getrandom/fn.u32.html) function +## of the [getrandom crate](https://crates.io/crates/getrandom) to produce +## a single random 32-bit integer. +## +## For hobby purposes, you can just call this function repreatedly to get random numbers. +## In general, we recommend using this seed in combination with a library like +## [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate additional +## random numbers quickly. +## +random_seed_u32! : {} => Result U32 [RandomErr IOErr] +random_seed_u32! = |{}| Host.random_u32!({}) - |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) - -## Generate an arbitrary number of bytes using the system's source of randomness. -## For additional details on the specific source of randomness used on various -## platforms, see the Rust crate [getrandom](https://docs.rs/getrandom/0.3.3/getrandom/index.html). -random_bytes! : U64 => Result (List U8) [RandomErr IOErr] -random_bytes! = |count| - Host.random_bytes!(count) - |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) + |> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err))) \ No newline at end of file