Stream: beginners

Topic: Getting started with a platform in C#


view this post on Zulip Cameron (Apr 23 2024 at 22:08):

Hello friendly people :wave:

How would I get started writing a platform in C#? I understand that there's no official support, but I'm not scared getting dirty using the C ABI and some unmanaged code.

Let's say I wanted to get applications written for basic-cli to run on a C# platform - what does this platform need? Are there any existing docs that I couldn't find?

I'll open source everything I can come up with, but I'm doing this to procrastinate other things so I can't promise following through until the end.

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:16):

There is an example dotnet platform https://github.com/roc-lang/examples/tree/main/examples/DotNetPlatform

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:16):

To support the same applications you will need to provide the same API from the platform.

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:20):

I'd recommend playing with the example platform, and testing out different things. To get something as complex as basic-cli you will likely need (want) a glue spec that can take the roc types and code gen the c# parts to interacts with roc. So that is something fun to also play with.

view this post on Zulip Cameron (Apr 23 2024 at 22:33):

Luke Boswell said:

There is an example dotnet platform https://github.com/roc-lang/examples/tree/main/examples/DotNetPlatform

Ha, then I am just blind. I've been staring at the Go example without knowing any Go :see_no_evil: Thanks!

Yeah, C# has roslyn source generators that can generate code at compile time based on resources files (like roc files!)
Do you know of any examples on how to make a glue spec for roc types? I assume I'd just need to represent the types in my platform roc API in C#.

Come to think of it: If I can get C header files, I can generate the C# bindings from that easily. Is there a way to generate C headers from Roc code?

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:37):

Coincidentally I just posted this a couple days ago https://roc.zulipchat.com/#narrow/stream/316715-contributing/topic/Glue.20generate.20Types.20in.20JSON/near/434573060

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:37):

Glue gen is a bit of a WIP so it's a bit wild rn, but if your up for a challenge it's super fun

view this post on Zulip Cameron (Apr 23 2024 at 22:45):

I've been staring at this for a little while and it looks really useful for all kinds of glue generation! I guess Str and Unit have a representation of [] because they are builtin types?

view this post on Zulip Cameron (Apr 23 2024 at 22:46):

Come to think of it, just generating C header files for roc types could help a lot, e.g. when using https://www.swig.org/

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:49):

Yeah, I think generating C types would be pretty handy.

view this post on Zulip Cameron (Apr 23 2024 at 22:55):

But I'd rather go the direct route for a nicer experience. In my fantasy world, I'd just add the platform roc files as additional files in my C# project, and all the C# glue would be auto-generated neatly as C# code that's not even on disk.
How would I get started with that? Do I need to write my own Roc parser in C#? Or can I go through your JSON route somehow?

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:56):

You can write your own DotNetGlue.roc plugin which takes the types from the roc compiler and generates the c# code.

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:57):

There is a RustGlue.roc and a ZigGlue.roc example in https://github.com/roc-lang/roc/tree/main/crates/glue/src

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:57):

In that other thread I made a JsonGlue.roc

view this post on Zulip Luke Boswell (Apr 23 2024 at 22:59):

When that PR lands, or if you use that branch, being able to just Inspect.toStr or Encode.toBytes on the types will help with figuring out what the types are for a given platform.

view this post on Zulip Luke Boswell (Apr 23 2024 at 23:00):

Say you write a DotNetGlue.roc and have a test platform test-platform.roc in your current directory. You can generate the glue using roc glue DocNetGlue.roc glue/ test-platform.roc and that will run the plugin/app.

view this post on Zulip Cameron (Apr 23 2024 at 23:12):

Thanks a lot! I'll look into it over the coming days, whenever the need to procrastinate strikes again :grinning_face_with_smiling_eyes:

view this post on Zulip Luke Boswell (Apr 23 2024 at 23:12):

You will also need to know how roc behaves with these types.

@Brendan Hansknecht went through a nice explanation in the recent online meetup for how roc represents the Str type and how seamless slices work.

You can find the implementation for the builtins at https://github.com/roc-lang/roc/tree/main/crates/compiler/builtins/bitcode/src

For example if you wanted to write a function that takes a Str and tells you if it is a seamless slice you might find the implementation in str.zig helpful.

pub fn isSeamlessSlice(self: RocStr) bool {
    return !self.isSmallStr() and @as(isize, @bitCast(self.length)) < 0;
}

Last updated: Jul 06 2025 at 12:14 UTC