松本行弘(Ruby发明者):Emacs怎样改变了我的人生

  |   Source

原文(英文版本)见这里.

以下是我的翻译兼一些技术方面的背景资料:

1980年,我开始编程.

Basic,400 steps (此句不知如何翻译)

1988年,我遇到了Emacs,在学校的Sun-3上,和200多个学生共用.

Emacs实际上是被禁止使用的,因为消耗太多内存.所以我只是尝试了一下了.

我可以自由下载Emacs并阅读其源代码.

Emacs是我的第一个Lisp解释器.

从Emacs我学到了很多关于语言实现的知识.

例如,emacs的整数实现(Embedding integer in pointers)

参考LispObject定义,在Emacs源代码的lisp.h中,LispObject是一个既可以作为指针使用又可以作为整数使用的类型 具体代码见下,注意LispInt为0,使得非负整数可以直接转换为对应的ListObject类型:

#define VALBITS 29
#define GCTYPEBITS 3

enum Lisp_Type { Lisp_Int = 0,

<span style="color: #969896; font-style: italic;">/* </span><span style="color: #969896; font-style: italic;">Symbol.  XSYMBOL (object) points to a struct Lisp_Symbol.  </span><span style="color: #969896; font-style: italic;">*/</span>
<span style="color: #e7c547;">Lisp_Symbol</span> = 2,

<span style="color: #969896; font-style: italic;">/* </span><span style="color: #969896; font-style: italic;">Miscellaneous.  XMISC (object) points to a union Lisp_Misc,</span>

whose first member indicates the subtype. */ Lisp_Misc = 3,

<span style="color: #969896; font-style: italic;">/* </span><span style="color: #969896; font-style: italic;">String.  XSTRING (object) points to a struct Lisp_String.</span>

The length of the string, and its contents, are stored therein. */ Lisp_String = LISP_STRING_TAG,

<span style="color: #969896; font-style: italic;">/* </span><span style="color: #969896; font-style: italic;">Vector of Lisp objects, or something resembling it.</span>

XVECTOR (object) points to a struct Lisp_Vector, which contains

the size and contents. The size field also contains the type

information, if it's not a real vector object. */ Lisp_Vectorlike = 5,

<span style="color: #969896; font-style: italic;">/* </span><span style="color: #969896; font-style: italic;">Cons.  XCONS (object) points to a struct Lisp_Cons.  </span><span style="color: #969896; font-style: italic;">*/</span>
<span style="color: #e7c547;">Lisp_Cons</span> = 6,

<span style="color: #e7c547;">Lisp_Float</span> = 7,

};

typedef union Lisp_Object { / Used for comparing two Lisp_Objects; also, positive integers can be accessed fast this way. / EMACS_UINT i;

<span style="color: #b9ca4a;">struct</span>
  {
<span style="color: #e78c45;">EMACS_INT</span> <span style="color: #e7c547;">val</span>  : VALBITS;
<span style="color: #b9ca4a;">enum</span> <span style="color: #e78c45;">Lisp_Type</span> <span style="color: #e7c547;">type</span> : GCTYPEBITS;
  } <span style="color: #e7c547;">s</span>;
<span style="color: #b9ca4a;">struct</span>
  {
<span style="color: #e78c45;">EMACS_UINT</span> <span style="color: #e7c547;">val</span> : VALBITS;
<span style="color: #b9ca4a;">enum</span> <span style="color: #e78c45;">Lisp_Type</span> <span style="color: #e7c547;">type</span> : GCTYPEBITS;
  } <span style="color: #e7c547;">u</span>;

} Lisp_OLisp_Stringbject;

又例如Emacs的内存自动回收机制(Mark and sweep garbage collection)

具体细节参考这里的讨论.

C和Lisp的Calling conventions(不好翻,基本上就是函数如何调用,函数参数的内存模型之类…)

我完全理解Lisp怎么工作的

我被Lisp Objects迷住了

当我得到Sparc工作站时我开始使用Emacs

我完全被迷住了,Emacs成为我的一部分

而且Emacs任何我不喜欢的部分我都可以改,Emacs完全可配置.

Emacs使我明白了任何东西都可以被程序员改变

完全的自由

编辑时可以无视键位设置

我想用Emacs做所有的事,编程,文档,邮件…

所以我写了"cmail",我的第一个严肃的Lisp程序,我每天用它

1993年,我开始搞我的Ruby

Ruby的设计受到Emacs实现的影响,例如整数和tagged pointer合用,相似的GC,和Lisp类似的Object Model

tagged pointer的细节请参考上文的C代码,高地址的3bit用作判别数据类型,低地址的29bit用作指针或者整数(取决于数据类型)

接下来我把Smalltalk的OO系统加上去

语法我用Algol/Ada/Eiffel

但是我是Emacs狂,所以在Emacs中支持auto-indent是必须的

在1993年,类似的语法要支持auto-indent很难

所以我就写了自己的ruby-mode.el,试图用elisp和正则表达式(regex)解决这个问题.

一个礼拜后,我在给Ruby加上end关键字后终于成功了

如果我不能让我的emacs下的ruby-mode成功,那么Ruby的语法会更像C

这样就和其他脚本语言差不多,Ruby也不会那么受欢迎

小结

  • Emacs教我什么是软件自由(freedom for software)
  • Emacs教我如何读代码
  • Emacs让我认识到Lisp的威力
  • Emacs教我如何实现语言核心
  • Emacs教我如何进行内存自动回收(Garbage Collector)
  • Emacs有助于我写代码和调试
  • 我用Emacs写j文档邮件
  • Emacs让我成为高效程序员
  • Emacs让我成为黑客
  • Emacs永远改变了我的人生
Comments powered by Disqus