elisp里不少标准函数有 destructive(none consing),也有 copy(consing) 的,有的函数两种都有。我觉得写项目的时候这种最好还是统一,不然很容易不小心写出bug。
那么,在1)一个项目里,尤其是围绕一个中心的数据结构的项目里,应该选择哪种呢?
2)elisp会不会更适合某一个模式?
3)这两种模式在elisp里有没有什么特殊的特性(优缺点)?
(还是两种没啥区别,基本上是我庸人自扰?)
(伸个手)
elisp里不少标准函数有 destructive(none consing),也有 copy(consing) 的,有的函数两种都有。我觉得写项目的时候这种最好还是统一,不然很容易不小心写出bug。
那么,在1)一个项目里,尤其是围绕一个中心的数据结构的项目里,应该选择哪种呢?
2)elisp会不会更适合某一个模式?
3)这两种模式在elisp里有没有什么特殊的特性(优缺点)?
(还是两种没啥区别,基本上是我庸人自扰?)
(伸个手)
别到处显式用列表就行。多用 就 elisp 这穷样,还是用列表吧(不穷,怎么老是讲穷人的哈希表云云嘛)defstruct
和 hash table。
Copy(Consing) 没性能,要大量采用,除非是想玩 immutable data structure,然而 elisp 也没这个条件。
该怎么写就怎么写,怎么写自然就怎么写,不要把问题复杂化。
哪里有by value了
哪个又是by reference呢?
例子
所以到底是哪种效率比较高?列表还是hash table?我一般列表用alist。谢谢
emasc本来性能一般,用copy好像的确不大好。
比如setcar
,setcdr
这种就是reference,append
这种就是copy
哈希表存取时间在非最坏情况下与整个表大小无关,最坏情况(空间不够需要扩展)要复制整个表,另外要预先分配内存。
alist 存取时间和深度相关,另外额外占用列表长度数量的指针空间。
说人话就是,大量数据用哈希表,那种在十个 entry 以下的就用 alist 好了。
他们都是C函数 你要是也能写C函数 你就不用为这个问题发愁了
Nothing is true, everything is premitted. (要啥沒啥,爱咋咋地)
(defun append (&rest lists)
"Construct a new list by concatenating the list arguments"
(if lists
(let* ((head (cons nil nil))
(tail head))
(do* ()
((null lists) (cdr head))
(let* ((list (pop lists)))
(if (null lists)
(rplacd tail list)
(dolist (element list)
(setq tail (cdr (rplacd tail (cons element nil)))))))))))
(defun setcar (x y) (setf (car x) y))
(setq zxc '(56 78))
(macroexpand '(setf (car zxc) 78)) ==> (let* ((v zxc)) (setcar v 78))
哪有什么by value 都是reference(C函数才能产生新的reference)
重点在 copy。题主不懂名词望文生意拿来乱用罢了。
另外我太懒了,不想在抄一个不用 setcar
的 setf
(也太长了,大概几百来行)
链接 有 也行
本来想说修改原参数,感觉好像不对。没学过想不出来词啊
ccl 和 elisp 不一样的吧
除了有个利用 method 的 dispatch 有点难搞(其实也不难搞),剩下的都可以用 cl-lib 套。我本地还有个用 Lisp Machine Lisp 写的 SETF
,和 Emacs Lisp 更接近,就是因為 license 不能隨便发。