开发者

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:

  1. CLISP saves myfile.lisp as p->argv_execute_file.
  2. CLISP creates the expression (LOAD "p->argv_execute_file") and pushes it onto the Lisp stack.
  3. CLISP saves any additional command-line arguments in a list.
  4. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