When dealing with "Model" types in apis, the standard way to interact with them is essentially to pass a box to the host.
This is seen in the host api as Box a
.
Currently glue does not really support this correctly and we have to modify the api to make glue happily generate. Generally by temporarily changing the type to Box {}
. This will lead to glue generating RocBox<{}>
.
This type mostly works, but can not actually free the underlying roc allocation (the host doesn't know how).
I think we can give a nicer (though not perfect) story to this case.
We can make glue specially handle Box typevar
such that it will generate what I am calling "Roc Opaque".
"Roc Opaque" will work very similar to "RocBox<{}>". It will have an explicit inc
and dec
function that can be called. That said, it will recognize that only roc can free the underlying type. As such, it will panic if the type is decremented enough such that it would be freed.
This gets us 3 things:
Box a
. It just works and generates RocOpaque
.let mut model = roc_init();
while true {
model = roc_update(model, inputs);
model.inc(1);
let out = roc_render(model);
// render out
}
RocOpaque
ensures that platforms are written correctly instead of accidentally leaking the model. (of course at the end of the app, a model can be explicitly forgotten instead of freed).Thoughts?
makes sense to me! @Folkert de Vries any thoughts?
Last updated: Jul 06 2025 at 12:14 UTC