soegaard2
2022-6-25 17:36:35

The FFI support variadic C functions with the #:varargs-after option. I have run into the error: PyObject_CallMethodObjArgs: arity mismatch; the expected number of arguments does not match the given number expected: 3 given: 4 where PyObject_CallMethodObjArgs is defined like this: ; PyObject *PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) (define-python PyObject_CallMethodObjArgs (_fun #:varargs-after 2 _PyObject* _PyObject* _pointer -> _PyObject*))


soegaard2
2022-6-25 17:37:34

The call site looks like this: (define result (apply PyObject_CallMethodObjArgs pyobj (string->py-string method-str) pyargs))


soegaard2
2022-6-25 17:38:44

I am surprised that the error says that 3 arguments are expected, when the function is variadic.

What am I missing?


mflatt
2022-6-25 17:38:48

#:varargs-after does not mean that you can supply any number of arguments to the FFI-generated Racket function. You need a separate FFI-generated function for each number of arguments that you want to supply. The #:varargs-after annotation indicates how many of the arguments are before in the C prototype.


soegaard2
2022-6-25 17:40:32

Got it! That’s reasonable easy to fix.


soegaard2
2022-6-25 17:42:27

Is this a limitation of ffilib?


mflatt
2022-6-25 17:45:19

Yes, but also Chez Scheme, and really a kind of fundamental limitation. You may have in mind that _pointer would be replicated N times for N extra arguments, but more generally, the extra arguments represented by in a C prototype can have different types among arguments (and differnet types for different calls). In C, a call site effectively has an inferred type for the function; in Racket, you have to be explicit by creating a new type for each combination of arguments.


soegaard2
2022-6-25 17:47:45

In this case all the extra arguments have the same type (a pointer) and the last argument is NULL.


soegaard2
2022-6-25 17:49:05

I’ll just make functions for 0 to 5 arguments and call it a day.


philip.mcgrath
2022-6-25 18:05:03

@soegaard2 Out of curiosity, in what context are you writing bindings for Python? It’s not on my agenda at the moment, but it’s something I’ve thought about doing.


soegaard2
2022-6-25 18:16:32

@philip.mcgrath I have finally realised that to bring “Scientific Computing” to Racket, we need bindings for Numpy (and related projects). Turns out Python has a libpython that can be used to embed it. The Python C-API is reasonably easy to use and seems a good fit to be used from Racket.

Right now I can start Python, convert values back and forth and call Python functions. I am experimenting with a pyffi that works analogous to the C FFI. I used it to write bindings for almost all of the functions in the builtins module Now I have begon working on ndarray from Numpy.

My plan is to present the work, when the core parts are stable. And hopefully get some help to write bindings for some of the most useful Python libraries.


philip.mcgrath
2022-6-25 18:27:00

That is basically why I have been interested: it’s not even the Python code so much as the thin layers over C or Cython, from what I’ve seen. (These also make Python much less memory-safe than it gets credit for. I still have not forgiven the dependency that wanted a faster JSON library, used one in C, and segfaulted.)

I recently learned of another effort at bindings for libpython in Racket, also: https://github.com/Aeva/snake-oil\|https://github.com/Aeva/snake-oil

One thing I’ve never been decided about is how/whether Racket’s modules and namespaces should correspond to Python environments.


ben.knoble
2022-6-25 18:39:17

If numpy is a thin C wrapper, would it be easier to try an FFI wrapper over that directly instead of going through Python? Or are they too entangled?


soegaard2
2022-6-25 18:50:36

@philip.mcgrath Thanks for the pointer. I had missed Aeva’s library.


soegaard2
2022-6-25 18:52:32

@ben.knoble There is a C API for Numpy, but they expose everything as Python objects. https://numpy.org/doc/stable/reference/c-api/index.html


soegaard2
2022-6-25 21:04:02

@ben.knoble I hope the Numpy C-PI can be used to take an array of numbers (like a flvector or a fxvector and turn it into a ndarray without copying the data.


philip.mcgrath
2022-6-25 21:34:42

The fact that PyPy implements the CPython API always amazes me.


hj93
2022-6-26 05:46:13

hi can you guys recommend racket libraries for computer music? i would like to make classical music with racket