Stream: beginners

Topic: Building Roc apps into Otherlang libraries


view this post on Zulip jan kili (Sep 03 2022 at 02:34):

I just noticed the CLI flag to build your Roc app as a C library - that sounds cool! I don't remember that from Roc marketing or training materials, though. Could we build Zig libraries, too? Rust? (Context: I'm uninformed on most low-level language stuff)

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 02:46):

That probably doesn't mean what you think it means. You mean --lib, right? IIRC, that just builds a dynamic library.

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 02:46):

It talks c abi. Which is probably why it says a c library, but it really is just a standard dynamic/shared library

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 02:46):

It can be loaded by zig or c or rust and talked to with cffi like normal

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 02:46):

We are not emitting c or anything.

view this post on Zulip jan kili (Sep 03 2022 at 03:04):

Ah, yes, I did not envision it outputting uncompiled C source code. However, I maintain that this is super cool and (maybe) undersold in Roc's story!

view this post on Zulip jan kili (Sep 03 2022 at 03:06):

So far I've envisioned Roc as a valuable tool for any teams who want a lang upgrade or simply want to script/control an existing engine... but this opens a third category of use cases - incremental Roc-ification of a codebase!

view this post on Zulip jan kili (Sep 03 2022 at 03:07):

It sounds like one could have a dozen product features implemented in Rust/Zig/C and decide to implement the 13th feature in Roc???

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:07):

I mean it really is no different that current Roc really. It would be the exact same api. It just lives in a dynamic library instead of being surgically linked into the host.

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:07):

I guess a tad more dynamic

view this post on Zulip jan kili (Sep 03 2022 at 03:07):

My realization is that Roc doesn't have to own the entrypoint/callsite

view this post on Zulip jan kili (Sep 03 2022 at 03:08):

/executable

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:08):

What do you mean?

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:08):

Roc currently doesn't own the executable entry point. It is defined in rust or zig or c

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:09):

I guess we tend to currently have roc control the build process, but that isn't required.

view this post on Zulip jan kili (Sep 03 2022 at 03:09):

It sounds like we could take an existing codebase that doesn't use Roc, sprinkle some Roc goodness on it, and continue to run the service/product the same way (same entrypoint, same executable build pipeline, same everything external/interface-y) but with part of the compiled code sourcing Roc

view this post on Zulip jan kili (Sep 03 2022 at 03:10):

In my opinion, this is a massive boon for Roc's adoptability

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:11):

I guess? We also can emit a .o file. Which is probably better than a library in most cases

view this post on Zulip jan kili (Sep 03 2022 at 03:11):

I've never used Lua, so maybe analogies to Lua were supposed to elicit this realization earlier for me

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:12):

But yeah, long term, platforms should have more control on specifying the build process. That will likely help a lot. The current situation is all manually hacked into the compiler. When I targeted a microcontroller, I just used the .o file and an external build process

view this post on Zulip jan kili (Sep 03 2022 at 03:13):

Is there precedent for this style of language interop? All of cffi maybe, which I never looked into? All of these JVM-based FPLangs like Scala?

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:15):

I'm not sure I understand these questions.

view this post on Zulip jan kili (Sep 03 2022 at 03:15):

Can an existing Rust codebase call any compiled Roc app though not import from it?

view this post on Zulip jan kili (Sep 03 2022 at 03:15):

I might need to watch some videos on what cffi and .o are

view this post on Zulip jan kili (Sep 03 2022 at 03:16):

I'm coming from an understanding that scripting languages call systems languages, not the other way around.

view this post on Zulip jan kili (Sep 03 2022 at 03:16):

This breaks that distinction for me, in a very promising way :D

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:17):

When using the dynamic lib or .o, must of the rust code would not change. It still needs to define all of the roc_ functions. It also needs to define all of the headers to know how to call roc code. Roc require bidirectional communication

view this post on Zulip jan kili (Sep 03 2022 at 03:18):

(Note: I've known that Roc apps are actually called by Roc platforms, not the other way around at all. However, I assumed that Roc platforms could call same-lang codebases but not the other way around, due to a crude understanding of executable entrypoint.)

view this post on Zulip jan kili (Sep 03 2022 at 03:19):

Ah, so an existing codebase would need to do the minimal enhancements required to become a Roc platform?

view this post on Zulip jan kili (Sep 03 2022 at 03:21):

That helpfully erodes at my idea of Roc platforms being codebases focused on Roc... rather than just codebases that happen to have implemented the adaptations necessary to call Roc

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:22):

