Stream: ideas

Topic: allow platforms to do arbitrary C FFI


view this post on Zulip Richard Feldman (Jan 06 2024 at 19:10):

splitting this off from #ideas > platform specific data structures

Brendan Hansknecht said:

It is arbitrary CFFI, but only for platforms.

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:11):

so I think this idea is worth discussing, but I definitely think this would have major ecosystem implications (some maybe positive, some maybe negative)

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:13):

for example, we've talked before about demand for LAPACK bindings, which is ~1.5K linear algebra functions implemented in about 600K LoC of FORTRAN plus inline assembly

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:18):

so here is a sequence of events that could plausibly happen if we add this feature:

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:20):

so on the one hand, it would be cool to unlock those use cases

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:21):

on the other hand, I don't like the idea of platforms forking just for the sake of exposing a different mix of non-I/O C FFI things

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:23):

the nice thing about I/O is that it all boils down to a small, finite set of OS syscall wrappers, and everything else is a convenience wrapper around that - so I/O doesn't have that potential "ecosystem explosion" problem, and it also doesn't have the problem of side-effecting functions claiming to not be side-effecting

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:24):

Couldn't this concern already happen just wrapped in tasks?

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:25):

Push to implement the full set of lapack tasks

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:27):

totally, but the downside of having to do all math using tasks creates an incentive to port those functions to pure Roc instead, even if they're not quite as fast due to missing out on inline assembly optimizations (but then again, the Task state machine probably has more overhead, so the pure Roc ones might actually be faster than that in practice)

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:28):

the outcome I would want to see is that we end up with pure Roc linear algebra libraries that are fast enough in practice for the use cases where people would want LAPACK or BLAS

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:29):

and I think it's healthy that the way FFI works today creates an incentive structure that rewards someone for doing that

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:29):

I think that's fair, but I think it greatly hurts the ability to interface with and interact with many types.

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:30):

so I have to admit, I don't totally understand why that would be

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:31):

For example, say i have a c platform that already uses Blas or lapavk and i want to move some code into roc. I need that roc code to directly work on the Blas/lapack types. So I am stuck using tasks for everything and It makes things clunky enough that roc probably isn't work using.

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:31):

I guess if I'm sending a data structure from the host to the platform which uses unions and/or pointer packing and/or needs to do unsafe pointer dereferencing a lot becuase bounds checks are too expensive?

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:32):

In general think about any sort of embedding case where roc is not the main language, it is just a plugin language. The main project will not contort itself to use roc types. Roc needs to be able to use the host types.

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:33):

No one is going to rewrite bevy to internally use roc types, but someone might enjoy writing a roc plugin that uses the existing bevy types.

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:34):

yeah I appreciate that :thumbs_up:

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:35):

That is the main use case we want to enable. I am not sure how to enable It without also enabling generic ffi.

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:36):

I'm curious what your thoughts are on the LAPACK example concern

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:37):

e.g. do you think it's a significant concern but worth it if it happens? or don't think it's a significant concern in practice? (like it would be fine if that happened)

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:37):

or it would be bad, but worth it for the sake of enabling more use cases

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:39):

another point to consider: a platform which offers (for example) functions for synchronous global mutable state access, and then that gets popular and a significant portion of the library ecosystem is built around requiring that

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:39):

for example, someone would probably do that to get locale and also for synchronous random number generation

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 19:47):

Hmm...yeah, i guess this plus module params makes everything a lot more concerning cause It enables Amy library to explicitly depend on many things that should be effects.

view this post on Zulip Richard Feldman (Jan 06 2024 at 19:53):

yeah

view this post on Zulip peeps (Jan 06 2024 at 20:41):

So I didn't want to fill this thread with my nooby questions or nooby suggestions, but I had an idea while DMing Brendan which is worth mentioning here:

What if we just prevented "FFI Modules" from being injected? Could we not just make an exception in the implementation of module params? And then later figure out how it could still be implemented while also mitigating abuse use cases, if people really want it. It might not come up as a requirement at all.

Brendan also mentioned that this "would need to be a recursive check. No function that calls and FFI function can be injected".

view this post on Zulip Richard Feldman (Jan 06 2024 at 20:46):

also module params are essentially syntax sugar

view this post on Zulip Richard Feldman (Jan 06 2024 at 20:47):

you can always have your functions take an extra argument, namely another function which the caller provides

view this post on Zulip Richard Feldman (Jan 06 2024 at 20:47):

(module params essentially do that for you behind the scenes)

view this post on Zulip Richard Feldman (Jan 06 2024 at 20:49):

so people could still implement side effecting functions, they'd just have to take an extra argument :sweat_smile:

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 23:12):

For sure, but at least It would be a much bigger hassle which would hopefully reduce how often It happens

view this post on Zulip Brendan Hansknecht (Jan 06 2024 at 23:14):

Like might be enough to avoid It becoming common, but yeah, not a true guarentee at all.

view this post on Zulip peeps (Jan 07 2024 at 18:48):

I don't know much about this topic, but how much code analysis could we do on the code that every C capable language compiles to? Like I could theoretically look at a Rust method or function and just say "if all these parameters are immutable, then this function is pure". We obviously don't want do that on a per language basis, but If you could do that on the bit code or generated C (maybe we can make sure certain opcodes are not present), then we could automatically enforce purity laws at compile time.

view this post on Zulip Sky Rose (Jan 07 2024 at 21:03):

That'd be hard, and also the motivation for this idea is to allow platforms to use impure implementations as long as they provide a pure interface.

view this post on Zulip peeps (Jan 07 2024 at 21:12):

Sky Rose said:

That'd be hard, and also the motivation for this idea is to allow platforms to use impure implementations as long as they provide a pure interface.

Oh thats interesting, im not familiar with functional programming (Roc would be my first tbh) so what would a pure interface look like?

view this post on Zulip Kevin Gillette (Jan 07 2024 at 22:46):

The lapack example, and the plausible sequence of events that @Richard Feldman listed, would suggest we would benefit from having some way to integrate with [pure] libraries without requiring support from the platform.

view this post on Zulip Chris Wesseling (Feb 26 2024 at 23:21):

peeps said:

Oh thats interesting, im not familiar with functional programming (Roc would be my first tbh) so what would a pure interface look like?

Roughly put: pure functions can be memoized. If you (given enough memory) could implement the function as a table lookup, it's pure. A table lookup always returns the same value for the same parameter and it doesn't change the parameter.


Last updated: Jun 16 2026 at 16:19 UTC