在329页的Lisp的土地,康拉德Barski解释的技术记忆化与下面的示例代码
(let ((old-neighbors (symbol-function 'neighbors))
(previous (make-hash-table)))
(defun neighbors (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-neighbors pos)))))
Run Code Online (Sandbox Code Playgroud)
这个想法很好:当我调用该neighbors函数时,我将结果保存到哈希表中,以便下次neighbors使用相同的值调用时pos,我可以查找结果而无需再次计算它.
所以我想知道,是否不会是更容易的功能重新命名neighbors,以old-neighbors通过编辑和重新编译它的源代码(书的314页上给出).然后可以将memoization示例简化为
(let ((previous (make-hash-table)))
(defun neighbors (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-neighbors pos)))))
Run Code Online (Sandbox Code Playgroud)
或者,通过事先previous变成一个全局变量*previous-neighbors*,甚至进入
(defun neighbors (pos)
(or (gethash pos *previous-neighbors*)
(setf (gethash pos *previous-neighbors*) (funcall old-neighbors pos))))
Run Code Online (Sandbox Code Playgroud)
从而使封闭不必要.
所以我的问题是:这样做的原因是什么?
我能想象的原因:
symbol-function …我怎么知道我是否称为回指宏?如果我在不知情的情况下这样做,一些看似未绑定的符号可能会与人们期望的完全不同.
从列表中收集所有偶数很容易:
> (loop for i in '(1 2 3 4) ;correct
when (evenp i) collect i)
(2 4)
Run Code Online (Sandbox Code Playgroud)
但是,如果有人得到了给迭代变量赋予名称的好主意it(因为"它"似乎是"item"的一个很好的缩写;也是C++人经常使用一个名为迭代器的迭代it),结果突然大不相同:
> (loop for it in '(1 2 3 4) ;wrong
when (evenp it) collect it)
(T T)
Run Code Online (Sandbox Code Playgroud)
这可能听起来很人为,但最近这个尴尬的错误发生在我认识的人身上.
那么如何避免再次陷入这种类型的错误呢?
每次我用 Meshlab 打开一个 STL 文件时,都会弹出一个窗口并询问我是否要“统一重复顶点”。我总是必须按“确定”按钮,这有点烦人。我怎么能告诉 Meshlab 它应该总是在不问的情况下统一它们?
谢谢!
最近,我经常嵌套几个返回多个值的函数。然而,与let允许将这些调用优雅地写成一个大语句的 不同,我总是以大量缩进结束。
我的问题是:有几个多值函数,例如
(defun return-1-and-2 ()
(values 1 2))
(defun return-3-and-4 ()
(values 3 4))
Run Code Online (Sandbox Code Playgroud)
是否有可能达到与
(multiple-value-bind (one two)
(return-1-and-2)
(multiple-value-bind (three four)
(return-3-and-4)
(list one two three four)))
Run Code Online (Sandbox Code Playgroud)
但写得更简洁 - 方式let,即,类似
(multiple-value-bind (one two)
(return-1-and-2)
(multiple-value-bind (three four)
(return-3-and-4)
(list one two three four)))
Run Code Online (Sandbox Code Playgroud)
?
一边念叨CLOS(在ANSI Common Lisp的由保罗·格雷厄姆),我注意到,有一些可以给九项职能defmethod作为其第二个参数:
+,and,append,list,max,min,nconc,or和progn.根据这个答案,它们被称为简单方法组合.
为什么只有这九个?我不能将任意函数作为第二个参数传递的原因是什么?
假设我定义xor为
(defun xor (&rest args)
(loop for a in args counting (not (null a)) into truths
finally (return (= truths 1))))
Run Code Online (Sandbox Code Playgroud)
(这当然可以改善).我想用以下方法定义描述衣服及其组合的几个类xor:
(defgeneric looks-cool (x)
(:method-combination xor))
(defclass black-trousers () ())
(defclass quilt () ())
(defclass white-shirt () ())
(defclass hawaii-shirt () ())
(defmethod …Run Code Online (Sandbox Code Playgroud) 是否有一个 Common Lisp 构造是 to labelswhat defmethodis to defun?也就是说,我想使用labels(或类似的东西)来定义几个具有相同名称但它们接受的参数不同的局部函数,并让编译器在其中进行选择。
作为 MWE,我想实现以下功能
(defmethod write-first-item-type ((lst list))
"Writes the type of the first item in lst."
(labels ((write-single ()
(format t "a single float"))
(write-double ()
(format t "a double float")))
(format t "The first item is: ~A.~%"
(cond ((eql (type-of (car lst)) 'single-float)
(write-single))
((eql (type-of (car lst)) 'double-float)
(write-double))
(t
(format t "unknown"))))))
Run Code Online (Sandbox Code Playgroud)
像
(defmethod write-first-item-type ((lst list))
"Should write the type of the first …Run Code Online (Sandbox Code Playgroud) common-lisp ×5
clos ×1
function ×1
land-of-lisp ×1
let ×1
lisp ×1
macros ×1
memoization ×1
meshlab ×1
oop ×1
overloading ×1
scope ×1
stl-format ×1
types ×1