如题 分享一个elisp的入门文档,希望能帮到刚刚入门学习elisp的同学。
论坛搜索这个链接,有六个搜索结果(包括你的),应该有不少人已经知道了。
大概是 2007 年写的,这十多年里 Emacs 加了
- Lexical Binding
- Generalized Variables
- Pattern Matching
这些很常用,也很有用的新特性,值得介绍。此外, 正则表达式部分,rx
也值得一提。
谢谢! 我去找一下呢
lexical binding:
GV其实没有那么常用,我只看了onlisp上的相关内容
Pattern Matching我看的是pcase的manual
传说中的rx,看这个,还有rx自己的docstring就够了
「常用」与否没法定量判断,所以…… 此外,Generalized Variables 的使用不仅包括 setf
,像 push
、cl-incf
等也有机会用到。
印象中官方的介绍太简陋了,当时我看了还是有很多不清楚,后来我装了 Emacs 27,看了新版的介绍感觉好多了。
好吧,原来cl-incf
和push
也能用GV… 我完全没有用过就是了
他们用的setf,setf用gv实现的
问个入门问题
(setq foo (lambda (name)
(message "Hello, %s!" name)))
(foo "Tom") ; => 不正确 在scheme这种写法是可行的。
(funcall foo "Tom") ; => 正确
lisp把变量和函数空间进行了区分。这体现了scheme与lisp之间的区别吗?
若是区分的,下面这种写法又如何理解呢?
((lambda (name)
(message "Hello, %s!" name)) "Tom")
lambda表达式的返回值可以直接调用,而把这个返回值赋值给一个变量就不可以直接调用这个变量。那么lambda的返回值,是一个函数空间的对象,却可以付给一个变量空间的对象?
因为这是唯一的特例。编译器/解释器对 lambda
会特殊处理。
谢谢!
也就是说, 在lisp中,函数空间和变量空间,除了lambda这个特例外,是严格区分的呗。
我觉得emacs自带的emacs lisp intro也很不错, 从简单的源码开始一步步了解elisp.
谢谢你的推荐 我去看下呢
Emacs不建议用这种形式直接调用lambda。所以其实统一用funcall最好
(byte-compile '((lambda (x) (1+ x)) 4))
;; Warning: Use of deprecated ((lambda (x) ...) ...) form
好的,scheme和lisp我接触的都不是很深,针对elisp目前有些疑问点。
-
scheme有一个RSR5, RSR6的标准,lisp有common lisp,那elisp呢?它虽然是独立发展,应该也有个规范吧。
-
我是从学习perl时知道名字空间隔离的,如变量名和函数名不共享在一个名字空间下,从你推荐的博文里看到这是LISP-1和LISP-2的区别。正好也解答了,我以前在本帖上提的问题。LISP-2的这种设计方式,除了能解决变量名和函数名冲突的问题之外,还有什么优势吗? 我自己倒是挺喜欢scheme和js的那种方式。变量有可执行属性的话,可以直接调用,而不是借助与funcal/apply
没有,硬要说就是自带的 Info 文档,同理 Python, Ruby, Lua, 都只有事实标准。
(defun hello () (print "hello, master"))
(funcall (read))
> 'hello
hello, master
In Scheme it requires using eval
to achieve it, though funcall
can be ten to hundred times faster than eval
。
原来如此,对于函数的调用,funcall在速度上有优势。我再问个问题,从管道或文件得到一个S表达式,想让它执行,不管是lisp还是scheme,都是用eval吧?在这方面,lisp没有自己独有的方法吧?
現在多数 Lisp 都是先 compile 再执行。
好的,谢谢!
另外歪个楼,国内现在是不是都在忙着准备过年呢?感觉这两天,发的帖子少了一些。
(setq foo '(("a" . 97) ("b" . 98))) ; => (("a" . 97) ("b" . 98))
;; update value by setcdr
(if (setq bar (assoc "a" foo))
(setcdr bar "this is a")
(setq foo (cons '("a" . "this is a") foo))) ; => "this is a"
foo ; => (("a" . "this is a") ("b" . 98))
能否帮忙解释下这段代码,为什么(cons '(“a” . “this is a”) foo) 的结果只有一个(“a” . “this is a”)存入foo中? 这段代码在第五章的“把列表当关联表”这一节中。