3

I've got a very large Lisp project whose output I'd like to programmatically pipe to a Python program, i.e. use Python to call the Lisp program on some input and get the output back into Python.

The project only compiles in Clozure Common Lisp (ccl64) and I did try to find a way to turn it into an executable (I'm using Mac OS X), but that ran into a lot of dead ends (I am not a Lisp programmer).

This documentation for Clozure Common Lisp should provide the solution to the above, but I was not able to understand it. The examples I made created a file, but Terminal would not run them as executables.

How to create executable for ccl64

I tried to follow this question's answer Compiling Common Lisp to an executable except using ccl64's save application function.

$ ccl64
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk  (DarwinX8664)!
? (in-package :ccl)  
#<Package "CCL">
? (defun main () (print "hello"))
MAIN
? (save-application "hello" :toplevel-function #'main)

I am trying to use Python's subprocess to invoke ccl64, run the Lisp program, and get the output. However, subprocess for some reason refuses to run the ccl64 command. Here is what I wrote so far:

import subprocess

process = subprocess.Popen(['ccl64', '-h'], stdout=subprocess.PIPE)
out, err = process.communicate()

The variable out should contain the output of getting the usage/help from ccl64. Instead I get an error:

Traceback (most recent call last):
  File "sub.py", line 3, in <module>
    process = subprocess.Popen(['ccl64', '-h'], stdout=subprocess.PIPE)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

How can I get Python to invoke ccl64 and get output from the Lisp project?

Community
  • 1
  • 1
user3898238
  • 957
  • 3
  • 11
  • 25
  • 2
    Specify the full path to the ccl64 binary. – uselpa Dec 01 '14 at 05:16
  • To extend a bit what @LePetitPrince says: When you're typing on a terminal, typing just `ccl64` works because the executable is in your `PATH` environment variable but (by default), `subprocess` doesn't know that `PATH`. Find where the `ccl64` executable lives and pass the whole path to your `Popen` call. – Savir Dec 01 '14 at 05:23

1 Answers1

4

The error in your Python code is clear: No such file or directory.

You need to tell in your Python code which application you want to run in a way that it actually finds it.

It's also not clear why you save a Lisp executable somewhere named hello, but you are not trying to call it. With the necessary path. Your code tries to call Clozure CL - without the necessary path - but why? You just saved an executable. Why would you call Clozure CL to run it? I would also save the executable with prepending the kernel - that makes it self-contained.

Example:

Calling Clozure CL:

rjmba:~ joswig$ ccl
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk  (DarwinX8664)!

Defining the main function:

? (defun main () (print "hello"))
MAIN

Saving an executable:

? (save-application "hello" :toplevel-function #'main :prepend-kernel t)

Running the new executable from the same directory:

rjmba:~ joswig$ ./hello

"hello" 

Calling a Clozure CL application with an argument:

bash-3.2$ ccl
Welcome to Clozure Common Lisp Version 1.9-dev-r15612M-trunk  (DarwinX8664)!

The function ccl::command-line-arguments returns the arguments as a list. The first item is the called application itself.

? (defun main ()                                                                
    (print (second (ccl::command-line-arguments))))
MAIN

? (save-application "hello"                                                     
                    :toplevel-function #'main                                   
                    :prepend-kernel t)

Calling it:

bash-3.2$ ./hello hello!

"hello!"
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • I made the executable with Clozure CL, but when I go to the terminal and enter `hello` (the name of the file created), the terminal does not run it. – user3898238 Dec 01 '14 at 08:00
  • That works. However when I run my executable, it crashes and then launches the ccl64 repl, frozen in it. The main function is simply `(defun main (string) (my-fun string))`. – user3898238 Dec 01 '14 at 08:13
  • This function works: `(defun main () (print "hi") (quit))`. I turned it into an executable called `hi`. But suppose I wish to print an arbitrary string. How can I make it so when I type `./hi hello!`, the console prints `hello!`. – user3898238 Dec 01 '14 at 08:31
  • I think this global value is what I need to use: `*command-line-argument-list*`. – user3898238 Dec 01 '14 at 08:44