bendudson / py4cl

Call python from Common Lisp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to export function and call it from python file?

chsasank opened this issue · comments

Thanks for an amazing library! This makes my life so much easier because I can have best of both worlds!

This library allows me to call python libraries very easily. Can I do the other way around too? According to docs, I can export a lisp function to python, like so:

(py4cl:python-exec "from scipy.integrate import romberg")

(py4cl:export-function (lambda (x) (/ (exp (- (* x x)))
                                      (sqrt pi))) "gaussian")

(py4cl:python-eval "romberg(gaussian, 0.0, 1.0)") ; => 0.4213504

This means I should be able to actually call the function in python file:

from xyz.cl import romberg
romberg(gaussian, 0.0, 1.0)

I know that library called cl4py exists, but I'd prefer not too add more dependencies. Besides, can I use both these libraries together? Will it cause conflicts?

py4cl is a lisp library. It has lisp as its main process, and creates a python sub-process to call python functions.
While cl4py is a python library. It has python as its main process, and creates a lisp sub-process to call lisp functions.

can I use both these libraries together?

You can use them in different processes, yes. Trying to use them in the same process looks like both will mutually recurse to create sub-sub-processes and so on.

May be check if Hylang suits your needs: http://hylang.org/


This means I should be able to actually call the function in python file

What py4cl:export-function essentially does is it creates a global variable gaussian and assigns it to an instance of the python class LispCallbackObject. This communicates with the parent lisp process to call the lisp function.

A python file becomes a python module, and there doesn't seem to be hack-less way to access global variables from the python modules. What you can do is pass those exported functions as arguments to the lisp functions in the new python files/modules you write. So, something like -

(py4cl:python-exec "
import os, sys
os.chdir(\"/path/to/your/python/module/directory/\")
sys.path.append(\"./\")")

(py4cl:python-exec "import my_python_module")
(py4cl:python-eval "my_python_module.foo(gaussian)") ;=> 0.4213504

with my_python_module.py containing:

from scipy.integrate import romberg

def foo(lisp_fn):
    return romberg(lisp_fn, 0.0, 1.0)

If you are using lisp, this still isn't recommended, because reimports and redefinitions in a running python process (or most non-CL languages) is a headache beyond the simplest cases.