Common Lisp中类似于Haskell的main函数的等效函数是什么?

8
Haskell的main函数正好符合我的要求:仅在文件自身加载时进行评估(例如./myfile.hsrunhaskell myfile.hs),其他情况下不进行评估。当文件被另一个文件导入时,main不会被调用。 newLISP也具有此功能。
是否有Common Lisp的等效代码?
我阅读了CLISP的源代码。当用户输入clisp myfile.lisp./myfile.lisp时,以下内容将发生:
  1. CLISP将myfile.lisp保存为p->argv_execute_file
  2. CLISP创建表达式(LOAD "p->argv_execute_file")并将其推送到Lisp堆栈上。
  3. CLISP将任何附加的命令行参数保存在列表中。
  4. CLISP将参数存储在Lisp变量*args*中。
CLISP从未创建指向p->argv_execute_file的Lisp变量,因此无法区分myfile.lisp是直接加载的,还是由REPL中的用户或另一个Lisp文件加载的。如果只有(car *args*)myfile.lisp,那么我的任务就很容易了。
注意:如果文件从REPL加载,Shebang会给CLISP带来麻烦,因此我将此代码放在~/.clisprc.lisp中。
(set-dispatch-macro-character #\# #\!
 (lambda (stream character n)
  (declare (ignore character n))
  (read-line stream nil nil t)
  nil))

为什么需要一个等同于主函数的函数? - Larry Coleman
2个回答

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)))

第4行的 exit 是不必要的 - 由于 exec,shell 永远不会运行它。而且 CL 也会忽略它。因此第4行可以被删除。 - ulidtko

0

(eval-when (situation*) ...)

更新 对于混淆的答案表示抱歉。

我可能错了,但似乎无法完全实现您想要的功能。我会编写一个shell脚本并调用clisp -i myfile.lisp -x (main)

是否有任何理由不将其设置为可执行文件(在这里中描述)?

P.S. Common Lisp是一种语言,clisp是其中之一的实现。


:load-toplevel 只在代码编译时起作用,而 :execute 则会在文件加载时调用 main 函数,这并不是期望的功能。 - mcandre
@mcandre 在文件加载时:load-toplevel 起作用,但其他一切都是正确的。我会更新答案,谢谢。 - khachik
clisp -i myscript.cl 作为 shebang 不太适用。此外,当加载脚本时,clisp 不允许使用 -x 参数。但还是谢谢 :) - mcandre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接