看了下elisp手册,没有找到有关模块化的地方,所有定义的函数都是全局函数。 那么问题来了,我安装了那么多插件,每个插件里面又define了一堆函数,这些插件之间是如何保证函数与其他插件的函数命名都不会冲突的?难道只能前缀区分么,那限制也太大了,现代语言里都会使用一些语法来保证命名不会冲突,这是不是elisp的一条致命缺陷呢。
怎么会呢?40多年不是靠前缀好好的吗?
加了模块,emacs插件还会那么强大吗?
如果加模块,那谁来负责分发代码呢?
emacs正因为没有这些负担,所以改完代码直接reload,开发效率才高呀。
因为都是全局的,所以在配置里面修改起来超级方便
模块名就不会重名了么
用前缀区分命名的确有些不便,但不至于要命。
与其担心重名,不如不要引入冲突。
不妨把 package_function
当成 package.function
,想象它是个“弱模块”。前缀和点只不过是表象,心中无码自高清。
Emacs principle No. 12: 不要装用不上的插件。这样问題的前提就不存在了。
实际上 Emacs 自帯的大量插件都不是自动加載的,你不看文档不读代码都不知道它们存在。不知道≈不存在,不存在的包怎么可能会冲突呢?
的确,除非都学 Java 用 reverse domain name。
比如我喜欢定义一些工具函数,什么 plist-map, plist-set 诸如此类,只在我这个包里用,但是由于名字太过通用就会有冲突的风险,我只能再命名成 my-package-plist-map, my-package-plist-set ,导致函数名都巨长无比,写起来麻烦又啰嗦。
涉及到相对底层的函数或者宏你可以加个 “!” 后缀, 像 doom 里面 setq!
, defadvice!
这样。短, 也便于区分。
edit:
不过这仅限于个人配置。写包的话还是要前缀。我遇到这种必须要自己写工具函数的情况不多,一般都会想办法用内置的函数解决。
有个 names 包可以替你加前缀
Emacs 28 之后可以用这个了
比如 plist-map
可以改成 m-plist-map
然后定义
;; Local Variables:
;; read-symbol-shorthands: (("m-" . "my-packages-"))
;; End:
自动变成 my-packages-plist-map, 你写的其他包要引用这个包的时候,也可以弄上 shorthand
似乎能具备namespace的能力,但这是一种魔法实现,对文件内的intern symbol做了特殊的执行处理,牺牲了代码含义的绝对性,理解成本高昂,这种设计真的优雅么,表示深深的怀疑
EmacsLisp 语言的目标不是好理解,也不是优雅,而是让 Emacs 配置更好写,彼此容易配合。
在我看来 elisp 没有模块化反而是一个大优点,因为这才让用户可以用最直接的方式控制自己的配置。
退一万步来说,就算不是优点,没有模块化肯定也不是一个『致命』缺陷。
反证:假如它是一个『致命』缺陷,那么 Emacs / EmacsLisp 应该没有命了,也就是说不存在了,或停止发展了。而现实是它仍旧在发展中,没有死。所以证明没有模块化不是一个『致命』缺陷。
我在编码时感觉体验怪怪的,每个变量名,工具名都长长的一大串,习惯了工业语言的我不太适应
歪个楼,想要raw string支持
那不是有 read-symbol-shorthands
和 names
这种 helper 么,能解决问题你又说不优雅😂
你在说 Java 么
和 Scheme 学的。
现代语言号称的很多好处其实可能也只是个伪命题
Elisp 这个东西都不是正版 module,只能说够用。你应该说和 C / C++ 学的,以前是手动 symbol mangling,现在改了一下 reader 方便一点而已。
Scheme 好歹还有个 R(6/7)RS module 呢