Stream: platform development

Topic: How to write a platform


view this post on Zulip Stephen (Feb 12 2024 at 14:22):

Hello everyone, great to be here. Trying to understand how Roc works with platforms and I'm pretty excited about the possibility of writing my own platform specifically with Zig.

Is there any documentation on how to do this?

Reading through some existing platforms, I see that there's some boilerplate around malloc and free, but I'm most confused about

  1. How the glue works
  2. How to export functions from the platform for use in the application
  3. What can the Roc program provide to the host platform (mainForHost?)

view this post on Zulip Anton (Feb 12 2024 at 14:48):

Hi @Stephen :)

Is there any documentation on how to do this?

No, we're making big changes in how platforms work so we delayed writing docs for it.
This is a recent example of how you can set up a zig platform so I recommended looking at that for guidance.

  1. How the glue works

Glue code allows the Roc program to talk with the platform written in Rust, Zig...
Automatic generation of Glue code (WIP) is currently only available for Rust.

  1. How to export functions from the platform for use in the application

Example of the Zig part.
Corresponding Roc part

  1. What can the Roc program provide to the host platform (mainForHost?)

Anything your heart desires :)

view this post on Zulip Luke Boswell (Feb 12 2024 at 19:51):

I wrote this article https://lukewilliamboswell.github.io/roc-ray-experiment/ to capture some of the lessons I've learnt about platform development. Writing platforms in Zig is super fun, let me know if you have any questions.

view this post on Zulip Stephen (Feb 12 2024 at 20:12):

Thank you @Anton and @Luke Boswell
I'll take a look at these :pray:

view this post on Zulip Albert (Jun 03 2024 at 16:08):

If I want to implement a Rust platform, how do I get started?

view this post on Zulip Hristo (Jun 03 2024 at 18:22):

Albert said:

If I want to implement a Rust platform, how do I get started?

All messages from this thread so far do apply to Rust as well.
Additionally, you might be interested in the second talk by @Luke Boswell from last month's meetup.

view this post on Zulip Luke Boswell (Jun 03 2024 at 21:28):

I also have a template repository for rust which has most of the parts ready to go

https://github.com/lukewilliamboswell/roc-platform-template-rust

view this post on Zulip Albert (Jun 13 2024 at 18:15):

Just watched the vid. So now I understand that Roc cli/compiler has 2 jobs.

view this post on Zulip Albert (Jun 13 2024 at 18:16):

  1. compile the roc app code to a shared object
  2. link the precompiled host binary to the shared object

view this post on Zulip Albert (Jun 13 2024 at 18:16):

which is exactly the opposite of Deno/Browser that takes JavaScript as data and run it in memory.

view this post on Zulip Albert (Jun 13 2024 at 18:17):

when the host code interacts with roc app code, the source is long gone

view this post on Zulip Albert (Jun 13 2024 at 18:17):

It's more like a FFI

view this post on Zulip Albert (Jun 14 2024 at 07:25):

so I am writing a new kind of communication software (chat + social media) that is decentralized (meaning local-first, client-first, not blockchain)

view this post on Zulip Albert (Jun 14 2024 at 07:26):

the protocol is https://nostr.com/

view this post on Zulip Albert (Jun 14 2024 at 07:26):

my software is https://blowater.app/

view this post on Zulip Albert (Jun 14 2024 at 07:27):

However, after 1.5 years of work, I have realized that the Browser platform is fundementally not friendly to local-first software

view this post on Zulip Albert (Jun 14 2024 at 07:27):

  1. The network API is so old and bad. WebSocket implementation in Web API is just very bad for robust networking.
  2. The storage API (IndexedDB) is also bad and slow as hell
  3. Browser is not that safe once you have lots of extensions. But a decentralized app needs to handle private keys. Therefore, I want to build cryptogrphic APIs and key storage into the platform itself.

view this post on Zulip Albert (Jun 14 2024 at 07:28):

The JavaScript language is also just not a good language to implement super robust software (the client needs to handle 2GB+ data locally)

view this post on Zulip Albert (Jun 14 2024 at 07:29):

Roc looks like a super good fit for my project because

  1. It has the separation of platform and app at the top level of design
  2. The language itself is safer and more robust to handle data (pattern matching)

view this post on Zulip Albert (Jun 14 2024 at 07:30):

So, I want to implement a platform that's basically like a Browser, but using Roc for scripting, providing modern network & storage APIs

view this post on Zulip Albert (Jun 14 2024 at 07:30):

along with a GUI layer

view this post on Zulip Albert (Jun 14 2024 at 07:31):

