Hi, I'm still trying to figure out some basic stuff about writing platforms, especially the mapping of data types. Right now, I'm using C to write a host. If mainForHost
is a record type,
Type: { n: U64, str: Str }
say. I can treat it as a struct in my host.c
struct MyType {
int n;
struct RocStr str;
};
but what about union types. Lets say I have a mainForHost
of type
MyUnion: [A Str (List MyUnion), Div (List MyUnion)]
how can I treat that in my host.c?
int n;
-> uint64_t n;
myunion would be the union of a { RocStr; RocList}
with a { RocList }
with a trailing uint8_t
for the tag.
One trick I use, is to make a super minimal platform.roc file and then use roc glue path/to/RustGlue.roc output/ platform.roc
to generate the glue for it and then see what it looks like in Rust.
Here is RustGlue.roc https://github.com/roc-lang/roc/blob/main/crates/glue/src/RustGlue.roc
So the return type e.g. mainForHost is just whatever type I'm interested to know how roc handles.
Here is an example
This is the c equivalent for [A U64, B]: https://github.com/ostcar/kingfisher/blob/b23e778dc5a56472d09b8319c1044138d2226141/host/roc/host.h#L19
As you can see, you need a struct and a union. The struct has two fields. The first field is the union, the second is one byte. The union contains all payload types and the byte decides, which one is active.
In your c code, you can look at the byte and then read the union value accordingly.
Nice, to be honest, I did not even know about glue. Maybe I should have run roc --help at some point :D
Took me some time, but I was able to run the simple examples I was thinking of using rust now.
I will probably be using Rust now that it's starting to work for me. But out of curiosity, I would still like to get my c example to work. @Oskar Hahn I ran a copy of your [A U64, B]
example successfully. However I can not seem to map that to my example. I can't even read the tag right. I get different values depending how long I make the string in the A
. I'm sure I'm just missing something.
https://github.com/mx-ws/rocunion
First glance that looks correct. But would need to take a deeper look.
Thanks for looking at it and for all the answers then!
Sorry for forgetting to circle back to this.
There is definitely a compiler issue here.
It seems that Roc doesn't understand that Lists create a separate allocation in a type definition
MyUnion: [A Str (List MyUnion), Div (List MyUnion)]
Is being generated as if it where a recursive tag union. But it isn't. The Lists stop it from needing to be recursive
So it is generating something roughly like:
MyUnion: Box [A Str (List MyUnion), Div (List MyUnion)]
@Ayaz Hafiz since you're online, do you know where I would look in the source code to teach roc that List
and Box
break recursion when it comes to tag unions?
Last updated: Jul 06 2025 at 12:14 UTC