Stream: compiler development

Topic: Roc Opaque


view this post on Zulip Brendan Hansknecht (Apr 10 2024 at 03:07):

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:

  1. No weird work around needed to run glue on apis with Box a. It just works and generates RocOpaque.
  2. No need to design model apis such that we have to pass in and get back the model on every call. You can do:
let mut model = roc_init();
while true {
    model = roc_update(model, inputs);
    model.inc(1);
    let out = roc_render(model);
    // render out
}
  1. The explicit panic on freeing the 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?

view this post on Zulip Richard Feldman (Apr 10 2024 at 11:17):

makes sense to me! @Folkert de Vries any thoughts?


Last updated: Jul 06 2025 at 12:14 UTC