Elisp 中各种形式的循环和迭代
Various forms of looping and iteration in Elisp
我试图理解 Emacs Lisp 中的所有循环结构。
在一个示例中,我尝试遍历符号列表并将它们打印到 *message*
缓冲区,如下所示:
(let* ((plist package-activated-list) ;; list of loaded packages
(sorted-plist (sort plist 'string<)))
(--map (message (format "%s" it)) sorted-plist))
--map
是包 dash.el
.
中的一个函数
如何在纯 Elisp 中执行此操作?
现在如何在不使用其他包的情况下在 Elisp 中迭代列表。
我看过一些使用 while
和 dolist
宏的例子,例如这里:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Iteration.html
但这些都是破坏性的、非功能性的循环表达方式。
来自 Scheme
(大约二十年前使用它和 SICP!),我倾向于更喜欢功能性的、非破坏性的(这是否总是导致递归?)表达想法的方式。
那么在 Emacs Lisp 中遍历项目列表的惯用方法是什么?
另外:有没有办法在 Emacs Lisp 中以函数式方式表达循环?
到目前为止我发现了什么
- 循环宏(来自 Common Lisp?)前缀为“cl-*”
https://www.gnu.org/software/emacs/manual/html_node/cl/Loop-Facility.html
- 迭代子句
https://www.gnu.org/software/emacs/manual/html_node/cl/Iteration-Clauses.html#Iteration-Clauses
Dash.el
https://github.com/magnars/dash.el
Magnar Sveen 的优秀软件包作为“Emacs 的现代列表 api。不需要 'cl'。”
还有什么?有推荐读物吗?
dolist
不是破坏性的,这可能是 Emacs Lisp 或 Common Lisp 中最惯用的方式,当您只想依次对每个成员做某事时循环遍历列表:
(setq *properties* '(prop1 prop2 prop3))
(dolist (p *properties*)
(print p))
seq-doseq
函数的作用与 dolist
相同,但它接受序列参数(例如,列表、向量或字符串):
(seq-doseq (p *properties*)
(print p))
如果需要更实用的样式,seq-do
function applies a function to the elements of a sequence and returns the original sequence. This function is similar to the Scheme procedure for-each
,它也用于它的副作用。
(seq-do #'(lambda (p) (print p)) *properties*)
有许多本机 ~map~ 函数可供您探索以遍历列表,其中包含一些小技巧或糖分。
在这种情况下,我选择 `mapconcat',它是从 C 代码加载的。
(mapconcat #'message sorted-plist "\n")
如果您正在寻找更传统的 Lisp map
函数,e-lisp 有它们:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Mapping-Functions.html#Mapping-Functions
在您的代码片段中,mapc
可能是您想要的(丢弃值,只需应用函数;如果您需要值,mapcar
仍然存在):
(mapc #'(lambda (thing) (message (format "%s" thing))) sorted-plist)
我试图理解 Emacs Lisp 中的所有循环结构。
在一个示例中,我尝试遍历符号列表并将它们打印到 *message*
缓冲区,如下所示:
(let* ((plist package-activated-list) ;; list of loaded packages
(sorted-plist (sort plist 'string<)))
(--map (message (format "%s" it)) sorted-plist))
--map
是包 dash.el
.
如何在纯 Elisp 中执行此操作?
现在如何在不使用其他包的情况下在 Elisp 中迭代列表。
我看过一些使用 while
和 dolist
宏的例子,例如这里:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Iteration.html
但这些都是破坏性的、非功能性的循环表达方式。
来自 Scheme
(大约二十年前使用它和 SICP!),我倾向于更喜欢功能性的、非破坏性的(这是否总是导致递归?)表达想法的方式。
那么在 Emacs Lisp 中遍历项目列表的惯用方法是什么?
另外:有没有办法在 Emacs Lisp 中以函数式方式表达循环?
到目前为止我发现了什么
- 循环宏(来自 Common Lisp?)前缀为“cl-*”
https://www.gnu.org/software/emacs/manual/html_node/cl/Loop-Facility.html
- 迭代子句
https://www.gnu.org/software/emacs/manual/html_node/cl/Iteration-Clauses.html#Iteration-Clauses
Dash.el
https://github.com/magnars/dash.el
Magnar Sveen 的优秀软件包作为“Emacs 的现代列表 api。不需要 'cl'。”
还有什么?有推荐读物吗?
dolist
不是破坏性的,这可能是 Emacs Lisp 或 Common Lisp 中最惯用的方式,当您只想依次对每个成员做某事时循环遍历列表:
(setq *properties* '(prop1 prop2 prop3))
(dolist (p *properties*)
(print p))
seq-doseq
函数的作用与 dolist
相同,但它接受序列参数(例如,列表、向量或字符串):
(seq-doseq (p *properties*)
(print p))
如果需要更实用的样式,seq-do
function applies a function to the elements of a sequence and returns the original sequence. This function is similar to the Scheme procedure for-each
,它也用于它的副作用。
(seq-do #'(lambda (p) (print p)) *properties*)
有许多本机 ~map~ 函数可供您探索以遍历列表,其中包含一些小技巧或糖分。
在这种情况下,我选择 `mapconcat',它是从 C 代码加载的。
(mapconcat #'message sorted-plist "\n")
如果您正在寻找更传统的 Lisp map
函数,e-lisp 有它们:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Mapping-Functions.html#Mapping-Functions
在您的代码片段中,mapc
可能是您想要的(丢弃值,只需应用函数;如果您需要值,mapcar
仍然存在):
(mapc #'(lambda (thing) (message (format "%s" thing))) sorted-plist)