It's not a hobbyst project, I am very serious with real budget behind it

view this post on Zulip Albert (Jun 14 2024 at 07:32):

But, I don't understand Rust nor Zig enough to get started, even if @Luke Boswell 's template. I need more help.

For example
image.png
Now I know that let out = call_the_closure(buffer); will run the Roc code.

But I don't understand

  1. how to add a new platform API in the Rust code.
  2. Why does the platform have Roc code as well in the platform dir? I thought platform should not have Roc at all.

view this post on Zulip Albert (Jun 14 2024 at 07:40):

I have been following Roc for 2 years and have watched @Richard Feldman 's talks since the Elm days btw. Now Roc feels like mature enough, at least for me, to work on.

view this post on Zulip Albert (Jun 14 2024 at 07:45):

As for the GUI layer, I am thinking about something like Egui or the GPUI from Zed editor. GPUI uses Egui as well. Just need to figure out what's the best API for Roc to consume.

view this post on Zulip Albert (Jun 14 2024 at 07:46):

Egui can run on Android now, so if we can implement a Rust Egui platform for Roc, maybe Roc can run on Android as well. iOS is always another beast.

view this post on Zulip Albert (Jun 14 2024 at 07:47):

But, if we can achieve it, it's 100X better than Flutter which is a good platform with a horrible language. Dart is the worst part of Flutter in my opinion.

view this post on Zulip Albert (Jun 14 2024 at 07:48):

If this is possible and exciting to you, please let me know. I need help to get started.

view this post on Zulip Luke Boswell (Jun 14 2024 at 08:26):

I've been very motivated by the idea of a GUI platform for roc. I've done a few experiments over the last couple of years to learn more about platform development and generally explore the space. I think it'd be super cool if we had a decent GUI platform. Roc is 100% a great fit for this in my opinion.

You may find Richard's Action-State design proposal an interesting read. It's a design for how GUIs might work in Roc (necessarily different from Elm).

I've built a PoC using raylib lukewilliamboswell/roc-ray. That platform works well and there is nothing really stopping it today from being a great graphics platform. It just needs some polish, more API coverage, an upgrade to a later zig version and a release. For the GUI parts, unfortunately we would need a pure roc layout implementation, something like flutter's layout algorithm would be good I think. Thought raylib is definitely not aimed at making modern/pretty looking GUI's.

The project I have been watching closely and think will be most suitable is linebender/xilem which brings together a lot of the GUI efforts from across the Rust ecosystem. They recently launched at RustNL, and there has been a lot of active development since then. I haven't had a chance to experiment with it (works been busy lately). I started early with this https://github.com/lukewilliamboswell/roc-masonry-experiment and my plan was to upgrade that to xilem and generally clean it up -- similar to how I've cleaned up the rust template (which has the latest and greatest).

One potential issue is that glue gen is still a WIP and needs to mature more. Writing types for interfacing between Roc and Rust by hand is the most reliable method, but also can be tedious. I started on https://github.com/lukewilliamboswell/roc-glue-code-gen with the goal to work on glue, but that turned into making template repositories. Actually fixing the glue generation requires a level of rust knowledge that I don't have right now.

Bit of a random collection of thoughts, but hope that helps.

view this post on Zulip Albert (Jun 14 2024 at 09:18):

Is glue compiled to the host or to the app binary?

view this post on Zulip Albert (Jun 14 2024 at 09:19):

or the GUI parts, unfortunately we would need a pure roc layout implementation, something like flutter's layout algorithm would be good I think.

Why? Is it because this approach is more cross platform? So that the host just take the pixel computed by the Roc GUI lib and draw it?

view this post on Zulip Albert (Jun 14 2024 at 09:21):

https://opensats.org/blog/opensats-receives-additional-funding-of-dollar21m-from-startsmall

view this post on Zulip Albert (Jun 14 2024 at 09:21):

Jack Dorsey is bootstrapping the Nostr ecosystem with additional 5M donations, on top of 5M last year.

view this post on Zulip Albert (Jun 14 2024 at 09:22):

There is real needs to implement a simpler, safer hosting environment for micro apps

view this post on Zulip Luke Boswell (Jun 14 2024 at 09:23):

Is there a plan for helping people manage public/private keys? That sounds like a challenge for new users. Or is the idea generally that identity will be more temporary.

view this post on Zulip Albert (Jun 14 2024 at 09:24):

Currently, with Browser apps, the private key is either stored by an extension or by the app itself which are not safe in both ways

view this post on Zulip Albert (Jun 14 2024 at 09:24):

In mobile and desktop, keys are stored by the apps

view this post on Zulip Albert (Jun 14 2024 at 09:24):

So, if you use the same key on many apps, you increase the danger of a key exposure

view this post on Zulip Albert (Jun 14 2024 at 09:25):

It's not like a blockchain that if you expose your key, you just transfer your fund as quick as possible to a new key

view this post on Zulip Albert (Jun 14 2024 at 09:25):

It's social media, if you expose your key, your identity is compromised forever

view this post on Zulip Albert (Jun 14 2024 at 09:26):

The user can generate a new key and start fresh but all the historical data is now accessible by the theft

view this post on Zulip Albert (Jun 14 2024 at 09:26):

With a Roc platform, I can minimize the attack surface

view this post on Zulip Luke Boswell (Jun 14 2024 at 09:26):

Albert said:

Is glue compiled to the host or to the app binary?

Glue is a feature of the roc cli that provides all of the Roc types for a given platform. So we can write plugins that code gen the equivalent host code to interface with the platform. I.e. have a glue plugin that will code generate rust code implmentation for that specific platform.

But it's a WIP and generally not very mature right now.

view this post on Zulip Albert (Jun 14 2024 at 09:27):

Luke Boswell said:

Albert said:

Is glue compiled to the host or to the app binary?

Glue is a feature of the roc cli that provides all of the Roc types for a given platform. So we can write plugins that code gen the equivalent host code to interface with the platform. I.e. have a glue plugin that will code generate rust code implmentation for that specific platform.

But it's a WIP and generally not very mature right now.

I still don't get it but I will learn more LOL

view this post on Zulip Albert (Jun 14 2024 at 09:28):

Albert said:

With a Roc platform, I can minimize the attack surface

Having key management built-in to the platform is separated from a GUI platform

view this post on Zulip Albert (Jun 14 2024 at 09:29):

Having a GUI platform is the 1st step, then I can import the GUI platform as a library and build key management on top of it

view this post on Zulip Albert (Jun 14 2024 at 09:29):

It's like Ark forks Chromium

view this post on Zulip Albert (Jun 14 2024 at 09:29):

However, I am not sure if I should choose Rust or Zig

view this post on Zulip Albert (Jun 14 2024 at 09:30):

Rust should be safer to write considering that this platform will load arbitrary Roc code

view this post on Zulip Albert (Jun 14 2024 at 09:30):

The use case is to dynamically load remote Roc code instead of compiling into the same binary

view this post on Zulip Albert (Jun 14 2024 at 09:31):

Similar to @Richard Feldman 's idea of writing editor extensions in Roc

view this post on Zulip Albert (Jun 14 2024 at 09:31):

If we do a good job, we can support both compilation mode (like electron) and dynamic mode (like browser)

view this post on Zulip Albert (Jun 14 2024 at 09:32):

Then we can get rid of both React Native and Flutter

view this post on Zulip Luke Boswell (Jun 14 2024 at 09:34):

Another approach is to write native apps using SwiftUI, or Kotlin and then use roc as a plugin. Using the same API would mean the roc parts can be identical, and defer mobile platform specific things to the platform.

view this post on Zulip Luke Boswell (Jun 14 2024 at 09:35):

Developing the platform in a mature ecosystem like Swift will be a nice experience. I've got a template platform for Swift and it works nicely.

view this post on Zulip Albert (Jun 14 2024 at 09:36):

Luke Boswell said:

Another approach is to write native apps using SwiftUI, or Kotlin and then use roc as a plugin. Using the same API would mean the roc parts can be identical, and defer mobile platform specific things to the platform.

If I can keep 90%+ of my code in Roc and just interfacing Kotlin or Swift platforms, that's also good

view this post on Zulip Albert (Jun 14 2024 at 09:48):

I am not familiar with mobile so desktop platforms will be my 1st target. I need

  1. http request (which the cli platform already has)
  2. websocket
  3. GUI (very challenging)
  4. cryptography
  5. storage (like a built-in database, the SQLite demo was nice. But I might need to implement my own database on top of a KV )

so, maybe I can start to add websocket to the CLI platform to learn

view this post on Zulip Albert (Jun 14 2024 at 09:52):

@Richard Feldman said there was no cross-platform Roc app. Can I interpret it as that if I want cross platform Roc. I can wirte the shared part as a Roc library and 2 separate Roc app that interface the platform IO and just import the Roc library?

view this post on Zulip Albert (Jun 14 2024 at 09:52):

