编程语言教程书该怎么写: 向K&R学习!

原文地址:Lax Language Tutorials
Andrew Binstock

每年在评审Jolt Awards图书的时候,我都会被一些语言教程类图书弄得心力交瘁。从这些年的评审经验来看,这些语言类教程的写得都不错,但除此之外,少有亮点。换句话来说,这些书都很严谨、很精密,如果读者有足够的定力,通过它们掌握一门语言的编程技术还是不成问题的。可是,即便对那些卖得最好的书,除此之外我都想不出来还能多说几句什么样的赞美的话了。

这些书普遍存在的一个缺点就是把简单的任务复杂化。最大的或者说最常见的一个问题,是作者们混淆了教程与一本面面俱到地介绍一门语言的专著的区别。由于种种原因,出版行业似乎特别热衷于后一种体裁,结果就导致了一些令人瞠目的大部头。我曾经看到过一本“介绍”Java语言的书,厚达1480页。如果说入门读物都得这么厚,显然是不合理的。不消说,这本书深入地讨论了一下AWT和Swing,然后笔锋一转,又给读者罗列出各种各样的第三方库,关于虚拟机的研究当然少不了,而最终则收尾于并行程序设计。谢天谢地,到这里终于全书完。鉴于这本书已经出到了眼前的第4版,有理由认为它体现了作者对它最终的心理预期。那就是,这实际上是教程兼参考书。而且,既然书的重量都达到了4.5磅(约2.04千克),我想多半也只能把它当作参考书来用了。Mark Lutz的《Learning Python》是Python语言图书中与此类似的一本。其他语言类图书中,像把Ruby介绍给西方读者的“鹤嘴锄书”(《Programming Ruby: The Pragmatic Programmers’ Guide》),作为此类图书也是当之无愧。书的前一半是教程,后一半明说就是参考。这种方法就好多了。不用管其中的Ruby教程占了多少篇幅(418页),仅就其质量而言,就充分说明它大受欢迎是有理由的。

第二个常见的问题,就是作者忘了读者在打算学一门新语言的时候,最想做的是什么;当然,无非就是要写几个小程序,借以熟悉语法。然而,很多教程通篇都是只有一两行的微型代码示例,只够演示某个功能,但没有一个独立有用的程序。如果语言还有一个内置的shell(或解释器),比如像Ruby、Groovy、Scala,那这个倾向就越发地明显了。

比如说,Odersky、Spoon和Venners合著的Scala教程(《Programming in Scala》)就能清楚地反映出这个问题。在这本书的前200页里面,超过20行代码的示例只有一个;大部分都不会超过10行。[而在K&R(Brian W. Kernighan和Dennis M. Ritchie)那本书(稍后会说到)里,第一个20行代码的示例出现在第26页。]结果呢,按照我自己的经验,就是看了半天书,也敲了不少代码,由此了解了不少功能,但却始终没有写出一个有点什么用的程序来。实话实说,这种现象简直太普遍了。现在,我眼前就摆着两本书,一本Clojure,一本Groovy,也都是这个套路。

最后一个问题在编辑不给力的书中经常会发现:一心只想展示一门语言的聪明技巧或者能做到的一些小hack。个人认为,读者是想来学语言的,不是来欣赏语言特技的。这个问题最常见于那些函数式语言,或者像Groovy一样有意设计得比竞争性语言(对Groovy来说就是Java)更好的语言的教程。

以上三个问题之所以让人感到难以理解,关键在于长期以来一直都有一本绝好的榜样:Kernighan和Ritchie的《C Programming Language》(K&R)。拿这本书跟其他教程比一比,差异立现。先从最明显的地方开始,K&R的教程部分只有177页,随后是40页的附录,附录是极其简明的参考。在这种篇幅适中的情况下,任何读者都能轻松看完,并且做完全部示例。其次,大多数程序都在20行代码以上,既有相应的用途,也不让人感到陌生,而且相对完整。即便是到了这本书的第125页左右,示例程序中都包含main()函数。这里说的可不是代码片段,而是虽短但却真实的程序。最后,书中对所有程序的解释分析十分透彻,而且前后相继,由浅入深。没有对功能漫无边际的简单罗列,所有示例都有一种内在的线索,让读者在任何时候都知道自己掌握了哪些基础知识,还需要探索哪些基础知识。

那在K&R中看不到什么呢?最明显的是,书中没有解释标准库中每个函数功能的部分。Java图书也应该把这个部分删掉。(对Java知识体系介绍得最为全面的两本书,就是Horstmann和Comell合著的《Core Java》卷I和卷II。但在两卷合起来1800页的篇幅中,没有包含教程,也没有像书中所说的那样讲述。)

K&R也没有填鸭式的说教。看这本书必须边看边思考。所有信息都摆在那儿,但你必须动手去做每一个例子,才能理解这门语言。作者希望看这本书的读者很用心很专注,因此会在你迅速学会这门语言的过程中,随时为你提供帮助,但不会强迫你一页接一页地阅读那些对理解语言没用的东西。

恐怕有人会说,C只不过是一门小型语言,所以介绍它自然用不着大部头。要是你也这么认为,请睁开眼来看看别的C语言教程,看有哪一本书像K&R这么薄,而且写得又那么好。要不然,再看看JavaScript,JavaScript也是一门小型语言,但还没有哪本书是篇幅又短,又容易理解的。

我想说明一下,前面提到的那几本书都是着意挑选出来的,因为这几本书在我看来都是相应语言领域的最佳教程。Odersky等写的Scala、Thomas写的Ruby,还有Lutz那本Python,这些都是学习相应语言的最佳起点。我只是希望这些书要是能更像K&R那样就好了。

