演变lisp图像

cli*_*ntm 11 sbcl common-lisp

我喜欢基于图像的语言的想法,最近我一直在通过sbcl玩弄Common Lisp.我已经在几个地方读到了如何通过保存和加载虚拟机的映像,您可以改进在该映像上运行的应用程序或一组应用程序.

我得到了如何将代码加载到图像中并使其运行,slime使这种事情非常好,但我的问题是:如何判断图像中定义了哪些函数?假设我想在运行后几天或几个月对某个功能进行更新,我记不起名字了.有没有办法获得代码甚至只是图像中定义的函数的名称?

现在,我将代码写入源代码并通过repl加载,所以我有一个副本,但似乎这是一个明显的功能.

Rai*_*wig 13

Common Lisp有的想法.包是一种符号注册表,用作符号的命名空间.您可以向Common Lisp索取所有包的列表.

CL-USER 1 > (list-all-packages)
(#<The SQL-COMMON package, 0/4 internal, 28/32 external>
 #<The LOOP package, 245/256 internal, 3/4 external>
 #<The COMM package, 0/4 internal, 940/1024 external>
 #<The REG package, 41/64 internal, 0/4 external>
 ...)
Run Code Online (Sandbox Code Playgroud)

每个包都将实体符号存储在某些数据结构中.你可以问Common Lisp哪些符号是在一个包中实现的.

CL-USER 2 > (loop for symbol being
                each external-symbol in (find-package "COMMON-LISP")
             collect symbol)
(MAKE-ARRAY INVOKE-DEBUGGER STRING-TRIM ...)
Run Code Online (Sandbox Code Playgroud)

为了使这更容易,Common Lisp提供了函数APROPOS和APROPOS-LIST.

CL-USER 3 > (apropos "MAKE-LOCK")
MP::INTERNAL-MAKE-LOCK (defined)
MP:MAKE-LOCK (defined)
WWW-UTILS:MAKE-LOCK (defined)
MAKE-LOCK
RESOURCES::MAKE-LOCK (defined)
MINIPROC:MAKE-LOCK (defined)
Run Code Online (Sandbox Code Playgroud)

函数,类等使用符号作为其标识符.你也可以问一个符号,它表示的功能.

CL-USER 4 > (symbol-function 'www-utils:make-lock)
#<Function WWW-UTILS:MAKE-LOCK 41E006A69C>
Run Code Online (Sandbox Code Playgroud)

有时Common Lisp也会记录函数的定义.然后函数FUNCTION-LAMBDA-EXPRESSION可用于检索'it'.

CL-USER 5 > (defun foo (a) (* (sin a) a))
FOO

CL-USER 6 > (pprint (function-lambda-expression 'foo))

(LAMBDA (A)
  (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 41403151C3>))
  (DECLARE (LAMBDA-NAME FOO))
  (* (SIN A) A))
Run Code Online (Sandbox Code Playgroud)

但通常现在Common Lisp实现不使用记录的定义,而是记录每个Lisp构造的源位置.

大多数Common Lisp实现可以以特定于实现的方式跟踪源位置.

Common Lisp标准定义了一个函数ED.

CL-USER 7 > (ed 'www-utils:make-lock)
Run Code Online (Sandbox Code Playgroud)

这会调用编辑器(内部或外部),并应打开该函数的源代码.为了完成这项工作,Common Lisp需要跟踪每个函数的源位置.接下来,编辑器需要访问该源.有时记录的位置是绝对路径/Users/joswig/lisp/utils.lisp.如果编辑器想要打开该文件,则应该可以访问它.但也可以使用http:server; utils.lisp等逻辑路径名.然后将其转换为真实的物理路径名.稍后可以配置此转换.因此,可以将Lisp移动到具有不同路径名的不同机器,配置逻辑路径名HTTP,然后Lisp仍然找到所有源代码,即使它位于具有不同文件系统结构的不同机器上.因此,要使其工作可能需要一些配置.但它是一个非常有用的功能,它被广泛使用.

源代码的记录以及源位置的记录如何工作是如何依赖于实现的,并且是相应的Lisp与其开发环境相结合的特征.Better Lisp实现在这方面有很多功能.


Sha*_*aun 5

如果您愿意,也可以使用do-symbols或do-external-symbols:

例:

>> (do-external-symbols (s (find-package :foo-package)) (print s))

FOO-PACKAGE:XXX
FOO-PACKAGE:YYY
FOO-PACKAGE:ZZZ
NIL
Run Code Online (Sandbox Code Playgroud)

其中XXX,YYY和ZZZ都是包中的外部符号:foo-package.