在elisp我可以评估或作为一个函数就像+.
(or nil 0 nil) ==> 0
(+ 1 0 1) ==> 2
Run Code Online (Sandbox Code Playgroud)
我可以使用apply来将+应用到列表中
(apply '+ '(1 0 1)) ==> 2
Run Code Online (Sandbox Code Playgroud)
所以,我会想或者会以同样的方式工作,但事实并非如此.
(apply 'or '(nil 0 nil)) ==> error: (invalid-function or)
Run Code Online (Sandbox Code Playgroud)
我想这是来自用于实现短路评估的一些内部魔术.如何使用apply对列表执行或操作?
PS我想要的应用程序是找出命令行上的任何元素是否与特定模式匹配,所以我写的重要部分是:
(apply 'or (mapcar (lambda (x) (string-match-p "pattern" x)) command-line-args))
Run Code Online (Sandbox Code Playgroud)
但它不起作用
Eli*_*lay 21
问题在于它or是一个宏(这是所讨论的"内部魔法"),你说得对,它可以做短路.如果or是一个函数,那么调用它将需要遵循用于评估函数调用的通常规则:在调用之前需要对所有参数进行求值.
另请参阅这个问题 - 它是关于Scheme的,但它是完全相同的问题.
至于解决方案,您应该使用some,如:
(some (lambda (x) (string-match-p "pattern" x)) command-line-args)
Run Code Online (Sandbox Code Playgroud)
注意:这使用默认情况下未包含在emacs中的常见lisp.只是用(require 'cl)
Ken*_*Ken 10
如果它让你感觉更好,那你就是一个好伙伴!这是Lisp FAQ的"常见陷阱"部分中的第三个问题:
这是简单但不一定令人满意的答案:AND和OR是宏,而不是函数; APPLY和FUNCALL只能用于调用函数,而不能用于调用宏和特殊运算符.
...... Eli当然正确地使用了他的建议SOME:
Common Lisp函数EVERY和SOME可用于在尝试应用#'AND和#'OR时获得您想要的功能.
(FAQ和这个答案主要是关于Common Lisp,但在这种情况下,如果省略#字符,答案是相同的.)
| 归档时间: |
|
| 查看次数: |
2801 次 |
| 最近记录: |