Stream: platform development

Topic: Deterministic simulation testing (DST) with Roc platforms


view this post on Zulip Jan Rüggeberg (Oct 23 2026 at 18:02):

Hi I'm Jan, a student from Berlin, Germany, and I'm planning to write my bachelor thesis about Roc.
More specifically about how the platform system may make it suitable for deterministic simulation testing.
This blog post by Phil Eaton is a good overview and introduction to what that is: https://notes.eatonphil.com/2024-08-20-deterministic-simulation-testing.html

I've not yet heard anyone talk about Roc and DST, except one guy for one minute on this podcast (https://shows.acast.com/dead-code/episodes/deterministic-simulation-with-stevan) 12:30-13:30.

Though I think Roc lends itself particularly well to DST, since it forces all of the nondeterministic operations to go through the platform layer (atleast the ones that I know of).

It is early days and nothing is decided yet, but my professor is open to it.
The thesis question could be something along the lines of this:
How can Roc's platform model be used to run one distributed system unchanged under deterministic simulation and in production, and what does this approach gain and lose compared with existing approaches?

The Plan:

I want to write a Raft implementation in pure Roc in the sans-io style (https://sans-io.readthedocs.io/how-to-sans-io.html) and on top of it a KV store.
I'll build two small platforms: one is a simulator and one has the real networking etc.
The platforms will be deliberately small and only include the functionality I actually need.

I did some testing and I think this is feasible. I don't need multithreading or async for this.

I would be glad if you could help me by answering a few questions:

  1. Did anyone already look into this domain (DST) in combination with Roc?
  2. Do you think this is feasible at the current state of the language?
  3. I'm planning on writing the platforms in Rust, because I've only written about 200 lines of Zig so far. Is there a strong reason to go with Zig instead?
  4. Is there other nondeterministic behaviour in the language (like HashMap iteration order in Rust)?
  5. Is there anything I glossed over or just forgot about?

I have a lot to learn, so I'm happy to hear your thoughts.

view this post on Zulip Richard Feldman (Oct 23 2026 at 18:06):

really cool! :smiley:

view this post on Zulip Richard Feldman (Oct 23 2026 at 18:10):

Jan Rüggeberg said:

  1. Did anyone already look into this domain (DST) in combination with Roc?

not as far as I know

  1. Do you think this is feasible at the current state of the language?

absolutely!

  1. I'm planning on writing the platforms in Rust, because I've only written about 200 lines of Zig so far. Is there a strong reason to go with Zig instead?

I'd say @Luke Boswell has the most experience with the differences in experience between writing Rust and Zig hosts, so I'll defer to him on that :smile:

view this post on Zulip Jan Rüggeberg (Oct 23 2026 at 18:15):

Thanks a lot for the input!!

view this post on Zulip Anton (Oct 23 2026 at 18:16):

Hi Jan :)

Did anyone already look into this domain (DST) in combination with Roc?

I did an AI assisted search through our group chat and found no direct matches. Something adjacent is the simulation tests we plan for effectful functions by supplying simulated values, without running the real effects and without an effect-interpreter layer. So it's similar but does not use the DST randomness.

view this post on Zulip Richard Feldman (Oct 23 2026 at 18:17):

  1. Is there other nondeterministic behaviour in the language (like HashMap iteration order in Rust)?

no, we go way out of our way to make everything as deterministic as possible actually - including across targets, e.g.

the main reason we do this is actually because of our eager compile-time evaluation - which basically evaluates any expression at compile time if it can be evaluated at compile time (e.g. it doesn't depend on any runtime inputs). This is only safe to do if there is no chance that it would change the runtime behavior of the program, which in turn means (especially in conjunction with caching of compilation artifacts, which is critical to compilation speed) that evaluation on your machine has to give the same answer as evaluating on any other machine would, even if that other machine has a different CPU architecture, or is wasm, etc.

view this post on Zulip Richard Feldman (Oct 23 2026 at 18:18):

  1. Is there anything I glossed over or just forgot about?

I actually don't think you need to do sans-io for this. You can do something much cooler, namely taking an existing Roc platform like basic-cli and making a drop-in replacement for DST (or even forking that platform to add a DST "mode") where basically it just replaces every single I/O operation with DST equivalents instead of doing the actual I/O, and then running the program tells you the output of the simulation

view this post on Zulip Richard Feldman (Oct 23 2026 at 18:19):

I'll build two small platforms: one is a simulator and one has the real networking etc.
The platforms will be deliberately small and only include the functionality I actually need.

this should also work fine, although if you wanted to do them both in the same platform, that should work too :smile:

view this post on Zulip Richard Feldman (Oct 23 2026 at 18:19):

it sounds like a really nice fit for Roc!

view this post on Zulip Jan Rüggeberg (Oct 23 2026 at 19:43):

I actually don't think you need to do sans-io for this. You can do something much cooler, namely taking an existing Roc platform like basic-cli and making a drop-in replacement for DST (or even forking that platform to add a DST "mode") where basically it just replaces every single I/O operation with DST equivalents instead of doing the actual I/O, and then running the program tells you the output of the simulation

Yeah I think you are right, I've thought about the abstractions one level too high. Namely something like send! which would then go to the platform and the platform can decide if it wants to use a sim, HTTP, RPC etc. for it.
AFAIK TigerBeetle and FoundationDB use the send abstraction, but I think in Roc I can actually make the sim at the Tcp.* function layer.

I think this will remove the ability from the platform to decide what protocol it uses for the sending. It also means HTTP needs its own sim, since the HTTP calls are not going through the Roc Tcp layer. But it could be a good design decision and would make the thesis claim even stronger.

I will explore it deeper, but I also need to make sure that the scope of the thesis does not explode.

This should also work fine, although if you wanted to do them both in the same platform, that should work too :smile:

Do you see any strong upsides in putting them in the same one?

view this post on Zulip Richard Feldman (Oct 23 2026 at 20:07):

main advantage would be that if I'm writing an application, I can have a way to DST it without needing to switch platforms (and hope the semantics accurately match on the drop-in replacement)

view this post on Zulip Luke Boswell (Oct 23 2026 at 21:53):

I have a platform that does this already, if you take a look at roc-signals it swaps out the host depending on what your target it. The app runs identically and has no way to know the host is different. If you target the web you get a WASM module for loading into the browser. If you target native you have a test harness which is driven deterministically through scripts written in S-expressions.

Also have a look at roc-gui that has a nicer builtin test harness.

I experimented previously which completely capturing and replaying everything crossing the boundary in roc-ray but I ripped it out because it was overkill for graphics and memory requirements we large with any decent duration of capture... but the idea worked really well.

Re Rust verse Zig I dont think there is too much of a difference, both will be a good choice for your use cass.

view this post on Zulip Luke Boswell (Oct 23 2026 at 21:54):

See https://lukewilliamboswell.github.io/roc-signals/docs/testing/

view this post on Zulip Luke Boswell (Oct 23 2026 at 21:55):

https://lukewilliamboswell.github.io/roc-gui/#_testing_your_application

view this post on Zulip Jan Rüggeberg (Oct 24 2026 at 17:03):

Thank you Luke, looks really cool!
I will definitely steal some stuff :)
I'll probably have some questions for you once I'm further into the project.


Last updated: Nov 04 2026 at 18:54 UTC