[Download pycaml-2011-10-05.tar.gz] - [Download numpycaml-2011-10-05.tar.gz]
There are many reasons why a Python-OCaml interface is a very useful thing to have. From the OCaml perspective, Python is a popular scripting language that provides the "glue" to a lot of useful functionality for which no direct OCaml interfaces exist (yet), such as plotting libraries like matplotlib.
From the Python perspective, a major problem is reduced execution speed. While Python is quite competitive for an interpreter, it still is slow in comparison to efficient compiler languages. Unfortunately, using libpython directly often means having to keep track of reference counts. While competent programmers know how to do this right, this still is an extra unnecessary intellectual burden. After all, if one decides to extend Python, this always is in order to solve some specific problem, not in order to get an opportunity to play with Python's reference counting.In the past, there have been a few attempts to write Python-OCaml interfaces - the most complete one which also made it into the Debian distribution was written in 2002 by Art Yerkes. While the original design had a number of flaws, and unfortunately also memory corruption problems both on the ML as well as on the Python side, one of its strongest points were to make it very easy to call OCaml functions from Python and vice versa.
The packages provided on this web page are an extension of Art Yerkes' 2002 "Pycaml" package. Apart from bug fixes and extensions, this evolved Pycaml should still be compatible with code using the original Pycaml. Thomas Fischbacher took the original Pycaml package in 2005 and fixed memory management issues and other bugs, plus introduced a mechanism to deal with opaque OCaml objects passed around between Python functions ("OCaml Pills") and numerous other extensions (such as a function providing type-checking wrappers for exporting statically typed ML functions as dynamically typed Python functions.) This extended Pycaml was then incorporated into the computational micromagnetism framework nmag developed at the University of Southampton. Due to its role in nmag, it received some further adaptions and extensions (in particular with respect to handling higher-rank numerical arrays, "tensors"), mostly by Matteo Franchin. In 2011, Klaus Aehlig contributed by providing cleaned up build scripts and some code fixes, and Max Albert contributed by splitting off the numpy related parts, bug fixes, cleanup, and further extensions. Unfortunately, the release of Pycaml as a separate package that could function independently of nmag got delayed over and over again, much less due to technical than due to political reasons. It now has been made available on this web page for download, despite somewhat flawed initial design and badly lacking documentation. Contributions - in particular concerning more examples and documentation - are highly appreciated.
Some interactive examples showing how to use the most important Pycaml features (in particular via the Pycaml.Nicerpy sub-module):
$ export OCAMLFIND_CONF=/home/tf/projects/pycaml/site-lib/findlib.conf # #use "topfind";; # #require "pycaml";; # module P=Pycaml.Nicerpy;; # P.repr (P.py_eval "2**20");; # P.repr (P.py_eval "2**20");; - : string = "1048576" # P.py_exec "import math";; - : int = 0 # P.repr (P.py_to_fun (P.py_resolve "math.cos") [|P.float_to_py 1.57|]);; - : string = "0.00079632671073326335" # P.py_register "math.five" (P.int_to_py 5);; - : unit = () # P.py_repl();; >>> math.five 5 >>> - : int = 0 # P.repr (P.fun_to_py ~register_as:"ocaml.foo" ~docstring:"Foo function" [|Pycaml.FloatType;Pycaml.FloatType|] (fun args -> let base = P.py_to_float args.(0) and pow = P.py_to_float args.(1) in P.float_to_py (base**pow)));; - : string = "<built-in method anonymous_closure of PyCObject object at 0xb76d3ab8>" # P.py_repl();; >>> ocaml.foo <built-in method anonymous_closure of PyCObject object at 0xb76d3ab8> >>> ocaml.foo(1.414213562,2.0) 1.9999999989447279 >>> help(ocaml.foo) Help on built-in function anonymous_closure: anonymous_closure Foo function >>> - : int = 0 #
Pycaml is made available under the terms and conditions of the GNU Lesser General Public License v2.1; other licensing options may be available on request. We would appreciate if Pycaml users working on their own projects contacted us so that we can coordinate further development.