Stream: beginners

Topic: Platform Clarification


view this post on Zulip Undefined Behavior (Mar 15 2025 at 22:37):

Roc beginner here

From https://www.roc-lang.org/platforms, I get the notion that "platforms" really modularize Roc's capabilities.

The stdlib doesn't ship with concurrency primitives, but if someone wanted to implement Golang-esque Channels or an Actor Model, platforms would be the way to do that?

view this post on Zulip Luke Boswell (Mar 15 2025 at 22:54):

Yeah thats the plan :+1:

view this post on Zulip Undefined Behavior (Mar 15 2025 at 22:57):

that's so cool!

view this post on Zulip Luke Boswell (Mar 15 2025 at 23:39):

Yeah, its going to really cool when we're back at the stage with a working zig compiler people can start building platforms again. We've learnt a lot about how to architect things so its much easier and more performant. I'm pretty sure we'll see lots of awesome experimental platforms soon, testing out different ideas and ways to use roc.

view this post on Zulip Adam Forbes (Apr 14 2025 at 02:56):

Hey all!

Just figured I add to this topic... First off, amazing language, love the overall idea/syntax/etc. (I'm a big Elm fan, also love Elixir.)

So, yeah, I guess I have a question re: platform concept. It seems like the idea is that an application has one and only one "platform"?

I'm not 100% sure this makes total sense to me? I'm sure this has all been debated and discussed at length, so I apologize in advance if this is just a rehashing of old dialogues!

Take two examples. First, Python. The way most people use Python is more like a wrapper to other native code, e.g. C and bit of Fortran (Numpy), C++ & CUDA (PyTorch), Rust (Polars), etc.

Second, the NodeJS alternative Bun, which uses Zig as the glue. If you go to their home page, they are touting Bun's performance on three things: Express (e.g. webserver), Postgres, and WebSockets.

The Bun webserver is literally µWebSockets (written in C++), which I think is a bit... uncool? that they don't really say that, and the websocket server is likewise literally µSockets (written in C), again, odd that they don't spell that out, while Postgres in an internal Zig library.

My point is, that from the user's perspective, you just import them as regular libraries and use them, unaware that they are written in different languages (C++, C and Zig) under the hood.

(I get that Zig is amazing at gluing all this together!)

But I guess my point is that, personally, the idea of having a single "server platform" that has all of these things baked in (e.g. web, ws, sql, etc) seems logical? And likewise, that you could then add your own independently without having to edit the main "platform"?

As opposed to having a bunch of independent backends (platforms) that only do a small part of what you need? Like why is the "webserver" platform different from the "cli" platform?

In my experience, backend code evolves, so at first may only need one thing (e.g. web server), but then you need access to a db, local file access, a pdf generator, S3 access, a job queue, ftp access, image generators, an in-memory db, etc. So if each of those things require side effects, then it seems like you need a way to add them w/o requiring someone to understand the "platform"? For example, maybe the main platform is Rust, but I am XYZ programmer and want to use another language for a job queue.

For me, I mentally compare Roc against the various other backend language and ecosystems like Python, Node, Elixir, Rust, Go, etc. , and am just thinking about how the Roc platform concept either helps or hinders the idea of using Roc as a potential replacement for say Node in the long term.

Thanks in advance for thoughts! :)

view this post on Zulip Brendan Hansknecht (Apr 14 2025 at 03:37):

Two core thoughts here. Just to give a super quick answer. One more theoretical and one more technical.

Firstly, think of Elm. A gigantic part of the reason elm is amazing is that it has exactly one "platform". Elm curates your entire experience in building a web app. This curation is what leads to elm being an amazing and delightful experience. Any time you have to leave the curation bubble and interact with JS, life gets worse. Roc is the same way. It just has many potential platforms. Each platform tries to curate in a way to make an amazing experience. The platform can still add escape hatches if it wants (raw access to os primitives, libffi support, etc). But using those escape hatches will be painful in comparison to staying within the curated experience. Since roc is such a young language, most platforms only have the curated expecience (that said, the curation is not always the best and as nice as something like elm).

On the technical side, ultimately roc is producing a single executable. An executable can only have one main function and has to compile into a single binary on the machine. The platform controls all of this. As such, two platforms in one executable does not make technical sense. How would I create an application with two main functions? which would run?

view this post on Zulip Brendan Hansknecht (Apr 14 2025 at 03:38):

