博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
勤劳,还是懒惰?
阅读量:6227 次
发布时间:2019-06-21

本文共 2340 字,大约阅读时间需要 7 分钟。

前一篇《 》讲述了如何用 Emacs Lisp 写一个可以在 Emacs 计算机里运行的 hello world 程序。

我们已经通过一个极为简单的 hello-world 函数,向 Emacs 计算机发出了第一声问候。

这个 hello-world 函数的定义非常简单:

(defun hello-world ()  (interactive)  (insert "hello, world"))

但是一旦弄懂了如何使用 Emacs Lisp 语言定义一个函数,以及 interactiveinsert 的用法,我们就可以在很多时候从一个勤劳的人蜕变为一个懒惰的人。

此前,有一段时间,我经常用 POV-Ray [1] 渲染一些很简单的三维场景:我向 POV-Ray 提供场景文件,由 POV-Ray 使用光线追踪技术基于场景文件中的描述完成三维渲染。每份 POV-Ray 场景描述文件往往是以下面内容作为开始:

#version 3.7;#include "colors.inc"global_settings {  assumed_gamma 1.0}

一开始我比较勤劳,会在每份场景文件中很认真地手动输入上述内容。现在就可以不必如此,在 init.el 中像下面这样定义一个函数:

(defun povray-head ()  (interactive)  (insert   "#version 3.7\n"   "#include \"colors.inc\"\n\n"   "global_settings {\n"   "  assumed_gamma 1.0\n"   "}\n"))

这样,每次当我新建了一份 POV-Ray 场景文件之后,只需要向 Emacs 发送 M-x povray-head <RET> 指令,场景文件中就会自动出现上述内容。

看,并不需要多么高超的编程技术,只是将 hello-world 函数略微改动一下,就节省了许多重复性的劳动。从物理学的角度来看,在我编写许多 POV-Ray 场景描述文件时,这个 povray-head 函数可以让我更省力。

所以,在我看来一个程序首先应该是一种有用的机械,它与杠杆、滑轮、斜面这些基本的省力装置不应该存在本质上的区别。因此,在写一个程序之前,需要明确,这个程序是否可以让你或让其他使用这个程序的人更省力。不省力的程序,是没必要去写的。

最近为了写几篇 Emacs Lisp 编程方面的文章,我不得不在 Emacs 里编程。实际上我也经常需要使用 C 语言在 Emacs 的宿主系统中编程。我经常需要写一些像下面这样的代码:

double *foo = malloc(n * sizeof(double));

若没学过 C 语言,就不必在意这行代码的含义,将它视为普通的文本即可。倘若手写这行代码,我必须写两次 double。现在,我可以再在 init.el 中定义一个 c-malloc 函数,让我在写此类代码时能够省点力。

以下是 c-malloc 的定义:

(defun c-malloc (name type n)  (interactive   (list (read-string "变量名称?")     (read-string "类型?")     (read-string "数量?")))  (insert (format "%s *%s = malloc(%s * sizeof(%s));" type name n type)))

这个函数的定义,与 hello-world 以及 povray-head 不一样,它是带有参数的函数。与后两者相比,它更符合我们在数学中对函数建立的一般性认识,即 w = f(x, y, z) 或 f: (x, y, z) -> w。

暂时不考虑 c-malloc 的细节,先看它是如何工作的。

现在,倘若 Emacs 重新加载了 init.el 文件,那么使用 M-x c-malloc <RET> 指令便可让 Emacs Lisp 解释器对 c-malloc 进行求值,但是 Emacs 在执行上述指令后,会在微缓冲区里问我三个问题。

第一个问题是:

变量名称?

我(在微缓冲区里)输入指令 foo <RET>,就回答了这个问题。紧接着,Emacs 会再问:

类型?

我输入指令 double <RET>,就回答了这个问题。最后,Emacs 会问:

数量?

我回答 n <RET>

注:
<RET> 表示单击回车键。例如
n <RET>,表示输入
n 之后,单击回车键。

回答了这三个问题之后,Emacs 就会在缓冲区里显现:

double *foo = malloc(n * sizeof(double));

实际上,Emacs 接受我的答案之后,会将它们依序分别绑定到 c-malloc 的三个参数 nametypen 上,这就相当于形成了下面的表达式:

(c-malloc "foo" "double" "n")

接下来,Emacs Lisp 解释器对这个表达式进行求值,结果就是在缓冲区里插入

double *foo = malloc(n * sizeof(double));

像这些琐碎但是出现频率比较高的代码片段,花一点时间,用编程的方式来生成它们,不仅省力,而且也避免了手工输入的错误。一个勤劳的人,应该用编程的方式让自己变懒,而不是让自己活成一段程序。

上文中出现的 Emacs Lisp 代码,看不懂没有关系,因为在下一篇就开始讲述 Emacs Lisp 的文本处理方面的编程知识。

下一篇

[1]

转载地址:http://wpxna.baihongyu.com/

你可能感兴趣的文章
ubuntu VNC连接树莓派
查看>>
[nodemon] Internal watch failed: watch ENOSPC错误解决办法
查看>>
全球首发----Tech·Ed 2006中国 实况报道。全程跟踪。(四)
查看>>
向C#的选项卡中添加自定义窗体
查看>>
WPF客户端读取高清图片很卡,缩略图解决方案
查看>>
ubuntu安装和配置SVN【转】
查看>>
通过串口连接控制树莓派
查看>>
线程池系列三:ThreadPoolExecutor讲解
查看>>
wp7 XAML基础
查看>>
机器这次击败人之后,争论一直没平息 | SQuAD风云
查看>>
Oracle中shrink space命令详解
查看>>
验证码 生成变形的文字
查看>>
用cflow工具生成代码函数调用关系【转】
查看>>
ASP.NET MVC5+EF6+EasyUI 后台管理系统(75)-微信公众平台开发-用户管理
查看>>
android用户界面之菜单(Menu)教程实例汇总
查看>>
单链表
查看>>
linux下的僵尸进程处理SIGCHLD信号【转】
查看>>
c#中volatile关键字的作用
查看>>
Hadoop概念学习系列之搭建(windows)Eclipse/MyEclipse远程操作(Linux上)hadoop2.2.0/hadoop2.6.0 出错集(三十五)...
查看>>
淘米水的10大功效
查看>>