Your last comment hits the nail on the head. For example, you may work on a game and just use Roc as a scripting language, but you still implement an entire game. This is super specialized and would be fine without roc. Roc is just a nice addition.

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:24):

Let's see. The best way to think about this is probably to just consider Roc another package/library in the host language (even though it clearly isn't).

It is a package with a really weird api that imports a few functions (roc_alloc, roc_memcpy, ..., roc_fx_DoSometing) and exposes a few functions roc_main_for_host, etc.

view this post on Zulip jan kili (Sep 03 2022 at 03:24):

Yes, but critically, adding Roc doesn't make your codebase Roc-y and it doesn't create a scoped Roc zone that can't benefit existing code elsewhere

view this post on Zulip jan kili (Sep 03 2022 at 03:26):

The first example I heard about game dev was that devs could add a scripting language for game players/modders to use... but that didn't make me think that the game developers might want to refactor some of the game engine into Roc for maintainability or stability/security reasons

view this post on Zulip jan kili (Sep 03 2022 at 03:29):

So, following that simplification, if Roc is basically a Rust/Zig/C library... then a Roc app is basically a particular single data transformation plugin that the library can perform for a Rust/Zig/C codebase?

view this post on Zulip jan kili (Sep 03 2022 at 03:30):

If a Rust codebase calls 3 different Roc apps, will it need 3 "really weird api"s?

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:30):

It would be, but roc can also call effects. That enables it to do more than just transform data

view this post on Zulip jan kili (Sep 03 2022 at 03:31):

True, I suppose the Roc app is a data transformation but the Roc "library" uses the result of that data transformation to call effects on behalf of the codebase

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:32):

Also, roc is really not made with the idea of using multiple apps, though since they are just object files, I guess you could. You would probably have to be careful around name conflicts

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:33):

But yeah, you would need to define all effects expected from all roc apps. Though you would only define things like roc_alloc once.

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:33):

Also, you would have to deal with all the function calling code, but in the future hopefully glue will generate most of that

view this post on Zulip jan kili (Sep 03 2022 at 03:33):

I suppose it'd be easier to either have the main function switch on a tag or expose a record of functions, rather than using multiple apps

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:35):

Also, long term, roc should be able to expose multiple function directly rather than through main

view this post on Zulip jan kili (Sep 03 2022 at 03:37):

To summarize, any existing Rust/Zig/C(/C++?) codebase can add a few specific IO/memory-related (effect-related) functions and start adding new business logic features in Roc instead of in Rust/Zig/C (or refactoring old business logic into a superior language for it)

view this post on Zulip jan kili (Sep 03 2022 at 03:38):

#BigIfTrue

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:38):

Yeah

view this post on Zulip jan kili (Sep 03 2022 at 03:39):

That enables such a clear incremental adoption/upgrade/refactor story

view this post on Zulip jan kili (Sep 03 2022 at 03:41):

  1. Add some boilerplate to your codebase
  2. Write new business logic in Roc
  3. Your codebase is now technically also a Roc platform
  4. Be happier
  5. Refactor old business logic into Roc
  6. Your codebase is now ONLY a Roc platform
  7. Be happier

view this post on Zulip Brendan Hansknecht (Sep 03 2022 at 03:50):

Haha :joy: you make it sound so simple

view this post on Zulip jan kili (Sep 03 2022 at 04:00):

Hahahaha

view this post on Zulip Richard Feldman (Sep 03 2022 at 11:54):

yeah check out examples/ruby-interop - that incremental adoption thing is how we're working on using it at work!

view this post on Zulip jan kili (Sep 04 2022 at 02:44):

How simple can step 1 become? Can we create+publish+maintain libraries/codegen for that "setup step" (platformification) to become trivial? Is it already trivial by virtue of it requiring only copy/paste of less than 50 lines of code?

view this post on Zulip jan kili (Sep 04 2022 at 02:46):

I don't know how Rust/Zig/C/Ruby libraries work, but a two-liner like

import Roc
Roc.initializePlatform({ ... })

would be super cool

view this post on Zulip Ayaz Hafiz (Sep 04 2022 at 03:02):

The goal of roc glue is to make that step trivial!


Last updated: Jul 06 2025 at 12:14 UTC