程序的基本形状

又名:写给不懂编程的人

一时兴起,用了差不多十天的时间,为「不懂编程」的人写了一系列的形散神不散的散文。这是我在这一年里做的我觉得最有意义的一件事,当然在我身边的人看来,这可能是我在这一年里做的最不务正业的事了。

「不懂编程」的人是加了引号的。这个人不是会编程的人,也不是不会编程的人,实际上这个人是我。也就是说,这一系列文章,不过是自嗨。拿出来示人,是自己觉得挺不错的东西,以为别人也会觉得挺不错。很可能这种感觉是错误的。

这些文章将 Emacs 作为一台可编程的机器,以 Emacs Lisp 作为编程语言。

对于 Lisp 语言,在写这些文章之前我只是略懂。现在我所掌握的 Emacs Lisp 的知识基本上都在在这个系列的文章里。这些知识基本上是我在写这些文章的过程中现学现卖,只不过是以我最喜欢的方式来卖的,其中还夹杂了一点奇怪的东西——我对这个世界的浅见薄识。

在这十二篇文章里,我很不学术也很不严肃地介绍了计算机原理、Emacs 的基本用法,以及 Emacs Lisp 的函数、变量、递归、Y 组合子、动态域/词法域、宏等知识,还讲述了 Emacs Lisp 版本的快速排序与列表的递归遍历程序的编写。我将这些知识称为程序的基本形状。

这些文章的目录如下:

  1. Emacs 是一台计算机:论证了 Emacs 本质上是一个可编程的机器——图灵机。
  2. 第一声问候:介绍了如何在 Emacs 里编写一个世界上被写过得最多的程序——hello world。
  3. 勤劳,还是懒惰?:神神叨叨的作者现身说法,强调了编程的意义——让我们更省力。
  4. 原子与虚空:介绍了构成程序的基本构成以及程序和 CPU 的关系。
  5. 周而复始:对于递归,我可能和很多人的认识不同,在我眼里,它是个发动机。程序也不是由表达式或命令构成的东西,而是一部由 CPU 驱动的机器。
  6. 红药丸,还是蓝药丸:一本正经的对条件表达式进行了一番胡说八道。
  7. 周游抑或毁灭世界:这一篇,算是与 Emacs 最亲密的一篇。其实,我原本想用很多篇幅介绍可以扩展 Emacs 功能的 Emacs Lisp 编程方面的知识,只不过写着写着就下了道。
  8. 无名:Y 组合子的推演。
  9. 长长的望远镜:介绍了 Emacs Lisp 的动态域/词法域,是对第 8 篇的补充。
  10. 从混乱到有序:煞有介事的介绍了如何用 Emacs Lisp 实现一个快速排序程序,穿插着介绍了向量与列表相关的一些功能。
  11. 咒语:介绍了 Emacs Lisp 的强大的宏的用法。Lisp 的宏一直都很强大,像失传很久而被现代人认为失灵的咒语。
  12. 无所遁形:介绍了如何让程序深入探索重重叠叠的列表的任何一个角落,算是对递归函数的认知再作一次强化。

更新说明:

2017.12.06:利用 let 表达式对第 12 篇的 list-map 函数进行了简化。

2017.12.07:为第 6 篇补充了一个例子,它是对第 3 篇定义的 c-malloc 函数所做的改进。

2017.12.07:为第 10 篇补充了一种守株待兔式的理解递归的方法。

2017.12.08:重新梳理了一遍对第 8 篇,克服了一些文字不通顺而导致难以理解的问题。

虽然这些文章讲的是如何用 Emacs Lisp 语言在 Emacs 环境中编程,但是一个事,你用英语来讲,还是用汉语来讲,事没有变,只是外在的形式变了。因此这些文章里所说的这些事,可能还都是大家经常遇见的。退一步说,学点 Lisp 也不算坏事。

前面已经说了,这些文章仅仅介绍了程序的基本形状,就像欧氏几何学里的三角形、四边形之类的东西。要想编写更复杂而且也更有用的程序,应该去看那些介绍了程序更复杂的形状的书。

接下来,对于编程的初学者,我建议的是,在参与编程这项工作的过程中,不妨再啃几本下面这样的书:

  1. 倘若对 Lisp 发生了兴趣,就去看《计算机程序的构造与解释》,最好中文译本与英文原版都找到,对照着看。
  2. Hello world 程序的始作俑者,Brain Kernighan 写的《C 程序设计语言》,最好中文译本与英文原版都找到,对照着看。之所以要看看 C 语言,是因为它面对的机器要比 Emacs 硬,啃起来,不小心就崩了牙。
  3. 《如何求解问题:现代启发式方法》,这本书会介绍一些有用的算法,在解决实际问题中有用,而不是在考试或比赛中有用。不过,这本书是差不多是被翻译毁掉了的书,最好找到英文原本来看,而将中文译本当作谷歌翻译结果来看。

倘若只是对 Emacs 有了兴趣,那就去看 Emacs 与 Emacs Lisp 的官方文档。

相关推荐