Common Lisp相当于Haskell的主要功能?

mca*_*dre 7 scripting haskell program-entry-point common-lisp

Haskell的main函数正是我想要的:评估文件何时自己加载(例如./myfile.hs或者runhaskell myfile.hs),而不是其他情况.main文件由另一个文件导入时不会被调用.newLISP也具有此功能.

Common Lisp有相同的代码吗?

我阅读了CLISP 的源代码.以下是用户输入clisp myfile.lisp或发生的情况./myfile.lisp:

  1. CLISP保存myfile.lispp->argv_execute_file.
  2. CLISP创建表达式(LOAD "p->argv_execute_file")并将其推送到Lisp堆栈.
  3. CLISP将任何其他命令行参数保存在列表中.
  4. CLISP将参数存储在Lisp变量中*args*.

CLISP永远不会引用Lisp变量p->argv_execute_file,因此无法识别myfile.lisp是由用户在REPL中直接加载,还是由另一个Lisp文件加载.如果仅仅(car *args*)myfile.lisp,我的任务很容易.

注意:如果从REPL加载文件,Shebangs会给CLISP带来麻烦,所以我把这段代码放在~/.clisprc.lisp:

(set-dispatch-macro-character #\# #\!
 (lambda (stream character n)
  (declare (ignore character n))
  (read-line stream nil nil t)
  nil))
Run Code Online (Sandbox Code Playgroud)

mca*_*dre 2

我找到了解决办法。这有点像 shell 技巧,但它确实有效。我很快就会修改它以适用于 CLISP 之外的 CL 实现。

#!/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)))
Run Code Online (Sandbox Code Playgroud)