It's now possible to create standalone executables from Python functions with SBCL (and only tested on Mac OS X). It is implemented on top of SBCL's function save-lisp-and-die. Using this functionality is straightforward: just call the method _exe() of the function. Example:
* (clpython:repl) Welcome to CLPython, an implementation of Python in Common Lisp. Running on: SBCL 1.0.20 REPL shortcuts: `:q' = quit, `:h' = help.
def f(): print "hello world"
... #<function f>
f()
hello world None
f._exe()
Building executable will terminate the Lisp session. Continue? (y or n) y Writing SBCL repl executable to: clpython-sbcl-20090105-f [undoing binding stack and other enclosing state... done] [saving current Lisp image into /Users/willem/dev/lisp/tmp/test-python/python/clpython-sbcl-20090105-f: writing 2872 bytes from the read-only space at 0x04000000 writing 1616 bytes from the static space at 0x04100000 writing 29245440 bytes from the dynamic space at 0x10000000 done] [willem test-python]$ ls -l ./python/clpython-sbcl-20090105-f -rwxr-xr-x 1 willem willem 29462540 Jan 17 18:50 ./python/clpython-sbcl-20090105-f [willem test-python]$ ./python/clpython-sbcl-20090105-f hello world [willem test-python]$
The executables have access to the command line arguments via "sys.argv". That should make it straightforward to write small utility programs. Here is an example program that takes input from the command line. Type it all in the repl:
import sys
def fact(n): if n <= 1: return 1 else: return n * fact(n-1)
def main(): # read argument from command line, using 10 as default if len(sys.argv) > 0: n = int(sys.argv[0]) else: n = 10 print "fact(%s):" % n print fact(n)
main._exe()
This gives an executable that behaves like this:
[willem test-python]$ ./python/clpython-sbcl-20090105-main fact(10): 3628800 [willem test-python]$ ./python/clpython-sbcl-20090105-main 20 fact(20): 2432902008176640000
- Willem