有人看过 spacemacs 新的 double dot layer system 了吗?

这还是Ldbeth说的, 有人看过spacemacs新的double dot layer system了吗?

感觉怎么样啊?

看了这个我才发现Emacs有面对对象……看到defclass的时候我都惊了

Emacs Lisp 中的面向对象叫做 EIEIO (Enhanced Implementation of Emacs Interpreted Objects), 来自 CLOS (Common Lisp Object System)。似乎没多少人使用。

在我所安装的第三方 package 中,只有 helm 有用到(并且大量使用),难道这就是 helm 代码臃肿/复杂的原因?:joy: 不理解的是,helm 定义了很多 class,最后却又当作 alist 来用。

内置的 package 中,大量用到 eieio 的是 cedet,年轻的朋友可能不知道这是什么。

1 个赞

EIEIO 是 Emacs Lisp 面向对象的其中一种实现,在旧有的 Common Lisp 兼容包上改进的(这个兼容包本来就有面向对象系统)。其他还有一些轻量面向对象系统,比如 Wanderlust 和 w3m 用的是 FLIM 的基于 Pratical Common Lisp 中实现的简易 CLOS 的 luna;参照了 Smalltalk 的 EOOPS。

EIEIO 和 Cedet 的关系类似于 Wanderlust 和 FILM,本身其实是同一个项目根据库和功能拆开了写,只是也有别的项目用这个库。

从这可以差不多看到在 Emacs Lisp 中用面向对象的基本是 CL 用户。

按照 CL 的习惯,数据结构很多会用 class 来实现。主要是为了扩展性和自动化。类似于 C++ 用 class 而不是 struct 的原因。

2 个赞

看完后的感想是,现在不是 Lisp 砖家怕是都 hack 不动 Spacemacs 了。

潜台词就是: 年轻人先来学一遍 Pratical Common Lisp 再来用 Emacs 吧。

本来在 Emacs 扩展都以单独的包发布的时候,想 Hack 了可以直接 C-h f 看看源代码然后吐槽一下风格,大部分时候代码逻辑都是比较清晰的。修改用 advice,才是 Emacs 比较推荐的做法。

大幅引入抽象以后,对于作者来说写是可以少写了,不是对项目特别熟的怕是动不了了。没有面向对象编程和 Lisp 经验的人连某个功能在哪里实现的都找不到。算是做绝了点。

我之前看spacemacs的时候也是感觉抽象很多,导致我看不懂配置。这下怕是更多了。

然而在 Emacs Lisp 中,用 struct 的情况占多数。

struct 也是可以扩展的:

(cl-defstruct person name (age 0) sex)

(cl-defstruct (astronaut (:include person (age 45)))
  helmet-size
  (favoite-beverage 'tang))

(setq joe (make-person :name "Joe"))
(setq buzz (make-astronaut :name "Buzz"))

改为 class:

(defclass person ()
  ((name) (age :initform 0) (sex)))

(defclass astronaut (person)
  ((age :initform 45)
   (helmet-size)
   (favoite-beverage :initform 'tang)))

(setq joe (person :name "Joe"))
(setq buzz (astronaut :name "Buzz"))

如果是我,可能会这样定义成员函数:

(defmethod walk ((p person))
  (message "walking on earth"))

(defmethod walk ((p astronaut))
  (message "walking in space"))

(walk joe)
(walk buzz)

在 helm 中更多是这样的:

(defclass person ()
  (;;...
   (walk
    :initarg :walk
    :initform (lambda ()
                (message "walking on earth")))))

(defclass astronaut (person)
  (;;...
   (walk
    :initarg :walk
    :initform (lambda ()
                (message "walking in space")))))

(funcall (oref joe :walk))
(funcall (oref buzz :walk))

可能这样更方便迭代吧。

Spacemacs —— 重新发明了 Emacs 配置

find-function只能跳转到文件开头,无法跳到定义处,很尴尬

不该用 describe-function

不记得是什么函数……因为都是用spacemacs doom-emacs快捷键的

我都是C-h f 然后鼠标点就能直接跳转函数了。记得是describe function

不过往好处想的话,反正新手已经看不懂spacemacs了,如果改写能让spacemacs效率翻倍功能完善配置清晰也挺好的。

我开始hack spacemacs的时候都是从在user-config里写小片段开始,后来干脆开始自己的配置了,从头到尾没有看spqcemacs实现。中间弄自己的layer的时候看过spacemacs layer的配置。

是指用宏批量生成函数然后find-function找不到的那些么?

defmethod 也算这类吧。

如果是 (defmethod foo () ...) 这种形式,出来的函数名仍然是 foo,还是能跳转的。 find-function 是先切换到定义所在的文件,然后正则表达式全文查找,所以只要往 find-function-regexp{,-alist} 添加规则就能匹配到。

如果定义 (definitfun foo () ...),然后生成的函数名 init//foo,这种就不太好办了。

defmethod 问题在如果分了好几个文件就麻烦了。

double dot 这个分支好像也被抛弃了,现在repo owner最新的 commit 在 moon 分支上。只是也有快一个月没更新了。感觉作者在酝酿什么大招,而且不实现就暂时不合并任何 PR。

哇是吗,我去看看

爲什麼不是原作者棄坑了……

是这样吗?如果是就太可惜了,本来以为可以一直发展下去的。最近确实一直没什么动静了。