我是一名初学者程序员,正在学习《Lisp之国》这本书。
我已经在REPL中输入了这本书的例子。现在,我想知道是否可以将当前的程序保存为.lisp文件,以便稍后加载并继续工作?我知道我可以在文本编辑器中创建.lisp文件并加载它们,但我喜欢使用全屏模式下的REPL来完成这些例子。
我是一名初学者程序员,正在学习《Lisp之国》这本书。
我已经在REPL中输入了这本书的例子。现在,我想知道是否可以将当前的程序保存为.lisp文件,以便稍后加载并继续工作?我知道我可以在文本编辑器中创建.lisp文件并加载它们,但我喜欢使用全屏模式下的REPL来完成这些例子。
不行。一旦您将函数输入REPL中,源代码就消失了,仅剩下解释或编译后的形式。您可以做一些聪明的事情,但我怀疑您现在不想处理它们。
首先,我知道您喜欢REPL,但我建议您查看一些带有Lisp支持的编辑器,例如带有SLIME的Emacs(http://common-lisp.net/project/slime/),它为您提供了最佳选择。您在编辑器中键入,它会在REPL中键入,您真的不知道与您现在所做的有什么区别。然后,您可以将喜欢的函数复制并粘贴到“适当”的.lisp文件中。使用Emacs的另一个优点是它基于一种称为Elisp的Lisp变体,因此您可以用Lisp编程您的编辑器。您可以对代码进行漂亮的打印,重新格式化和重构成多个函数,并执行各种出色的操作。
如果您仍然只想键入clisp并在REPL中玩耍,那么您仍然有选择。
如果要记录REPL会话的输出,请查看DRIBBLE。它将将您的会话记录到文件中,您可以稍后编辑该文件以提取所需内容。
例如,这是一个简单的会话:
ataylor:~ $ clisp
blah blah
[1]> (dribble "/Users/ataylor/jerome.lisp")
#<OUTPUT BUFFERED FILE-STREAM CHARACTER #P"/Users/ataylor/jerome.lisp">
[2]> (defun add-two (a b) (+ a b))
ADD-TWO
[3]> (add-two 1 2)
3
[4]> (dribble)
#<CLOSED OUTPUT BUFFERED FILE-STREAM CHARACTER #P"/Users/ataylor/jerome.lisp">
[5]>
Bye.
查看文件内容很容易,但是文件可能会很快变得很大。
ataylor:~ $ cat jerome.lisp
;; Dribble of #<IO TERMINAL-STREAM> started on 2011-09-14 18:16:57.
#<OUTPUT BUFFERED FILE-STREAM CHARACTER #P"/Users/ataylor/jerome.lisp">
[2]> (defun add-two (a b) (+ a b))
ADD-TWO
[3]> (add-two 1 2)
3
[4]> (dribble)
;; Dribble of #<IO TERMINAL-STREAM> finished on 2011-09-14 18:17:16.
您可以复制(defun add-two (a b) (+ a b))
并将其粘贴到文件中以备后用。
加载该文件(我将其添加到jerome1.lisp
)非常简单。
ataylor:~ $ cat jerome1.lisp
(defun add-two (a b) (+ a b))
ataylor:~ $ clisp
blah blah
[1]> (load "/Users/ataylor/jerome1.lisp")
;; Loading file /Users/ataylor/jerome1.lisp ...
;; Loaded file /Users/ataylor/jerome1.lisp
T
[2]> (add-two 1 2)
3
[3]>
Bye.
最简单的方法是将你的Lisp会话保存为一个镜像文件。它将保存你创建或编译的所有函数,以及大部分状态。当你在下一次会话中加载它时,就几乎像你没有退出clisp一样。这个方法因实现而异,在clisp、sbcl等之间有所不同。我将向你展示如何在clisp中操作。
但是,这种方法的问题是你无法打开文件并进行编辑,将其发布到github上或其他地方。我将给出一个简短的例子。
ataylor:~ $ clisp
blah blah
[1]> (defun add-two (a b) (+ a b))
ADD-TWO
[2]> (add-two 1 2)
3
[3]> (EXT:SAVEINITMEM)
;; Wrote the memory image into lispinit.mem (3,422,616 bytes)
Bytes permanently allocated: 171,840
Bytes currently in use: 3,243,400
Bytes available until next GC: 808,130
3243400 ;
808130 ;
171840 ;
1 ;
65640 ;
7834
[4]>
Bye.
-M
标志将其返回给clisp。ataylor:~ $ clisp -M lispinit.mem
blah blah
[1]> (add-two 1 2)
3
clisp
交互方式进行实验,请将整个终端回滚历史记录复制到文件中,然后运行:sed -n -e 's/^\[[0-9]\+\]> //;tstuff' -e 'b;:stuff' -e 'p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/{s/.*//;h;d;};h;n;p;x;G;brep' myfile.lisphist > myfile.lisp
clisp -repl myfile.lisp
,然后就完成了!你回到了上次会话的地方。当然,要交互式加载,你应该删除最后一行(quit)
。:)sed
命令,它的作用是查找clisp
提示符[number]>
,然后打印该行(删除提示符),然后尝试平衡括号。如果成功,则扫描下一个提示符;如果括号不平衡,则打印行直到平衡为止。sed -n -e '/^\[[0-9]\+\]> /{s///;p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}' myfile.lisphist > myfile.lisp
emacs
; 我一直在使用直接在命令行调用的clisp
。我不知道SLIME中是否有回滚历史记录。)