——Andrew Binstock
《Dr. Dobb’s》主编

时间: 2024-10-10 23:12:56

编程语言教程书该怎么写: 向K&R学习!的相关文章

K&R 学习笔记 第一章

今天开始学习C语言,为了之后的游戏开发学习做好基础,其实在大一的时候学校有C语言的课程,学的马马虎虎,教学也比较浅显,感觉并不能学习到C语言的精髓.在经过多人推荐下,入手了K&R ,看了第一章之后,才发现的确值得这么多人称赞. 其实大多数书的第一章都是差不多的,以Hello World 引出本书学习的知识体系的顺序,有趣的是之后的练习,也是要花一番功夫的. 1.4 提到了幻数,所谓幻数,就是在程序中直接使用的数字.C语言的传统方式是使用#define行来对付幻数.C语言预处理程序是一个强有力的工

Makefile学习教程 跟我一起写 Makefile

https://github.com/zhangliyong/myknowledge/blob/master/Makefile%E5%AD%A6%E4%B9%A0%E6%95%99%E7%A8%8B%20%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99%20Makefile.wiki ++ Makefile学习教程 跟我一起写 Makefile 0 Makefile概述 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Wi

《Swift编程语言教程》中文翻译及读书笔记page21

<The Swift Programming Language>中文翻译及读书笔记,附件中为英文原版教程 因21页之前内容和技术关系不大,不做翻译整理,从第21页开始 第21页 1 swift作为一门语言对的新老语言的继承与扩展 本页主要内容是简要介绍了一下swift编程语言的定位.拥有自己的数据类型int.float.string等数据类型外,swift还具有array.dict等数据类型. 2 引入了tuple元组数据类型 特别说明的是在swift语言里引入了oc和c没有的tuple元组数

零基础学Python,这是阿里Python8年开发经验写给你的学习路线图

今天给大家分享一位前辈整理的一个Python web学习路线.这位前辈由于有编程基础,所以采用了自学Python的方式.学完后主要做后端开发.希望对你有所启发. 整理的一个 python web 学习路线,这基本就是笔者自学后做后端的学习路线.创一个小群,供大家学习交流聊天如果有对学python方面有什么疑惑问题的,或者有什么想说的想聊的大家可以一起交流学习一起进步呀.也希望大家对学python能够持之以恒python爱好群,如果你想要学好python最好加入一个组织,这样大家学习的话就比较方便

【Zigbee技术入门教程-01】Zigbee无线组网技术入门的学习路线

[Zigbee技术入门教程-01]Zigbee无线组网技术入门的学习路线 广东职业技术学院  欧浩源 一.引言    在物联网技术应用的知识体系中,Zigbee无线组网技术是非常重要的一环,也是大家感觉比较难以掌握的一个部分.Zigbee无线组网技术之所以让你感有学习难度,不是因为它真的复杂,而是它看起来很复杂,让人望而止步.另一方面则是Zigbee技术在应用层面上将硬件和软件完成融为一个体系,要求开发人员既要有扎实的硬件技术,又要有清晰的软件思维.    目前,尽管有不少关于Zigbee无线组

从软件工程的角度写机器学习6——深度学习之卷积神经网络(CNN)实现

卷积神经网络(CNN)实现 背景 卷积神经网络广泛用于图像检测,它的实现原理与传统神经网络基本上是一样的,因此将普遍意义的神经网络和卷积神经网络的实现合成一篇. 神经网络实现思路 "扔掉神经元" 尽管所有教程在介绍神经网络时都会把一大堆神经元画出来,并且以输入节点--神经元--输出结点连线,但是,在编程实现时,基于神经元去编程是低效的.典型如这篇经典文章里面的代码: http://blog.csdn.net/zzwu/article/details/575125. 比较合适的方法是将神

程序猿之---C语言细节16(看了绝对值,编译类型ANSI C和K&amp;R C类型判断,c编译器类型转换bug的细节)

主要内容:编译类型ANSI C和K&R C类型判断,c编译器bug的细节 #include <stdio.h> int main() { // 例子1 :编译器类型判断 /* * K&R采用无符号保留原则,即当一个无符号类型与ing 或更小的整型混合使用时,结果类型为无符号 * ANSI C采用值保留原则, 即当把几个整数操作数像下面这样混合使用时,结果类型可能为有符号也可能为无符号 * ,结果取决于操作数的类型的相对大小 */ if(-1 < (unsigned cha

《C专家编程》笔记(一)——C语言的历史、K&amp;R C和ANSI C

1. C语言的许多特性是为了方便编译器设计者而建立的.于是C语言的语言特性有:数组下标从0而非1开始:C语言的基本数据类型直接与底层硬件相对应:auto关键字只对创建符号表入口的编译器设计者有意义:表达式中的数组名可以看作是指针:float被自动扩展为double(ANSI C中不再如此):不允许嵌套函数(简化了编译器):register关键字,为编译器设计者提供线索,却把包袱丢给了程序员. 2. C编译器不曾实现的一些功能必须通过其他途径实现(编译器实现的功能,如加减乘除.指针.取地址).在C

K&amp;R练习题6-1统计关键词出现的次数

这道练习题训练了: 1.结构体数组 2.二分查找 3.指针操作 ---- 都不难,但很基础,我觉得很好,做完了记到博客上来,题目见k&R,实现如下: /* * Practice of struct array. K&R 6-1 * @author : wusuopubupt * @date : 2014-09-18 */ #include <stdio.h> #include <ctype.h> #include <string.h> #define M