elisp 短路处理

我有下面一段逻辑,有更好的短路处理吗?

(defun fun1 ()
...)

(defun fun2 ()
...)

(defun fun3 ()
...)

(defun check-fun()
   (or (fun1)
        (fun2)
        (fun3)))

一旦有一个函数处理成功,其后面的函数就不执行了。

我目前的写法,是保证每个函数都在最后返回一个bool值,还有更好的写法吗?

比如下面的函数

(defun gd-emedit-open (start-ins end-ins &optional special-open)
  (or (region-round start-ins end-ins)
      (direct-insert start-ins)
      (if (null special-open)
          (pair-insert start-ins end-ins)
        (funcall special-open))))

要保证region-round,direct-insert和pair-insert ,还有传进来得special-open都有bool返回值或nil

如果不用返回值,怎么判断程序执行成功了没?

我想问得是,有没有像scheme那种,continuation的那种写法,或其他什么类似的写法。

比如一个比较笨的写法,外层catch,内层throw

elisp里还有没有,其它控制流程的写法?

不太懂,这是啥? :sweat_smile:

不太喜欢这种catch和throw的写法,本质就是goto。

用 catch 并没有什么问题。

“Goto considered harmful” considered harmful

scheme里的一种控制流程的机制,一时我也说不清楚。google一下吧,一般翻译成"继续“。

这么写有性能方面的问题吧?

没有,出于一些设计,几乎所有 Lisp 的异常处理是零开销的。

程序员们总是吃饱的闲着慌的,好比Java的时候大家都捧exception。现在反而觉得用返回值真香。 :rofl:

elisp里没有continution的概念吧?上面的代码还有比catch更好看的改法吗?

没有。另外,continuation 本质上就是 coroutine。

所以你可以试试这个 EmacsWiki: coroutine.el

如果你愿意用 cl-lib 的话可以用 return-from。 不过并没有什么区别。

1 个赞

except能处理复杂的情况,返回值要麻烦很多

好的,谢谢!我就是想通过不同的方式写来学习elisp。

高版本的emacs内置的generator.el就有iter-defun。和这个coroutine.el没差多少

1 个赞

generator 和 coroutine 并不一样,generator 保存的“状态”只是个本地的值,coroutine 保存的是全局的计算状态,conceptually 即整个 stack frame。也就是说 generator 并不能提供 control flow 的功能。

Emacs Lisp 没有专门的 bool 值的概念,条件判断中 nil 为假,其它值均为真,所以一切函数都必然返回一个 bool 值。


你的问题不够清楚,请尽可能完整的描述你的问题,给出的代码要可以运行,也不要夹带对答案的假设。

问题解决了,下次我再描述清楚一点。