想问一下大牛们,elisp的函数如何实现引用传递?


#1
;;实现(a b c d e)的一个全排列
(setq count 0)
(defun arrange-list (plist rlist temp)
  ""
  (if (= temp 5)
      (progn 
        (message "[%s]rlist:%s" count rlist)
        (setq count (1+ count)))
    (let ((i 0)
          ) 
      (while (< i 5)
        (setq rlist (cons  (nth i plist) rlist))
        (arrange-list plist rlist (1+ temp))
        (setq rlist (cdr rlist))
        (setq i (1+ i))
      )
      )
    )
)


(let ( (plist '(a b c d e))
      )
  (arrange-list plist nil 0)
)

如题,想计算出全排列的个数,这个plist在递归调用是值传递还是引用传递?如果是值拷贝,当plist规模很大时岂不是很耗内存?


#2

elisp就是pass by ref,甚至因此藏有一些陷阱


#3

参考 company--permutations 或者 -permutations 的实现。


#4

我这个是丑陋了一点哈哈,顺便问一下elisp的学习路线, 我该怎么快速掌握呢?


#5

我之前写的lambda 过程需要funcall才能调用,跟scheme不一样,奇怪,这个是elisp特有的模式吗?


#6

#7
(defun company--permutations (lst)
  (if (not lst)
      '(nil)
    (cl-mapcan
     (lambda (e)
       (mapcar (lambda (perm) (cons e perm))
               (company--permutations (cl-remove e lst :count 1))))
     lst)))

看了company–permutatios的实现,还是有点疑问,cl-xxx这种函数是elisp还是common lisp?它们可以混合起来写的吗? 还有(cl-remove e lst :count 1)里的:count 这个是什么用法? lisp程序有没有一个比较完善的类似c或java的api文档可以查询呢?


#8

Emacs自帶文檔,C-h i隨便看。

cl-*是elisp模擬的common lisp的部分實現。因爲當初RMS教主覺得cl過於複雜,所以簡化CL做出來Elisp,後來Emacs引入了詞法作用域,而且各種插件寫的越來越喪心病狂了,落後生產力跟不上人民羣衆的需要了,只好重新發明了一次CLtL1,扗Emacs裏名字叫cl-lib

cl-lib有關的文檔扗Info的CL章節裏,Elisp有關的文檔扗Elisp章節裏。

此外C-h f可以查詢函數的docstring。Emacs內置函數的docstring還是比較詳盡的。另外CL的Hyperspec有時可以用作參考 http://www.lispworks.com/documentation/HyperSpec/Front/


:count 用來限制最大移除個數

用`code`貼單行代碼

```

多行代碼

```


#9

非常感谢! 也许是我太弱了,上面的代码在结构上看不懂,这lambda的两层嵌套也太难懂了,再加上递归,我绕了半天也没绕明白,我再好好研究研究吧,谢谢!


#10

C-u M-x eval-defun 开启逐步调试