For a while I have been hacking on using Python/Python libraries from Racket.
The library is now so advanced, that it makes sense to present it here.
The purpose is simple: make it easy to use Python libraries from Racket.
Libraries written in Python ought to work out of the box. Due to the way Python represent all values as objects, it is possible to use reflection to bridge Python values nicely back and forth between Python and Racket. Most Python extensions (libraries are implemented in C) are well-behaved
and work as if they were native libraries. Some Python extensions miss the reflection
information. If you happen to need such a library there is a low-level interface available.
The low-level interface has an interface similar to the the C FFI.
Currently you can't pass Racket functions to the Python side - but if there is popular demand...
The introduction to Pyffi is a good place to begin
I found recently the Python interface for Gambit Scheme, but it was hard to get it working ... still, one thing that I found interesting there was the interactive call to pip, which installs new packages in a dedicated virtualenv. And you can even call it from REPL, in theory.
Any chance you are considering to add something like this to pyffi? Leveraging the Python standard library and Numpy is good, but being able to install any PyPI package would open many doors.
With the pyffi configuration tool you can choose which Python installation to use - virtual or not.
So install Python as normal, then use python3 -m pip install <your-python-package> to install your packages. Finally use raco pyffi configure to configure pyffi.
The command raco pyffi is available after installation of pyffi.
Now, ideally, you could write raco pkg install pyffi and be done, but I haven't put pyffi on the package server yet [1]. For now, clone the pyffi Github repo
https://github.com/soegaard/pyffi
and use raco pkg update pyffi to install it.
[1] The documentation of pyffi contains examples that invokes the Python, so to build the documentation a Python installation is needed. That is, I need help from the maintainers
of the build server to get the documentation built.
It would be lovely if the garbage collectors of the two systems could interact properly.
Python uses reference counting (there is not much to do about that).
When a Python value is allocated from Racket, the Racket side gets a pointer to a C-struct.
This C-struct contains a reference count, which we increment (so the Python garbage collector
doesn't remove values used by Racket). On the Racket side the pointer is associated with a "will executor". When Racket determines that the value is dead, we decrement the Python
reference count. This allows the Python side to reclamin the memory.
(note: no need to specify "pyffi" again as it's inferred from the current directory name)
... although, I just tried that and, while the package did install, I saw some errors:
pyffi-doc/pyffi/scribblings/manual-pyffi.scrbl:9:21: cannot open module file
module path: pyffi
path: /Users/siddhartha/work/racket/pyffi/main.rkt
system error: no such file or directory; rkt_err=3
and
ffi-lib: could not load foreign library
path: libpython3.10.dylib
system error: dlopen(libpython3.10.dylib, 10): image not found
context...:
/Applications/Racket-Latest/collects/ffi/unsafe.rkt:131:0: get-ffi-lib
body of "/Users/siddhartha/work/racket/pyffi/pyffi-lib/pyffi/libpython.rkt"
...
raco pkg install: packages installed, although setup reported errors
I haven't followed this thread in detail so apologies if I've missed something above.
Btw - It might me faster to use the Racket Discord while we figure out, what's wrong.
For comparison, here is my output on macOS:
soegaard@mbp2 stxmat % raco pyffi show
Current configuration for 'pyffi'.
libdir = "/Library/Frameworks/Python.framework/Versions/3.10/lib"
data = "/Library/Frameworks/Python.framework/Versions/3.10"
Meaning:
libdir: location of the shared library 'libpython'
data: location of bin/ lib/ share/ etc.
open-input-file: cannot open module file
module path: pyffi/configure-pyffi
path: /Users/saludes/pyffi/configure-pyffi.rkt
system error: no such file or directory; rkt_err=3
context...:
/Applications/Racket/collects/raco/raco.rkt:41:0
body of "/Applications/Racket/collects/raco/raco.rkt"
body of "/Applications/Racket/collects/raco/main.rkt"
raco pyffi configure
open-input-file: cannot open module file
module path: pyffi/configure-pyffi
path: /Users/saludes/pyffi/configure-pyffi.rkt
system error: no such file or directory; rkt_err=3
context...:
/Applications/Racket/collects/raco/raco.rkt:41:0
body of "/Applications/Racket/collects/raco/raco.rkt"
body of "/Applications/Racket/collects/raco/main.rkt