elisp-shorthands emacs28 新功能

https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=58055b5fc330689234cafb51398844f6e5791077

3 个赞
+** Shorthands
+Shorthands are a general purpose namespacing system to make Emacs
+Lisp's symbol-naming etiquette easier to manage.  Also known as a
+"renamed symbol", a shorthand is any symbolic form found in Lisp
+source that abbreviates a symbol with a different and longer print
+name.  Among other applications, it facilitates the importation of
+popular libraries such as 's.el' without the polution associated of
+very short prefixes.  For details, see the manual section "(elisp)
+Shorthands".
+
++++
1 个赞

就是下面这个包,目前只有 1 颗 ★,怎么突然就进了 Emacs ?

;; Local Variables:
;; shorthand-shorthands: (("^s-" . "magnar-string-"))
;; End:

进emacs只要签了FSF协议,有管理权限的可以直接push

你得看作者,眼熟不,joaotavora

最大的可能是:RMS 认可这种方式实现 namespace,我前一段时间看到 RMS 发邮件,建议合并这个feature的

:joy: :joy: :joy: :joy: :joy: :joy:

故事应该是从应该是从包含 s.el 的时候

https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg00016.html

发现用 sting-- s-- 前置的老方法有点呆,没有 namespace 真的不行,joaotavora 又开了另一个讨论

https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg00515.html

那个 elisp-shorthand 的仓库也刚好拿那个 s.el 来做实验,

2 个赞

这个东西就是改一下reader, 把读入的symbol alias一下. 没有做真正的module(比如require之后还是所有的公有的似有的package全部都放进全局的obarray里了).

以前Andrea(native comp作者)提议做binding based的module, 这种原理是module里面存放的是几个symbol到变量或者函数的映射表(分别用来做public 和 private), 导入的时候可以rename import或者prefix import(e.g. substring -> str:substring).

但是这样做其实不怎么方便, 因为 Emacs 经常用 symbol property 来搞其他东西(比如defface用symbol property来做额外的namespace), 导致这个竞争力不如symbol based的module. symbol based的module就是直接在module里装一个存放symbol的obarray, 实际的binding都在symbol里. 不过我觉得这种很容易给没用过lisp的人造成混乱.

用 Common Lisp举个例子

CL-USER> (defpackage :symbol-transparency (:use :cl))
#<PACKAGE "SYMBOL-TRANSPARENCY">
CL-USER> (in-package :symbol-transparency)
#<PACKAGE "SYMBOL-TRANSPARENCY">
SYMBOL-TRANSPARENCY> (defmacro aif (cond then &optional else)
                       `(let ((it ,cond))
                          (if it ,then ,else)))
AIF
SYMBOL-TRANSPARENCY> (export 'aif)
T
SYMBOL-TRANSPARENCY> (in-package :cl-user)
#<PACKAGE "COMMON-LISP-USER">
CL-USER> (symbol-transparency:aif (+ 1 1) (format t "It's ~a" it))
; in: SYMBOL-TRANSPARENCY:AIF (+ 1 1)
;     (FORMAT T "It's ~a" IT)
; 
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::IT
; 
; compilation unit finished
;   Undefined variable:
;     IT
;   caught 1 WARNING condition
; Debugger entered on #<UNBOUND-VARIABLE IT {1007D8BF93}>
[1] CL-USER> 
; Evaluation aborted on #<UNBOUND-VARIABLE IT {1007D8BF93}>
CL-USER> 

奇怪, 我们定义的 aif 宏明明可以用 it 来代指 if 语句里的条件表达式, 为什么又提示变量未绑定呢?

这是因为aif 里的 symbol it 是在 symbol-transparency 里的it, 而我们这里是 cl-user 里面的 it, 两个 it 不相同.

;; :: 是获取私有符号的特殊 reader syntax
CL-USER> (eq 'symbol-transparency::it 'it)
NIL

这个东西乍一看好像没什么, 但容易造成混乱. 比如面向对象编程, 导出一个class时允许用户继承后覆盖某个member, 必须要把那个member的symbol也一起导出. 而一个 symbol 因为有 symbol-plist的存在, 导入不明package的symbol时, 又担心把奇怪的东西一起导入了…

2 个赞

是啊,所以叫 shorthand,

没有 namespace 真的很不方便,但这个 shorthand 看起来也不像是正经的解方。

如果能出个 elisp 2.0 就好了。

1 个赞

这个嘛。。。。我感觉可以当做一个念想了