我正在通过格雷厄姆的书"On Lisp"工作,并且无法理解第37页的以下示例:
If we de?ne exclaim so that its return value incorporates a quoted list, (defun exclaim (expression) (append expression ’(oh my))) > (exclaim ’(lions and tigers and bears)) (LIONS AND TIGERS AND BEARS OH MY) > (nconc * ’(goodness)) (LIONS AND TIGERS AND BEARS OH MY GOODNESS) could alter the list within the function: > (exclaim ’(fixnums and bignums and floats)) (FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS) To make exclaim proof against such problems, it should be written: (defun exclaim …
这段经文On Lisp真的让人感到困惑 - 目前尚不清楚返回引用列表'(oh my)如何能够真正改变函数未来的行为方式:不会在函数中从头开始再次生成返回的列表,下一次是叫什么名字?
如果我们定义exclaim以使其返回值包含引用列表,
Run Code Online (Sandbox Code Playgroud)(defun exclaim (expression) (append expression ’(oh my)))然后任何后来破坏性修改返回值
Run Code Online (Sandbox Code Playgroud)(exclaim ’(lions and tigers and bears)) -> (LIONS AND TIGERS AND BEARS OH MY) (nconc * ’(goodness)) -> (LIONS AND TIGERS AND BEARS OH MY GOODNESS)可以改变函数中的列表:
Run Code Online (Sandbox Code Playgroud)(exclaim ’(fixnums and bignums and floats)) -> (FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS)为了对这些问题作出惊呼证据,应写成:
Run Code Online (Sandbox Code Playgroud)(defun exclaim (expression) (append expression (list ’oh ’my)))
最后一次调用exclaim将goodness结果添加到结果中的确切方式是什么?该函数没有引用任何外部变量,那么单独的调用如何nconc实际改变exclaim函数的工作方式?
我真的想学习Scheme宏.我浏览了一下"On Lisp"的内容,很多章节都专门讨论了Lisp宏.但是我不知道常见的口齿不清.我可以用它来学习Scheme宏吗?
在On Lisp,p.267,Paul Graham提供了一个继续传递宏的实现:
(setq *cont* #'identity)
(defmacro =lambda (parms &body body)
`#'(lambda (*cont* ,@parms) ,@body))
(defmacro =defun (name parms &body body)
(let ((f (intern (concatenate 'string
"=" (symbol-name name)))))
`(progn
(defmacro ,name ,parms
`(,',f *cont* ,,@parms))
(defun ,f (*cont* ,@parms) ,@body))))
(defmacro =bind (parms expr &body body)
`(let ((*cont* #'(lambda ,parms ,@body))) ,expr))
(defmacro =values (&rest retvals)
`(funcall *cont* ,@retvals))
Run Code Online (Sandbox Code Playgroud)
以下代码遍历树t2的每个叶子的树t1,使用此实现,我想知道restart调用时会发生什么,特别是在t1从A(第一个元素)更改为B(第二个元素)的叶子之后.当restart被调用时,它只是从弹出lambda函数*saved*,而lambda函数调用dft-node …
在On Lisp(第84页)格雷厄姆说
‘(a b c)(没有逗号)等于’(a b c)
然后说
反引号列表相当于对引用元素的列表调用.
也就是说,‘(a b c)(没有逗号)等于(list ’a ’b ’c).
一个语句是因为假的'(a b c),并(list 'a 'b 'c)似乎并不相等.后者是一个新的consed列表(可以安全地修改),而前者是一个常量 - 或者至少规范允许编译器对其进行处理.
所以也许这是一个非常挑剔的问题,但是是一个反引号列表(没有逗号),如‘(a b c)等于'(a b c)或等于(list 'a 'b 'c)?
我正在阅读Paul Graham 的On Lisp,试图更好地理解编程的函数式风格。在第 3 章中,他提到函数式程序“通过返回值来工作”,而不是产生副作用。我不太明白该声明对如何操作和表示过程的中间结果的影响。如果函数式程序返回一个值,那么使用捕获它(let)是否等同于使用(lambda)函数?
下面的示例显示了函数 的定义,(group)使用 lambda 函数捕获中间结果。(group)接受一个列表src和一个数字n,并将列表元素细分为k大小为 的组n。
(defun group (src n acc)
(funcall
#'(lambda (back)
(cond
((consp back)
(group back n (cons (subseq src 0 n) acc)))
(t
(reverse (cons src acc)))))
(nthcdr n src)))
Run Code Online (Sandbox Code Playgroud)
该函数的最后一行通过获取(nthcdr n src). 然后,这个结果作为参数传递给 lambda 函数,该函数决定如何src根据参数进行处理。这是纯粹的功能代码,没有副作用。另一方面,我可以用(group)以下方式定义:
(defun group (src n acc)
(let ((back (nthcdr n src)))
(cond …Run Code Online (Sandbox Code Playgroud)