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

北战南征 提交于 2020-01-04 03:17:09

问题


I'm calling a Lisp function (and a few other thing) from a shell script. For brevity, below is relevant part of the script :

./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

The above code works fine but I had to append the package name CC3 for every symbol that is used; which makes the code unwieldy and hard to type.

I tried to simplify it like so, using 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))'

Much easier to read and type, but unfortunately it doesn't work. I've tried all sorts of ways to include the use-package directive but so far no success.

Is it even possible to include a use-package directive while launching a Lisp program via the GNU Common Lisp's (gcl) load directive?

Update: The solution is to use multiple evals as suggested by the accepted answer.

./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))'


回答1:


Maybe you could use multiple eval, here is what I do with 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:


It's maybe possible to do that but it will be ugly.

If you give it a form form evaluation, it will read the form first. Thus it then is too late during evaluation to change the reader (telling new packages, ...). Thus it needs to be done before.

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)

So, if you want to pass a single form to eval, you would write which first creates the package and then reads/evals from a string, which is encoded in the form. Tricky.

Alternatives:

  • maybe the Lisp allows at startup multiple -eval forms? Do whatever you need to initialize Lisp to know about the packages in the first -eval form. Then have the code to execute in the second form.

  • write a file and put the necessary forms there. Load it. Since a file can contain multiple forms, you can have DEFPACKAGE, IN-PACKAGE or similar on top and then have the rest of the code in the file depending on it.



来源:https://stackoverflow.com/questions/28341391/how-can-i-specify-the-package-name-when-launching-a-lisp-program-from-the-comman

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!