This design force the coder to push IO/Side Effects to the most outside of the system

view this post on Zulip Albert (Jun 14 2024 at 09:53):

What about async code? Can I have async code in a Roc library because it's an effect?

view this post on Zulip Luke Boswell (Jun 14 2024 at 10:05):

If your interested in how cross-platform could work, and looking for a larger and more mature example, checkout imclerran/roc-start. That's a nicely written roc app that runs on all of the targets supported by basic-cli, so currently linux/macos OS and x64/arm64 ARCH. The basic-cli platform provides pre-built binaries for various OS/ARCHs so the same roc app can run on all of those without needing to change anything. Indeed, it's easy to cross-compile from a macos to build a binary for linux using just the roc cli.

view this post on Zulip Luke Boswell (Jun 14 2024 at 10:06):

E.g roc build --target=linux-x86 src/main.roc

view this post on Zulip Anton (Jun 14 2024 at 14:47):

What about async code? Can I have async code in a Roc library because it's an effect?

Others are welcome to correct me, but I believe that will be possible once Task is a builtin. :thinking: What are the blockers on that? I could not find a tracking issue.

view this post on Zulip Brendan Hansknecht (Jun 14 2024 at 15:40):

Not just task as a built-in, needs the full effect interpreters setup.

Theoretically it could be manually done today (I did it with some future testing, but it is not a nice experience)

view this post on Zulip Brendan Hansknecht (Jun 14 2024 at 15:52):

A few random other answers:

  1. A platform has roc code in it cause it needs to define the API between roc and the underly language. It also is allowed to define arbitrary roc libraries.
  2. Pure roc layout logic is not required for any of this. Might be nice to have, but layout logic can be manually done or dealt with in the platform. Doing it purely in roc could help with consistency across devices. This is especially true if building multiple device specific platforms.
  3. While this project could probably be forced in current day roc, I honestly believe we are early for this project. That said, if you are willing to force it, or will to also help contribute to fixes in the compiler you need, definitely in the realm of doable.
  4. Glue generates code in the host language that helps deal with ffi from the host to the app.

view this post on Zulip Albert (Jun 14 2024 at 17:08):

Brendan Hansknecht said:

A few random other answers:

  1. A platform has roc code in it cause it needs to define the API between roc and the underly language. It also is allowed to define arbitrary roc libraries.
  2. Pure roc layout logic is not required for any of this. Might be nice to have, but layout logic can be manually done or dealt with in the platform. Doing it purely in roc could help with consistency across devices. This is especially true if building multiple device specific platforms.
  3. While this project could probably be forced in current day roc, I honestly believe we are early for this project. That said, if you are willing to force it, or will to also help contribute to fixes in the compiler you need, definitely in the realm of doable.
  4. Glue generates code in the host language that helps deal with ffi from the host to the app.

I guess I should just start with adding some dumb APIs to the Rust template and get a feel with Roc

view this post on Zulip Brendan Hansknecht (Jun 14 2024 at 17:15):

Yeah..or as you said, add websockets to basic cli

view this post on Zulip Albert (Jun 16 2024 at 06:11):

What is a effect interpreter ?

view this post on Zulip Albert (Jun 16 2024 at 06:17):

https://github.com/lukewilliamboswell/roc-platform-template-rust/blob/9e445264138f75477121ff6f1caf2cc1c250fdaa/platform/Stdout.roc#L2

view this post on Zulip Albert (Jun 16 2024 at 06:18):

This syntax module [line, Err] is not described in https://www.roc-lang.org/tutorial#modules

view this post on Zulip Albert (Jun 16 2024 at 06:19):

That's the difference between module [name], exposes [name] and exposing [name]?

view this post on Zulip Luke Boswell (Jun 16 2024 at 06:31):

That syntax is just a regular module https://www.roc-lang.org/tutorial#regular-modules

view this post on Zulip Luke Boswell (Jun 16 2024 at 06:31):

Unfortunately that part of the tutorial needs some love :sad:

view this post on Zulip Luke Boswell (Jun 16 2024 at 06:32):

An effect interpreter is a large upgrade to roc that has been in development for some time. It will change the way the host in the platform is written and enable fully async execution of effects.

view this post on Zulip Albert (Jun 16 2024 at 06:39):

Luke Boswell said:

Unfortunately that part of the tutorial needs some love :sad:

LOL

view this post on Zulip Albert (Jun 16 2024 at 06:39):

Luke Boswell said:

An effect interpreter is a large upgrade to roc that has been in development for some time. It will change the way the host in the platform is written and enable fully async execution of effects.