So one platform is more of a fundamental constraint. That said, we could definitely make escape hatches easier if we wanted (we don't though).

view this post on Zulip Brendan Hansknecht (Apr 14 2025 at 03:40):

One could make the ultimately flexible roc platform if they wanted, it would be a main function and only expose a wrapper around libffi. With that, all c ffi compatible code would be accessible. It would be a horrible experience, but it would fundamentally be able to talk to essentially all software and do anything. No platform yet exposes libffi, but I expect it to eventually happen for a super flexible escape hatch.

view this post on Zulip Luke Boswell (Apr 14 2025 at 03:47):

I think another aspect of this is the ecosystem being pure roc... the boundary for API's moves a little up to a higher abstraction. So platforms will tend to provide lower level primitives, and that means more functionality can be provided by cross-platform libraries.

For example, any platforms that provide TCP-like primitives can probably support a large number of roc packages and functionality from interfacing with SQL servers, sending HTTP requests, etc.

From an app authors perspective the focus in more on higher level functionality and integrating libraries.

If more flexibility is required than the platform (or a cross-platform package) provides, I expect it to be common to fork the platform and easily implement customised parts for a particular use-case.

view this post on Zulip Adam Forbes (Apr 14 2025 at 03:57):

Cool. Makes sense! Yes, that is a good analogy re: Elm and JS.

Also, the single executable... interesting...

Yeah, I mean (now responding to Luke), if the whole goal of Roc is to be super-fast (e.g. faster than Go, I believe Richard said), then the idea of providing a platform with a low level set of system primitives (including TCP, etc) would encourage the writing of a web server in Roc, websockets in Roc, sql client in Roc, etc.

Personally, the idea of forking a platform sounds seems... counter-intuitive? I'd think you'd want a small number of very low level, bulletproof platforms? Like "server", "wasm", "embedded", "browser", that kind of thing?

Anyway, thanks for the thoughts!

view this post on Zulip Brendan Hansknecht (Apr 14 2025 at 04:04):

Yeah, a lot of possiblities. One is the low level apis and all roc. Another is more high level bespoke experiences, but maybe with more restrictions. I think it will be a mix of both in practice depending on the exact goals

view this post on Zulip Luke Boswell (Apr 14 2025 at 04:37):

I think it's a nice feature that both are totally reasonable options with Roc and have different trade-offs.

I can start with a friendly batteries included web-server, and if my needs outgrow that I can roll over the top with an more customised platform that suits my needs (tuned for performance or provides unique capabilities).

view this post on Zulip Tib (Apr 14 2025 at 08:30):

Ok but imagine I need a redis server, a mysql db, a web server and say... an access to the sound card. Then I have to create my own platform ?

view this post on Zulip Anton (Apr 14 2025 at 09:38):

view this post on Zulip Adam Forbes (Apr 14 2025 at 13:00):

Cool. Yeah, Cmd is a necessary escape hatch, and could handle lots of "fork/exec" stuff, e.g. calling ffmpeg, etc. As long as you use Cmd for "slow" stuff & have a worker pool in front of it, should be fine.

I guess it comes down to really asking the question: "What is the first world real use-case for Roc?"

For example, Elixir was trying to replace Ruby on Rails. So the first real world "test" of the Elixir language was the creation of the Ecto library, an ORM for sql, as that was seen as a fundamental requirement to build a web server backends and ultimately replace rails.

As everything I work on tends to be... API driven? E.g. web server serving JSON, HTML, handling Websockets & calling a bunch of stuff on the backend behind the scenes, I look at languages through that lens. (Obviously Async + green threads (or imitate Tokio) is all key for this kind of stuff.) As opposed to writing a command line util, etc.

So that's why when I view of Roc, I am looking at to see how it would ultimately compare to say Node, Phoenix/Elixir, Go, etc.

Maybe that's not the goal! Maybe the goal is embedded dev! Or build tools like Vite. Or writing compilers, like Microsoft just moved the Typescript compiler to Go. Or writing GPU code, like Mojo. Etc.

But in general, I think working backward from a goal is a good strategy :)

I guess with the Platform concept, the idea is you can kick this can down the road? E.g. once the language and Platform interfaces is solid, then someone can write an "async networking platform" that would allow someone to build a batteries-included web framework?

view this post on Zulip Fábio Beirão (Apr 14 2025 at 13:04):

Just adding two cents here. The way I see it, in Elm you kind of already have this ""platforms"" concept. I recently had to do a headless Elm application and I ended up using Platform.worker instead of Browser.application.
It's still Elm, you just don't get a view function.
What I love about the ROC idea on platforms is that I can see in one place (Main module) where have we taken the "capabilities" from the platform and to which libraries/functions have they been passed to. Please don't ever let go of that core principle 🙏🏻

