roc/examples/hello-world
2022-06-12 16:09:44 +02:00
..
c-platform fix a complaint by my clang 2022-06-01 14:17:12 +02:00
rust-platform extend lifetime of string till end of block 2022-06-12 16:09:44 +02:00
swift-platform fixed hello swift 2022-06-01 17:15:52 +02:00
web-platform formatter: remove spaces at the beginning and end of single-line square bracket expressions 2022-05-22 14:06:34 +01:00
zig-platform formatter: remove spaces at the beginning and end of single-line square bracket expressions 2022-05-22 14:06:34 +01:00
.gitignore ignore all .wasm files in examples, rather than individual ones 2022-06-06 16:45:22 +01:00
helloWorld.roc formatter: remove spaces at the beginning and end of single-line square bracket expressions 2022-05-22 14:06:34 +01:00
README.md Rename hello examples from snake_case to camelCase for consistency 2022-03-07 21:10:19 -07:00

Hello, World!

To run, cd into this directory and run:

cargo run helloWorld.roc

To run in release mode instead, do:

cargo run --release helloWorld.roc

Design Notes

This demonstrates the basic design of hosts: Roc code gets compiled into a pure function (in this case, a thunk that always returns "Hello, World!\n") and then the host calls that function. Fundamentally, that's the whole idea! The host might not even have a main - it could be a library, a plugin, anything. Everything else is built on this basic "hosts calling linked pure functions" design.

For example, things get more interesting when the compiled Roc function returns a Task - that is, a tagged union data structure containing function pointers to callback closures. This lets the Roc pure function describe arbitrary chainable effects, which the host can interpret to perform I/O as requested by the Roc program. (The tagged union Task would have a variant for each supported I/O operation.)

In this trivial example, it's very easy to line up the API between the host and the Roc program. In a more involved host, this would be much trickier - especially if the API were changing frequently during development.

The idea there is to have a first-class concept of "glue code" which host authors can write (it would be plain Roc code, but with some extra keywords that aren't available in normal modules - kinda like port module in Elm), and which describe both the Roc-host/C boundary as well as the Roc-host/Roc-app boundary. Roc application authors only care about the Roc-host/Roc-app portion, and the host author only cares about the Roc-host/C boundary when implementing the host.

Using this glue code, the Roc compiler can generate C header files describing the boundary. This not only gets us host compatibility with C compilers, but also Rust FFI for free, because rust-bindgen generates correct Rust FFI bindings from C headers.