从命令行启动 Lisp 程序时如何指定包名称?

How can I specify the package name when launching a Lisp program from the command line?

我正在从 shell 脚本中调用 Lisp 函数(以及其他一些东西)。为简洁起见,下面是脚本的相关部分:

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a" (CC3::sunset (CC3::fixed-from-gregorian (CC3::gregorian-date 1996 CC3::february 25)) CC3::jerusalem))' 728714.7349874675

上面的代码工作正常,但我必须为每个使用的符号附加包名 CC3;这使得代码笨重且难以输入。

我试着像这样简化它,使用 use-package :

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a" (use-package "CC3") (sunset (fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'

更容易阅读和输入,但不幸的是它不起作用。我已经尝试了各种方法来包含 use-package 指令,但到目前为止没有成功。

甚至可以在通过 GNU Common Lisp (gcl) 加载指令启动 Lisp 程序时包含 use-package 指令吗?

更新: 解决方案是按照已接受答案的建议使用多个评估。

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(use-package "CC3")' -eval '(format T "~a" (sunset (fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'

也许可以这样做,但会很难看。

如果你给它一个表单表单评估,它会先读取表单。因此,在评估期间更改 reader(告诉新包,...)为时已晚。因此需要提前完成。

CL-USER 1 > (eval (read-from-string "(foo::bar)"))
Error: Reader cannot find package FOO.

Better:

CL-USER 5 > (eval '(progn (defpackage foo (:use "CL"))
                          (read-from-string "(foo::bar)")))
(FOO::BAR)

因此,如果您想将单个表单传递给 eval,您可以编写 which 首先创建包,然后 reads/evals 从字符串中创建,该字符串在表单中进行编码。棘手。

备选方案:

  • 也许 Lisp 在启动时允许多个 -eval 形式?做任何你需要初始化 Lisp 的事情,以了解第一个 -eval 形式的包。然后让代码以第二种形式执行。

  • 写一个文件,把必要的表格放在那里。加载它。由于一个文件可以包含多个表单,因此您可以在顶部添加 DEFPACKAGEIN-PACKAGE 或类似内容,然后根据它在文件中添加其余代码。

也许你可以使用多个 eval,这是我对 sbcl 所做的。

#!/bin/sh
sbcl --noinform \
   --eval '(load "boot.lisp")' \
   --eval '(in-package #:my-pkg)' \
   --eval "(do-something-useful)" # do-something-useful is in my-pkg