【问题标题】:How can I specify the package name when launching a Lisp program from the command line?从命令行启动 Lisp 程序时如何指定包名称?
【发布时间】:2025-12-20 15:35:11
【问题描述】:

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

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(格式 T "~a" (CC3::sunset (CC3::fixed-from-gregorian (CC3::gregorian-date 1996 CC3::2 月 25 日)) CC3::耶路撒冷))' 728714.7349874675

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

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

./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(格式 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 年 2 月 25 日)) 耶路撒冷))'

【问题讨论】:

    标签: shell batch-file common-lisp gnu-common-lisp


    【解决方案1】:

    也许你可以使用多个 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
    

    【讨论】:

      【解决方案2】:

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

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

      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 首先创建包,然后从字符串中读取/评估,该字符串在表单中编码。棘手。

      替代方案:

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

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

      【讨论】: