RU version is available. Content is displayed in original English for accuracy.
I couldn't really find any bindings generator that would create type-safe, rich bindings for Haskell from Rust. Naturally, both languages have rich type systems, so I was amazed that no awesome bindings generator already existed, hence I decided to write my own. hsrs feels very similar to pyo3 and napi-rs, and if you've used those, hsrs will feel right at home.
What's unique about hsrs as opposed to hs-bindgen is that it has type-safe bindings for rich types, like Result, Maybe, etc. while also generating Haskell bindings. The repo contains a minimal example, and more details are available in the haskell discourse: https://discourse.haskell.org/t/ann-hsrs-ergonomic-haskell-b...

Discussion (7 Comments)Read Original on HackerNews
Maybe the GC would be less of a problem if we didn't want to have the best possible performance as well.
```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.
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.
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
I think purity is something the programmer just has to annotate themselves. Any boundary between languages with different type system guarantees will always have this kind of friction - Rust to C/C++ FFI also has to deal with ownership, lifetimes and aliasing manually.
Regarding type classes, monomorphisation indeed seems like a difficult obstacle for polymorphic function. But just translating type classes and impls might not be as difficult? So going from:
toWith more and more ecosystem libraries being written in Rust (and a Python wrapper) could this be a way to expand the Haskell ecosystem?