;;; *** Start of simple documentation *** ;;; "Why" is a complex question, with a simple answer: I like Lisp's code and Python's extremely simple-to-use and easy-to-install library collection. I've never got a webserver to run in Clisp, but I got web.py (Aaron Swartz's server framework) running in minutes. ;;; Requirements: ;;; Lisp (!) ;;; Python must be installed. Not the 'devel' build, but just the general consumer version. All you need is the python/lib libraries and the Python library binary (on Windows, it's "python22.dll" or "python24.dll" etc, and on Linux it's (I think) libpython2.3.so.1.0 etc). If you want to re-distribute, you can in some cases include the Python DLL even in commercial distributions, perhaps the specific python/lib .py libraries used. It's easiest just to ask people to download Python first, but that's about 6mb. ;;; For those who don't want to read the code (I know I wouldn't!), here's some tips on using it. ;;; First, this code is only tested in Clisp, Allegro and Lispworks on Windows, and Clisp on Linux (but should work with the other two in Linux as well). ;;; To run a bit of Python code and print its results to the Lisp console, type "(py::py [code])" where [code] is a string with the Python code you want to execute. It will also return a string with the text printed out. eg, (py::py "print 'abc'") will print "abc" to the Lisp REPL and return "abc" to the caller. ;;; Use the ' for strings in Python code so you don't have to escape the quote character " ;;; To escape Lisp calls to Python, use \" ;;; When calling back from Python to Lisp, you may need to escape strings (if calling in a string from Lisp) with \\\" (which is \" in escaped Python code). ;;; To run code and not print anything (the most efficient method), "(py::pythonlisp [code] T)" ;;; To run code and define a module of callbacks which Python can run by module name and function name, add it as a 3rd parameter to pythonlisp or define it with add-python-module, and then you need to copy and paste the callbacks and rewrite as appropriate. ;;; get-mbox-messages is a good example of how to pass a module definition to add-python-module, as is the definition in init-python ;;; mbox-add-field is an example of a callback with 2 string args ;;; SetString is 1 arg ;;; GetString is no args but a return value. I haven't done any work on having 'l' args (long integer), so use 'atol' with 's' args. ;;; There are some toys: ;;; To interact with Python, "(py::py-repl)". Be very careful in this mode, in the same way you would be in the Lisp REPL. Don't paste code into the window, don't do anything like play around with file access unless you know what you're doing, and treat it as you would any console. ;;; To get a webpage in a string, "(py::get-web-page [url])" ;;; To get all the messages in a Unix-style mbox mail file, "(py::get-mbox-messages [filename])" - this does not open any files for write-access (only read-binary), so should be okay in all situations, but the file handles may remain open (untested). Works with Netscape mail files, probably Mozilla and Thunderbird too. It is not OS-dependent, so the same code will work in Windows, Linux, etc. ;;; *** End of simple documentation ***