Python
Python intrinsics, which allow calling Python code from MCore, are offered as an optional feature for the boot bootstrap interpreter. Note: it is not yet supported for the Miking compiler.
To build the project with Python integration you need to have Python 3 installed on your system. You will also need to install any Python libraries you want to use (for example using pip).
In addition, you need the pyml OCaml Python bindings, available via opam:
opam install pyml
boot will automatically be compiled with Python support when the pyml package is installed.
NOTE: Currently, there seems to be a problem with the current OPAM bindings with the multicore switch. If the above command fails, try to run the following and then install pyml again:
opam pin stdcompat 15
To install for the current user, run make install as usual.
Usage
The following example shows how to use the intrinsics to sort a sequence using
Python's builtin sorted function.
let builtins = pyimport "builtins"
let x = [5.,4.5,4.,1.,1.5]
let y = pycall builtins "sorted" (x,)
let x_sorted = pyconvert y
pycall is the main piece of the Python intrinsics: in the example above,
it is used to call the function sorted from the builtins module, imported
with the pyimport intrinsic. As the example shows, arguments are
passed to the pycall intrinsic using tuples (remember that (x,) is a
singleton tuple containing x). The result of a pycall (y in the example
above) is a Python value, which can either be passed to other Python functions,
or converted back to an MCore sequence using the pyconvert builtin.
pycall can also be used to call methods of objects by passing an object
instead of a module as the first argument. For example, the following code
will invoke the count method of a list:
let builtins = pyimport "builtins"
let pylist = pycall builtins "list" ([1,1,2],)
let ones = pyconvert (pycall pylist "count" (1,))
In the examples above, we use the builtins module to access Python's builtins.
Other modules can also be imported as long as they are available in the Python
path: for instance, it is perfectly possible to import numpy or matplotlib,
assuming that they are installed.
The following example shows how a numpy nparray can be created and converted
to an MCore sequence. The key here is to use numpy's tolist method first,
since conversion directly from nparray is not supported.
let rnd = pyimport "numpy.random"
let nparray = pycall rnd "normal" (0., 0.1, 10)
let mc_seq = pyconvert (pycall nparray "tolist" ())
In the next example, we use matplotlib to produce a plot; this works in
exactly the same way as in a regular Python program.
let plt = pyimport "matplotlib.pyplot"
let np = pyimport "numpy"
let x = pycall np "arange" (0, 4, 0.1)
let y = pycall np "cos" (x,)
let _ = pycall plt "plot" (x, y)
let _ = pycall plt "show" ()
Conversion between MCore and Python
When calling a Python function using the pycall builtin, the arguments will be
automatically converted from MCore values to Python values. Similarly, the
opposite conversion is performed when using pyconvert on the result of a
pycall. This section explains the details of these conversions.
From MCore to Python
| MCore type | Python type |
|---|---|
| Bool | bool |
| Int | int |
| Char | N/A |
| Float | float |
| [Char] (String) | str |
| [a] | List |
| () | None |
| Record | Dict |
| Tuple (Record) | Tuple |
| other | N/A |
From Python to MCore
| Python type | MCore type |
|---|---|
| bool | Bool |
| int | Int |
| long | Int |
| float | Float |
| str | [Char] (String) |
| List | [a] |
| None | () |
| Dict | Record |
| Tuple | Tuple (Record) |
| other | N/A |