Common Lisp equivalent to Haskell's main function?
Haskell's main
function does just what I want: evaluate when the file is loaded by itself (e.g. ./myfile.hs
or runhaskell myfile.hs
) and in no other case. main
will not be called when开发者_开发百科 the file is imported by another file. newLISP also has this functionality.
Is there equivalent code for Common Lisp?
I read the source code for CLISP. Here's what happens when the user enters clisp myfile.lisp
or ./myfile.lisp
:
- CLISP saves
myfile.lisp
asp->argv_execute_file
. - CLISP creates the expression
(LOAD "p->argv_execute_file")
and pushes it onto the Lisp stack. - CLISP saves any additional command-line arguments in a list.
- CLISP stores the arguments in the Lisp variable
*args*
.
CLISP never makes a Lisp variable referring to p->argv_execute_file
, so there is no way to discern whether myfile.lisp
was loaded directly, by the user in the REPL, or by another Lisp file. If only (car *args*)
were myfile.lisp
, my task would be easy.
Note: Shebangs give CLISP trouble if the file is loaded from the REPL, so I put this code in ~/.clisprc.lisp
:
(set-dispatch-macro-character #\# #\!
(lambda (stream character n)
(declare (ignore character n))
(read-line stream nil nil t)
nil))
I found a solution. It's a bit of shell trickery, but it works. I'll soon modify this to work on CL implementations other than CLISP.
#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
exit
|#
;;; Usage: ./scriptedmain.lisp
(defun main (args)
(format t "Hello World!~%")
(quit))
;;; With help from Francois-Rene Rideau
;;; http://tinyurl.com/cli-args
(let ((args
#+clisp ext:*args*
#+sbcl sb-ext:*posix-argv*
#+clozure (ccl::command-line-arguments)
#+gcl si:*command-args*
#+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
#+cmu extensions:*command-line-strings*
#+allegro (sys:command-line-arguments)
#+lispworks sys:*line-arguments-list*
))
(if (member (pathname-name *load-truename*)
args
:test #'(lambda (x y) (search x y :test #'equalp)))
(main args)))
(eval-when (situation*) ...)
Update sorry for the confusing answer.
I could be wrong, but it seems to be impossible to do what you want exactly. I would make a shell script and call clisp -i myfile.lisp -x (main)
.
Is there any reason to not make it executable (described here)?
P.S. Common Lisp is a language and clisp
is one of the implementations.
精彩评论