Is this related to that host API implementations are not async at the moment?

view this post on Zulip Albert (Jun 16 2024 at 06:39):

https://github.com/roc-lang/basic-cli/blob/307f1f91d984ac966cca75a40d403bdced1f05a6/platform/src/lib.rs#L632

For example, I am looking at the http request implementation of basic cli

view this post on Zulip Albert (Jun 16 2024 at 06:40):

Is host API execution blocking at the moment?

view this post on Zulip Albert (Jun 16 2024 at 06:40):

Is there an article or design draft of  effect interpreter that I can read?

view this post on Zulip Albert (Jun 16 2024 at 06:43):

image.png
Is this code also the code used in the Roc compiler or written only for platform development purpose?

view this post on Zulip Brendan Hansknecht (Jun 16 2024 at 16:23):

Mostly for platform development, but the roc compiler uses it in some places

view this post on Zulip Brendan Hansknecht (Jun 16 2024 at 16:23):

And yeah, lack of effect interpreters is why every effect is synchronous currently

view this post on Zulip Albert (Jun 17 2024 at 05:19):

Is parallelism also the decision of the platform?

view this post on Zulip Brendan Hansknecht (Jun 17 2024 at 05:39):

Yes

view this post on Zulip Brendan Hansknecht (Jun 17 2024 at 05:41):

For example, basic webserver is automatically multi threaded, but gives the requests no control over concurrency.

view this post on Zulip Brendan Hansknecht (Jun 17 2024 at 05:41):

Long term, it will likely support better async effects, but it might never support spawning arbitrary threads

view this post on Zulip Brendan Hansknecht (Jun 17 2024 at 05:42):

Basic CLI on the other hand is single threaded by default but plans to support spawning tasks that can run in parallel (multi threaded communication architecture unclear at the moment)

view this post on Zulip Anton (Jun 17 2024 at 09:39):

Is there an article or design draft of  effect interpreter that I can read?

Do we have a google doc for this @Richard Feldman?

view this post on Zulip Richard Feldman (Jun 17 2024 at 12:47):

hm I don’t think so!

view this post on Zulip Brendan Hansknecht (Jun 17 2024 at 15:25):

You would really think after all of this discussion in various threads that we would have something written up.

view this post on Zulip Brendan Hansknecht (Jun 17 2024 at 15:25):

I guess the only write up is the small summary here: https://www.roc-lang.org/plans

view this post on Zulip Albert (Jun 18 2024 at 01:26):

The name "interpreter" does not convey what it does under the hood

view this post on Zulip Brendan Hansknecht (Jun 18 2024 at 02:30):

It is essentially a standard async state machine. The reason for the word "interpreter" is that the platform is essentially implementing an interpreter to run the state machine that executes roc code and effects.

view this post on Zulip Albert (Jun 20 2024 at 07:02):

What is the Rust representation of a Roc record in the basic-cli?

view this post on Zulip Luke Boswell (Jun 20 2024 at 08:04):

If you have the following Roc record

MyRecord : {
    age: I64,
    name: Str,
}

In rust this would be

#[repr(C)]
struct MyRecord {
    age: i64,
    name: roc_std::RocStr,
}

view this post on Zulip Luke Boswell (Jun 20 2024 at 08:05):

fields are sorted alphabetically

view this post on Zulip Albert (Jun 20 2024 at 08:29):

So I simply return a RocResult<MyRecord, RocError> in the rust platform lib?

view this post on Zulip Luke Boswell (Jun 20 2024 at 08:30):

I'm not sure what you are doing, but that looks ok to me.

view this post on Zulip Oskar Hahn (Jun 20 2024 at 09:14):

I think, that the fields are not only sorted alphabetically, but also be size in memory. If I am correct, then "name" will be before "age".

view this post on Zulip Albert (Jun 20 2024 at 15:30):

Luke Boswell said:

I'm not sure what you are doing, but that looks ok to me.

I am trying to expand the file API of the basic cli to return metadata of the file as well

view this post on Zulip Albert (Jun 20 2024 at 15:31):

It can be a useful small tool to check duplicated files

view this post on Zulip Brendan Hansknecht (Jun 20 2024 at 21:12):

They are sorted by alignment and name.

age -> i64, aligned to 8 bytes
name -> Str, aligned to 8 bytes as well (cause it is a pointer and 2 i64s)

So should be age then name.

view this post on Zulip Anton (Jun 21 2024 at 10:53):

Do we have a file people can check to find the alignment for a type?


Last updated: Jul 05 2025 at 12:14 UTC