在Peter Seibel的书"Practical Common Lisp"中,我们可以找到一次非常复杂的宏的定义(参见页面底部http://www.gigamonkeys.com/book/macros-defining-your-own.html).
我在过去3周内第10次阅读这个宏定义,无法理解它是如何工作的.:(更糟糕的是,我不能自己开发这个宏,即使我理解它的目的以及如何使用它.
我对这个臭名昭着的宏观系统"衍生"特别感兴趣,一步一步!有帮助吗?
在Practical Common Lisp的第8章,宏:定义你自己,我们定义一个宏with-gensyms如下:
(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body))
Run Code Online (Sandbox Code Playgroud)
这是什么目的(&rest names)?如果我们用just替换它names,效果似乎是一样的.在这两种情况下,我们都将符号列表传递给"gensym-ed".
我正在阅读Peter Seibel的Practical Common Lisp.在第9章中,他正在通过创建单元测试框架来引导读者,并且他包含以下宏来确定列表是否仅由真实表达式组成:
(defmacro combine-results (&body forms)
(let ((result (gensym)))
`(let ((,result t))
,@(loop for form in forms collect `(unless ,form (setf ,result nil)))
,result)))
Run Code Online (Sandbox Code Playgroud)
我不清楚使用宏的优势在于什么 - 似乎以下内容会更清晰,并且对于动态值更有效:
(defun combine-results (&rest expressions)
(let ((result t))
(loop for expression in expressions do (unless expression (setf result nil)))
result))
Run Code Online (Sandbox Code Playgroud)
宏的优点是,它在运行时对于在编译时扩展的任何调用更有效吗?或者它是一个范例的东西?或者这本书只是试图找借口在宏中练习不同的模式?
我正在阅读Gigamonkey(Peter Seibel的)Practical Common Lisp,并在Macros章节中关于DO的部分中遇到了以下声明:
与LET中的变量定义一样,如果省略init-form,则变量绑定到NIL.与LET一样,您可以使用普通变量名作为仅包含名称的列表的简写.
我不知道他的意思是"使用普通变量作为缩写,只包含名称的列表",即第二句.第一句是在LET的Common-Lisp Hyperspec中备份的,通过一个简单的例子(let (n) n) ~~> NIL,但我找不到与第二句相对应的任何内容.事实上,像是(let n n)一个SBCL编译器.
这是什么意思?这个用法的最小例子是什么?
因此,我再次经历了实践通用Lisp,我真的无法理解如何创建具有恒定大小的向量。
根据这本书:
但是,即使具有填充指针的向量也不能完全调整大小。向量* x *最多可以包含五个元素。要制作可任意调整大小的向量,您需要传递MAKE-ARRAY另一个关键字参数::adjustable。
但是,当我使用时,(vector-push-extend)即使设置:adjustable nil(或将其保留为默认值),我也可以扩展初始向量。
(vector-push 'a *x*) ;; 0
(vector-push 'b *x*) ;; 1
(vector-push 'c *x*) ;; 2
(vector-push 'd *x*) ;; 3
(vector-push 'e *x*) ;; 4
*x* ;; #(A B C D E)
(vector-push 'f *x*) ;; NIL
*x* ;; #(A B C D E)
(vector-push-extend 'f *x*) ;; 5
*x* ;; #(A B C D E F)
Run Code Online (Sandbox Code Playgroud)
我认为(vector-push-extend)不能调整数组的大小,这不是:adjustable吗?创建非动态(不可调整)数组的正确方法是什么?
我正在阅读《实践通用Lisp》,对Lisp的COPY-TREE功能有疑问。
这本书给出了调用的例子
(copy-tree '( '(1 2) '(3 4) '(5 6)))
Run Code Online (Sandbox Code Playgroud)
在解释了它之后,本书做出了如下声明:
如果原始文件中的cons单元引用了原子值,则副本中相应的cons单元将引用相同的值。因此,原始树和COPY-TREE生成的副本共同引用的唯一对象是数字5、6和符号NIL。
但这对我来说没有意义。我认为所有原子都将在原始和新原子之间共享。因此,我希望在原始副本和副本之间共享1、2、3、4、5、6和NIL,并且唯一的“新对象”将是所有CONS单元。
哪一个是正确的,为什么?
谢谢。
我正在阅读Practical Common Lisp.在第11章中,它说明了有关排序:
通常,在对序列进行排序后,您不会关心序列的未排序版本,因此在排序过程中允许
SORT和STABLE-SORT销毁序列是有意义的.但它确实意味着你需要记住写下面的内容:Run Code Online (Sandbox Code Playgroud)(setf my-sequence (sort my-sequence #'string<))
我尝试了以下代码:
CL-USER> (defparameter *a* #( 8 4 3 9 5 9 2 3 9 2 9 4 3))
*A*
CL-USER> *a*
#(8 4 3 9 5 9 2 3 9 2 9 4 3)
CL-USER> (sort *a* #'<)
#(2 2 3 3 3 4 4 5 8 9 9 9 9)
CL-USER> *a*
#(2 2 3 3 3 4 4 5 8 9 …Run Code Online (Sandbox Code Playgroud) 我正在与SBCL(SBCL 1.2.13.84-7d75f89)一起学习本书中的 Common Lisp .我遇到了一个问题,试图找到并加载名为的包multiprocessing.
我曾尝试做(ql:system-apropos "multiprocessing"),(ql:system-apropos "thread"),(ql:system-apropos "smp")想看看是否有一个使用它的quicklisp包.
我也使用谷歌搜索,甚至在Quickdocs,但我似乎在某处失败.
如有任何帮助,我将不胜感激.
该代码伴随着书实用的Common Lisp包含ASDF文件.如何使用Quicklisp加载此代码?
在实用Common Lisp的第8章末,Peter Seibel展示了once-only宏观.其目的是通过用户定义的宏中的变量评估来缓解一些微妙的问题.注意我在这一点上并没有试图理解这个宏如何工作,就像在其他一些帖子中一样,但是如何正确使用它:
(defmacro once-only ((&rest names) &body body)
(let ((gensyms (loop for n in names collect (gensym))))
`(let (,@(loop for g in gensyms collect `(,g (gensym))))
`(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n)))
,(let (,@(loop for n in names for g in gensyms collect `(,n ,g)))
,@body)))))
Run Code Online (Sandbox Code Playgroud)
以下是一个示例(不正确)设计宏,试图展示几个变量评估问题.它声称通过某个delta迭代一系列整数,返回范围:
(defmacro do-range ((var start stop delta) &body body)
"Sample macro with faulty variable evaluations."
`(do ((,var ,start (+ ,var ,delta))
(limit …Run Code Online (Sandbox Code Playgroud) 我在“实践通用Lisp”(优秀书籍)的第26章上。我正在尝试从https://github.com/Apress/practical-common-lisp下载:
CL-USER> (defpackage :com.gigamonkeys.web
(:use :cl :net.aserve :com.gigamonkeys.html))
Run Code Online (Sandbox Code Playgroud)
这给出了这个错误:
(There is no package named "NET.ASERVE" .
[Condition of type CCL::NO-SUCH-PACKAGE])
Run Code Online (Sandbox Code Playgroud)
克隆https://github.com/franzinc/aserve.git后, 我运行了:
CL-USER> (asdf:oos 'asdf:load-op :aserve)
Run Code Online (Sandbox Code Playgroud)
但出现错误:
There is no package named "EXCL" .
[Condition of type CCL::NO-SUCH-PACKAGE]
Run Code Online (Sandbox Code Playgroud)
我找不到EXCL软件包,所以我安装了Portableaserve并运行:
CL-USER> (load "~/GitHub/portableaserve/INSTALL.lisp")
Run Code Online (Sandbox Code Playgroud)
但又得到了:
there is no package named "EXCL" .
[Condition of type CCL::NO-SUCH-PACKAGE]
Run Code Online (Sandbox Code Playgroud)
有人会知道如何在Mac上的lispbox-0.7内安装allegroserve(包括EXCL)来运行上述defpackage命令吗?
在"Practical Common Lisp"的第3章中,我们被要求通过创建一个make-cd定义如下的函数来创建CD数据库:
(defun make-cd (title artist rating ripped)
(list :title title :artist artist :rating rating :ripped ripped))
Run Code Online (Sandbox Code Playgroud)
在我的REPL中(使用SLIME)这似乎按计划进行...直到我来为数据库添加一个值,例如
(make-cd "Roses" "Kathy Mattea" 7 t)
(:TITLE "Roses" :ARTIST "Kathy Mattea" :RATING 7 :RIPPED T)
Run Code Online (Sandbox Code Playgroud)
然后我收到以下错误消息
Undefined function :TITLE called with arguments ("Roses"
:ARTIST
"Kathy Mattea"
:RATING
7
:RIPPED
T) .
[Condition of type CCL::UNDEFINED-FUNCTION-CALL]
Run Code Online (Sandbox Code Playgroud)
这段代码是书中所写的字符字符,没有任何说明可以解释错误或此错误的含义.
我是Lisp的新手,不知道这里出了什么问题!