Show HN: Hsrs – Type-Safe Haskell Bindings Generator for Rust

52 points by suis_siva 17 hours ago on hackernews | 6 comments

rienbdj | 13 hours ago

Really cool nice job!

With more and more ecosystem libraries being written in Rust (and a Python wrapper) could this be a way to expand the Haskell ecosystem?

[OP] suis_siva | 4 hours ago

Maybe!

_flux | 13 hours ago

It would be so nice if these "well typed languages" would be able to interact better with each other. Alas, the GC will probably cause some friction, e.g. the ocaml-rs package makes this pretty visible: https://github.com/zshipko/ocaml-rs/blob/master/examples/rus... . (I have not used either of these projects.)

Maybe the GC would be less of a problem if we didn't want to have the best possible performance as well.

[OP] suis_siva | 5 hours ago

Oh wow, that does seem quite painful. That crate reminds me of how JSC' internal bindings work:

```cpp JSC_DEFINE_HOST_FUNCTION(jsMyFunction, (JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)) { JSC::VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); ... ```

kind of the same thing, seems like -- passing data around to be managed by the GC.

yccs27 | 10 hours ago

It's great that this allows passing Rust structs both as ForeignPtr and as native records with marshalling!

Some questions/ideas:

- Is there a way to generate #[hsrs::data_type] bindings for Rust library types, or do you need to create custom wrapper types for them?

- It seems like all #[hsrs::function]s are translated to return IO (since Rust functions can do arbitrary side effects). It would be great if you could (unsafely) mark functions as pure, to get pure Haskell functions without having to wrap them in unsafePerformIO.

- Both Haskell and Rust have HM type systems, so I wonder if you could also translate type classes from Rust to Haskell.

[OP] suis_siva | 4 hours ago

> - Is there a way to generate #[hsrs::data_type] bindings for Rust library types, or do you need to create custom wrapper types for them?

At the moment, no. I'll ad this to the list of features for 0.2, totally slipped my mind, and if I remember correctly, both napi-rs and pyo3 have support for this.

> - It seems like all #[hsrs::function]s are translated to return IO (since Rust functions can do arbitrary side effects). It would be great if you could (unsafely) mark functions as pure, to get pure Haskell functions without having to wrap them in unsafePerformIO.

I did think through this a little bit and couldn't find a good way to implement this so decided to delay it until the next release, until I come up with some better ideas.

I wanted some sort of automated mechanism to determine purity, but that, obviously, doesn't exist in Rust. There _are_ some ways to approach this -- `const fn` are pure (I think), and it would be cool if I added support for https://github.com/creusot-rs/creusot. I was thinking of walking down the AST of a function to automatically infer purity, but that seems like a whole other, order-of-magnitude larger project. I'm still not sure what to do about this (bar a simple annotation), but I'll land something for 0.2. https://github.com/harmont-dev/hsrs/issues/1

> - Both Haskell and Rust have HM type systems, so I wonder if you could also translate type classes from Rust to Haskell.

Yes!! I do think that would be quite neat and I spent a little bit of time thinking through it, but I couldn't really come up with a great use-case (at least for my needs) that justified the necessity of this feature. This _might_ (probably won't) land 0.2, but it's definitely something I'm thinking about. One of the big problems that makes this quite non-trivial is monomorphization -- it's unclear what kind of specializations of a particular generic function you want in Rust. Trait objects _should_ be able to work, but I still haven't figured out the details of all of that. https://github.com/harmont-dev/hsrs/issues/2