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

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。

哇是吗,我去看看

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

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

应该没弃坑吧,之前3月份在twitter上有说明


可能遇到什么问题,在攻克吧

2 个赞

感觉 advice 机制,就是从clos得到灵感的,个人感觉,基于广义函数的面向对象比大多数人熟悉的面向对象,更符合直觉