view this post on Zulip Anton (Apr 14 2025 at 13:26):

But in general, I think working backward from a goal is a good strategy :)

I like exploration, we've got this pretty unique setup, let's explore where it's strength and weaknesses are. Relatedly on this philosophy, I love the book "Why Greatness Cannot Be Planned".

view this post on Zulip Adam Forbes (Apr 14 2025 at 13:28):

Anton said:

I love the book "Why Greatness Cannot Be Planned".

Will check it out! Love the concept! :)

view this post on Zulip Anton (Apr 14 2025 at 13:28):

An "async networking platform" may now be possible with atomic refcounting, cc @Brendan Hansknecht. But it currently requires significant expertise or a lot of motivation and it's not a priority for the core team right now.

view this post on Zulip Brendan Hansknecht (Apr 14 2025 at 19:26):

Yeah, should be possible to build now. You could theoretically unleash the full power of go as a platform for roc.

view this post on Zulip Anthony Bullard (Apr 16 2025 at 02:21):

You could probably use something like https://github.com/anthdm/hollywood as inspiration

view this post on Zulip Anton (Apr 16 2025 at 09:21):

Accessible actors in Roc could be something people really enjoy, the mental model is so much easier compared to how threads are typically used.

view this post on Zulip Fábio Beirão (Apr 16 2025 at 09:36):

In the dotnet ecosystem I am really enjoying Microsoft Orleans (virtual actors) https://learn.microsoft.com/en-us/dotnet/orleans/overview
It kind of side-steps the whole supervision tree from Erlang/Akka, of course with its own trade-offs. But the mental model did indeed click hard (hard to go back :sweat_smile:)

view this post on Zulip Anthony Bullard (Apr 16 2025 at 10:53):

Implementing an actor model platform for Roc is one of my main goals (or at least to see one be implemented)

view this post on Zulip Anthony Bullard (Apr 16 2025 at 10:54):

Just helping the language be stable syntax-wise before I even start on it

view this post on Zulip Anthony Bullard (Apr 16 2025 at 10:55):

A Purely Functional Actor system is my dream

view this post on Zulip Anthony Bullard (Apr 16 2025 at 10:56):

Imagine being able to property test all the concurrent behaviors of every component of your system...

view this post on Zulip Anthony Bullard (Apr 16 2025 at 10:58):

I like to think of it as a bunch of little Elm programs communicating with type safe messages in a massively concurrent way

view this post on Zulip Anton (Apr 16 2025 at 10:59):

That sells it well :) (If you know Elm :big_smile: )

view this post on Zulip Anthony Bullard (Apr 16 2025 at 11:00):

I hope it will. I tried to build it from soup to nuts myself, but I'm much happier doing it in steps with this community

view this post on Zulip Anthony Bullard (Apr 16 2025 at 11:01):

You could also say "communicating memory-isolated state machines"

view this post on Zulip Anthony Bullard (Apr 16 2025 at 11:03):

Or "event-driven architecture in the small"

view this post on Zulip Anton (Apr 16 2025 at 11:04):

"communicating memory-isolated state machines"

This seems the coolest

view this post on Zulip Fábio Beirão (Apr 16 2025 at 11:26):

"communicating memory-isolated state machines"

How familiar are you with Erlang processes? :sweat_smile:

view this post on Zulip Anthony Bullard (Apr 16 2025 at 21:57):

That’s the point. processes are (roughly) Actors

view this post on Zulip Anthony Bullard (Apr 16 2025 at 21:58):

They would be true Actors if they guaranteed in order processing of messages

view this post on Zulip Anthony Bullard (Apr 16 2025 at 22:02):

And that all messages are handled

view this post on Zulip Luke Boswell (Apr 17 2025 at 05:24):

"communicating memory-isolated state machines"

Isn't that the idea behind object oriented programming?

view this post on Zulip Anthony Bullard (Apr 17 2025 at 23:32):

It’s funny you say that. There is a discussion between Alan Kay and Joe Armstrong(creator of Erlang) about this very thing. The difference is communication between actors is always asynchronous and therefore coordinated.

view this post on Zulip Anthony Bullard (Apr 17 2025 at 23:33):

https://youtu.be/fhOHn9TClXY?si=xCQVAaC_7y1piomb


Last updated: Jul 06 2025 at 12:14 UTC