JuliaPy / JuliaPy/PythonCall.jl

RFC: Syntax for Gradual Julia-ization of a Python library

Ouverte
#521 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub
enhancement
Langage dominant
Julia
Étoiles
1.1k
Forks
86
Merge moyen
1 j 22 h
PR mergées (30 j)
3

Description

I think the greatest thing about PythonCall/JuliaCall is how easy it makes it to integrate Julia into a Python project, so that one can gradually port the hot inner loops into Julia functions. I think it could be made even easier to do this, and wanted to share a couple of ideas.

## 1. Julia should be optional

Installing Julia on every user’s machine is a big ask for heavily-used Python libraries that have battle-tested build scripts. Therefore I think the process of Julia-izing a Python library should be very gradual, and allow for a Julia backend to be *optional*.

I think it would be nice if there was a standardized and documented way to check for the availability of `juliacall` without triggering an install of Julia, which would open up specific high-performance branches of code. For example,

```python
if juliapkg.is_installed():
# Julia branch of code
else:
# regular code
```

In a package, you could create an optional “extra” set of dependencies which would install the juliacall library and also trigger the `juliapkg.is_installed` branches to become `True`.

I think this may be preferable in some cases to simply checking the presence of `juliacall` in the user’s environment which might be installed from another package. For this idea, the user would need to explicitly install the Julia backend with something like
```bash
pip install "mypackage[julia]"
```
For those checks to trigger.

Thus, if a package developer chooses to make this an option, users would need to opt-in to enable the faster behavior.

## 2. Syntax for Julia versions of functions

In a similar direction, I wonder if there is another syntax available for writing Julia versions of functions. One idea is to have something like `@numba.jit`, but with a Julia version, which could look like

```python
@juliacall.pydef
def foo(x):
return np.sum(x ** 2)

@juliacall.jldef(foo)
def foo_jl(x)
return """
x -> sum(xi -> xi^2, x)
"""
```

The `jldef` would run `juliacall.seval` on the return value of the Python code (a string), and feed the arguments of the function to the resulting anonymous function. This would be cached.

In addition, the `jldef` version would only be activated if a user installs the Julia backend of the package. The `pydef` version would check if it is installed, and call the Julia branch of the code, which gets associated using the `jldef(foo)` specification.

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.