标签: practical-common-lisp

了解如何实现一次性lisp宏

在Peter Seibel的书"Practical Common Lisp"中,我们可以找到一次非常复杂的宏的定义(参见页面底部http://www.gigamonkeys.com/book/macros-defining-your-own.html).

我在过去3周内第10次阅读这个宏定义,无法理解它是如何工作的.:(更糟糕的是,我不能自己开发这个宏,即使我理解它的目的以及如何使用它.

我对这个臭名昭着的宏观系统"衍生"特别感兴趣,一步一步!有帮助吗?

lisp macros common-lisp practical-common-lisp

17
推荐指数
2
解决办法
2321
查看次数

defmacro形式参数列表中`(&rest xs)`和`xs`之间的区别

在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".

macros common-lisp pattern-matching practical-common-lisp

8
推荐指数
1
解决办法
151
查看次数

这个宏有优势吗?

我正在阅读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)

宏的优点是,它在运行时对于在编译时扩展的任何调用更有效吗?或者它是一个范例的东西?或者这本书只是试图找借口在宏中练习不同的模式?

lisp macros common-lisp practical-common-lisp

8
推荐指数
2
解决办法
139
查看次数

Common Lisp:普通变量是LET中列表的简写?

我正在阅读Gigamonkey(Peter Seibel的)Practical Common Lisp,并在Macros章节中关于DO的部分中遇到了以下声明:

与LET中的变量定义一样,如果省略init-form,则变量绑定到NIL.与LET一样,您可以使用普通变量名作为仅包含名称的列表的简写.

我不知道他的意思是"使用普通变量作为缩写,只包含名称的列表",即第二句.第一句是在LETCommon-Lisp Hyperspec中备份的,通过一个简单的例子(let (n) n) ~~> NIL,但我找不到与第二句相对应的任何内容.事实上,像是(let n n)一个SBCL编译器.

这是什么意思?这个用法的最小例子是什么?

common-lisp practical-common-lisp

6
推荐指数
1
解决办法
196
查看次数

如何保护向量免于调整大小?

因此,我再次经历了实践通用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吗?创建非动态(不可调整)数组的正确方法是什么?

vector common-lisp practical-common-lisp

5
推荐指数
2
解决办法
109
查看次数

Common Lisp的副本树:原始对象和副本将共同引用哪些对象?

我正在阅读《实践通用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单元。

哪一个是正确的,为什么?

谢谢。

common-lisp practical-common-lisp

3
推荐指数
1
解决办法
452
查看次数

lisp中的破坏性排序

我正在阅读Practical Common Lisp.在第11章中,它说明了有关排序:

通常,在对序列进行排序后,您不会关心序列的未排序版本,因此在排序过程中允许SORTSTABLE-SORT销毁序列是有意义的.但它确实意味着你需要记住写下面的内容:

(setf my-sequence (sort my-sequence #'string<))
Run Code Online (Sandbox Code Playgroud)

我尝试了以下代码:

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)

common-lisp practical-common-lisp

3
推荐指数
2
解决办法
536
查看次数

在Common Lisp中查找名为"multiprocessing"的包

我正在与SBCL(SBCL 1.2.13.84-7d75f89)一起学习本书中的 Common Lisp .我遇到了一个问题,试图找到并加载名为的包multiprocessing.

(这是在本书的第29章)

我曾尝试做(ql:system-apropos "multiprocessing"),(ql:system-apropos "thread"),(ql:system-apropos "smp")想看看是否有一个使用它的quicklisp包.

我也使用谷歌搜索,甚至在Quickdocs,但我似乎在某处失败.

如有任何帮助,我将不胜感激.

lisp common-lisp multiprocessing practical-common-lisp

3
推荐指数
1
解决办法
193
查看次数


使用`once-only`宏

实用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)

macros common-lisp practical-common-lisp

2
推荐指数
1
解决办法
175
查看次数

如何在Mac上安装aserve并将其加载到lispbox-0.7中?

我在“实践通用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命令吗?

clisp common-lisp lisp-in-a-box practical-common-lisp

1
推荐指数
1
解决办法
35
查看次数

Common Lisp的新功能,无法理解为什么defun功能在简单的情况下不起作用

在"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的新手,不知道这里出了什么问题!

common-lisp practical-common-lisp

0
推荐指数
1
解决办法
85
查看次数