Emacs Lisp
Emacs Lisp 为 Emacs 带来强大的扩展和功能自我进化的能力。
Emacs Lisp 是一种 Emacs 内置的图灵完备的编程语言,Lisp 是 List Processor 的缩写,即链表处理。
Emacs Lisp 哲学:操作和数据统一是在一个链表中,在运行时可修改。
LeetCode 中有一些中等难度的题,是实现一个 Lisp 表达式的四则运算处理器,常规解法是实现一个状态机,简洁解法是用递归。值得一提的是,Lisp 本身的求解过程就是递归。
解释运行
你也可以把 Emacs Lisp 当成一种独立的编程语言来学习,Emacs 除开核心的大部分功能是由 Emacs Lisp 实现,所以你的代码和其本身没有区别。
Emacs Lisp 是一种解释型编程语言,运行它的命令是:
emacs -Q --script hello-world.el
看起来和执行 Python 脚本没什么不同。
python hello.py
基本元素
- 函数:
(func-name argument1 argument2 ...)
,类似 C 或 Pascal 的func_name (argument1, argument2, ...)
- 变量:没有类型,可以取任何值;
- ATOM:
- 整数:
-2^27
~2^27-1
- 浮点数:
123.456e3
- 字符:必须带有一个前导问号,例如
?a
;ESC、LINEFED/NEWLINE、TAB 分别是\e
,\n
,\t
- 字符串:
"abc"
,引号中的引号需要转意"abc\"efg\"hij"
- 布尔值:
t
表示真,nil
表示假; - 符号:即各种名字,类似指针,是在名字前加一个单引号
'
。
- 整数:
括号的位置
LISP 和 C/Pascal 其实很是类似的,Emacs Lisp 的运行速度其实非常快,用户可以通过 eval-last-sexp 实践。
C 语言中的表达式 1 + 2
,在 Lisp 中是 (+ 1 2)
。
操作步骤:
- 按 C-x b,输入
*scratch*
; - 输入
(+ 1 2)
,确保光标在此 S 表达式最后; - 按 C-x C-e,则在下方会显示
3 (#o3, #x3, ?\C-c)
表示求值的结果等于 3。
赋值
setq 是一个函数,可以一次对一个或多个变量赋值。
Setq 例子
(setq a a-value
b b-value
c c-value)
函数
(defun count-words-buffer ()
(let ((count 0))
(goto-char (point-min))
(while (< (piont) (point-max))
(forward-word 1)
(setq count (1+ count)))
(message "buffer contains %d words." count)))
语句
let
(let ((var1 value1) (var2 value2) ...)
statement-block)
(let (var1 var2 var3 ...)
statement-block)
(let (var1 (var2 value2) var3 ...)
statement-block)
if 语句
(if condition
true-case
false-block)
cond 语句
(cond
(condition1
statement-block)
(condition2
statement-block)
...)
while 语句
(while condition
statement-block)
message 例子
;; 显示为 "hi there" is a string, 142 is a number, and q is a character
(message "\"%s\" is a string, %d is a number, and %c is a character"
"hi there" 142 ?q)
// 显示为 "hi there" is a string, 142 is a number, and q is a character
printf("\"%s\" is a string, %d is a number, and %c is a character\n",
"hi there", 142, 'q')
save-excursion
(save-excursion
statement-block)
(defun count-words-buffer ()
(save-excursion
(let ((count 0))
(goto-char (point-min))
(while (< (piont) (point-max))
(forward-word 1)
(setq count (1+ count)))
(message "buffer contains %d words." count))))
运算符
算术运算符
+
-
*
/
%
1+
1-
max
min
比较运算符
>
<
>=
<=
/=
=
equal
(用于字符串和其他复杂对象)
逻辑运算符
-
and
or
not
语句块
progn
(progn
statement-block)
列表
列表
(list 2 3 4 5)
(length list)
(cons 1 (list 2 3 4 5)
(append list1 list2)
(pop list)
(nbutlast list n)
(setcar list x)
(setcdr list x)
(setq calc-stack (cons x calc-stack))
(car calc-stack)
(setq calc-stack (cdr calc-stack))
Lisp 语言要素
(list 2 3 4 5)
; 第一个元素
(car list)
; 第二个到最后一个
(cdr list)
; 第 n 个元素
(nth n list)
; 最后一个元素
(car (last list))
; 第 n 个到最后一个
(nthcdr n list)
; 不包含 n 到最后一个
(butlast list n)