前言
Emacs Lisp是一种神秘莫测的黑客编程语言. 它的弱点是众所周知的, 它很慢, 它是单线程的, 同时它的变量是动态绑定的, 等等等等. 我当然还能继续说下去, 但这些不是主要目的. 尽管有这些看得见的弱点, 但Emacs Lisp仍然是github上最流行的lisp方言, 这一点有许多程序员对此发誓. 至于我, 能平均每天写50到100行之间的Emacs Lisp代码.
当然, 我决定投资我的时间去学习它, 并且发现这样做了以后更加高兴. 我真的希望以后也能如此. 我所遇到的主要问题是劝阻我不要将时间投资到编程语言上. 但是现在, 我真的希望在多年前就能花时间去学习它.
尽管遇到这样的问题, 又是什么使它如此的棒呢? 为什么任何人都应当学习Emacs Lisp呢?
所以, 事不宜迟, 下面我就给出当今应当学习Emacs Lisp的5点理由:
不管学习多少Emacs Lisp都会立即使你的生活变得更美好
你学习到的东西能够立即改变你的生活, 不是从现在起一年, 不是毕业以后, 也不是当你的团队开始下一个项目时你才会使用到这门语言, 而是 现在!
许多Lisp方言位于理论的范围内, 这很好, 也有它们的位置. 但是Emacs Lisp显得”更快更脏”. Emacs Lisp是非常有实践性的, 它能帮助你解决你每天所遇到的问题.
如果你不懂任何Emacs Lisp, 那么你的.emacs文件有可能充满了为了安装所需的包而复制粘贴的各种代码, 这很正常. 但问题是这会迅速的变得难看. 不久之后你的.emacs文件就会变得非常难以维护. 学习Emacs Lisp会使你的Emacs生活更有秩序.
如果你需要获得关于Emacs的任何帮助, 很有可能帮助你的那个人将会带来一些Lisp代码. 你很难对他说”对不起, 我不懂任何elisp!” 在##emacs站点, 会一点Emacs Lisp能使你更好的融入社区.
今天, 学习Emacs Lisp, 会使你的生活更美好.
Emacs Lisp和Emacs是一个真正有趣的编程平台
你并不一定非要是一个狂热的Emacs党. 但我想任何人都会同意Emacs是有趣的.
Chances are that you have some exposure to the ideas behind Smalltalk, such as, you know, that whole “objected oriented” thing.(不知道怎么翻)另外, Samlltalk不仅仅是一种编程语言, 同时也是一种编程环境. 在Emacs上也拥有这种同样强大的精神. 因为对用户来讲一切东西都是立即可见的. Emacs是类似有这种精神的系统的一种主要继承者.
想要知道一个键绑定是做什么的吗? 按”C-h k”. 想要知道函数是做什么的吗? 按”C-h f”. 想要看函数的源代码, 单击刚才出现的buffer上的链接即可. 或者你想要在你需要的时候修改它, 仅仅改变函数定义出的代码同时按”C-x C-e”使之生效
当用Emacs Lisp编程时, 你会觉得在这个系统上完成工作就像当今社会与石器时代相比. 另外还有红利: 这不仅仅是一些智力上的练习, 同时也是实践性的, 精彩的, 同时还能立即可用.
动态绑定确实很棒
让我们快速回顾一下动态绑定, 同时对比另一方面, 词法绑定(lexical binding).
首先, 让我们看看变量绑定, 特别的, 用Javascript伪代码来表示, 如下:
function createAdder(num_to_add) { function(new_num) { return num_to_add + new_num; } } add2 = createAdder(2); add10 = createAdder(10); console.log(add2(6)); // = 8 console.log(add10(13)); // = 23
我们来看看这段代码. createAdder函数用来返回另一个函数, 它是用来”创建”和”增加”的. createAdder将返回一个参数和一个新函数的和.
重要的一点是, 无论createAdder什么时候返回, 它都仍然返回传给它的参数–num-to-add. Whatever variables are within a parent’s scope when a function gets created remain available to it for its execution(不知道怎么翻).
词法作用域非常棒, 它能真正优雅地解决问题, 正式这点使Ajax和Node.js更加合理.
动态作用域是不同的, 在动态作用域中, 变量在求值时绑定和计算. 计算变量在任意调用栈之上.
用伪代码举个例子, 动态绑定的Javascript如下所示:
function adder(new_num) { return num_to_add + new_num; } function add2(new_num) {l num_to_add = 2; return adder(new_num) } function add10(new_num) { num_to_add = 10; return adder(new_num) } console.log(add2(6)); // = 8 console.log(add10(13)); // = 23
关键的不同点是adder函数, 变量 num-to-add 似乎不涉及任何东西. 然而当语言是动态绑定的, 变量会在它被调用的地方引用. 因此add2函数设置的变量num-to-add, 当adder函数被调用时, 它才有可能被引用.
你可能会想这听起来就好像是全局变量, 没错, 的确如此. 这就是为什么当今绝大部分语言都是词法绑定的, 而不是动态绑定的.
实践中, 这这的不容易变糟. 你所想的变量改变是有据可查的. 当需要时代码仅仅使用动态范围解析, 当然这不需要经常进行.
动态绑定事实上相当方便. 举个例子, 它可以使你的变量基于配置改变.
另外还有一种宏, 叫做lexical-let, 能使你得到词法绑定的功能.
如果这还不够, Emacs24现在支持词法作用域. 你只需要用elip文件设置一个变量告诉你想要的词法作用域.
所以, 动态绑定确实很酷.
单线程是件好事
Emacs Lisp是单线程的, 很可能永远都会是. 这可能会有点限制, 但却带来了相当大的简化.
老实说, 如果你真的想处理锁和它们的同胞, 你不得不去其他地方看看.
当你理解Emacs Lisp后关于Emacs的一切都会更有意义
你可能已经注意到Emacs有相当纯净的文档, 而它的文档又相当广泛. 然而, 绝大部分文档仅仅在有Lisp代码的上下文中才有意义. 因此如果你不懂Emacs Lisp, 那么许多文档都是没用的.
举个例子, 为了明白Emacs键绑定系统, 你需要了解键绑定的组成结构, 而这就意味着Lisp.
老实说, 在Emacs中到处都是Emacs Lisp, 不了解Lisp也能用Emacs, 但当你理解了它的原生语言–Emacs Lisp后, 将会更好的使用Emacs.
因此你应当学点Emacs Lisp. 它是一个相当迷人的编程环境, 而且很有可能使你的生活变得更容易. 另外, 对我来说, Emacs Lisp的问题是没有足够明显的dissuading. 事实上, 应该考虑加强它们.
总之, 用Emacs Lisp工作使人兴奋, 我强类推荐给那些认为自己是一个严肃的程序员的人们.