Let's start Scheme

2015-05-18

FFI library comparison for R6RS implementations

I'm writing Portable Foreign Function Interface for R6RS and have found some interesting things to share. Currently the library supports the following implementations and this article mentions them mainly:
  • Sagittarius (0.6.4)
  • Vicare (0.3d7)
  • Mosh (0.2.7)
  • Racket (plt-r6rs 6.1.1)
  • Guile (2.0.11)

API wise


Most of the implementations supports common procedures with different names. Only Mosh, Sagittarius and Vicare provide similar APIs. (Well, at least Sagittarius took some of the API names from Mosh, I don't know about Vicare.) Unfortunately, Mosh has much less APIs and seems incomplete. For example, Mosh doesn't have any API to convert bytevectors to pointers or APIs to set unsigned char/short/int/long to pointer. This might be critical in some cases. Vicare and Sagittarius have enough APIs to do almost everything.

Racket has interesting APIs. Almost all foreign variable need to have types.  For example, it distinguish char * and void * whilst above 3 not really do.

Guile has limited pointer operation procedure. It seems users always convert pointers to bytevectors, I think this is pretty inconvenient though. And it doesn't accept bytevector as pointer directly. So it needs to be converted by bytevector->pointer procedure.

Documentation wise


Racket provides excellent documents so I could write the library without referring its source code.

Guile provides good documents it's not so user friendly means I needed to do some try and errors to figure out how it works (especially, document doesn't provide library name. It took me some time to figure it out).

Mosh is OK document, though I also referred the source code. (because of lack of APIs, I hoped there is hidden ones).

Sagittarius is also OK document. Though, some of APIs documents are missing so it would be hard to write this library without referring the source code.

Vicare has poor document for FFI (unlikely the other documents). It just have shallow intruductions. This basically means there might be a chance that APIs would be changed. To write the library, I needed to refer the source code.

Other implementations


There are 4 more R6RS implementations which support FFI, Chez, Ypsilon, IronScheme and Larceny. These are the reasons why I didn't do it in first place:

Chez: I can only use Petite Chez Scheme but this doesn't support FFI. So to make it I need the comercial one which is not available anymore.

Ypsilon: Released version of Ypsilon has very limited APIs to create foreign functions/variables. And no document. Trunk version is far more APIs but not maintained nor released (I think it's sad but I can't help it). Just gave up.

IronScheme: .NET ... well simply not familiar to use it

Larceny: I might support, even it has good document. But there is no proper install script. So it's kinda hard to run/test.

Conclusion



I don't mean which APIs are the best or worst. Just figured out that if I want to write a portable library, then it might be better to have rather low level APIs exposed. And if low level APIs are there, then most of the concepts can be shared even they look completely different. (In this sense, Ypsilon's APIs are too high level to handle, unfortunately.)

No comments:

Post a Comment