很多人写信问我,我需要什么水平的数学基础才能成为一名优秀的程序员?十八年前,当我在大学计算机系读大一时,也曾被同样的问题困扰。面对学数学、物理等学科的同学,我自卑。人们常说那些专业的知识更精,难度更大。如果那些专业毕业后做编程工作,水平其实比计算机专业的毕业生要高。直到几年前我钻研编程语言,我才从这个问题中得到答案和解脱。由于很多编程新手都会遇到同样的问题,所以我想在这里详细说明一下这个问题。数学不是计算机科学的基础很多人错误地认为计算机科学是数学的一个分支,数学是计算机科学的基础,数学是一门更深奥的科学。这些人认为只要学了数学,编程什么的都很容易,其实不然。事实是这样的:计算机科学根本不是真正的数学,它只是借用了很少的、非常基础的数学,而且它比高中数学要简单一点。所谓的“高等数学”在计算机科学中基本上用不到。计算机是比数学更基本的工具,就像纸和笔一样。计算机可以用来解决数学问题,也可以用来解决非数学问题,如工程问题、艺术问题、经济问题、社会问题等等。计算机科学是一门完全独立的学科。学习数学和物理不能替代学习计算机科学。你必须学习计算机科学才能成为一名优秀的程序员。数学家们使用的语言,与C++、Java等常见的编程语言相比,其实是非常落后的,设计也很差劲。所谓“数学之美”,其实多半是夜郎的狂妄。99%的数学家都写不出像样的代码。毫不夸张地说,数学是一门极其糟糕的语言。如果你深入研究过编程语言的理论,你会发现数学家使用的符号只是一种非常糟糕的编程语言。一些数学理论是有用的,但是数学家描述这些理论的语言是复杂的,缺乏一致性、可组合性、简单性和可用性。这也是为什么大多数人一看到数学就头疼的原因。这并不是他们不够聪明,而是数学语言的“设计”出了问题。当人们学习数学时,他们只花很少的时间去思考它的本质,大部分时间都花在纠结于它的语法上。举个很简单的例子。如果你说x-1表示x的-1次方(x的倒数),那么f-1是什么意思?f的-1次方,f的倒数?不要被数学老师的教条和借口所迷惑,他们总是告诉你:“你应该记住这个!”但是你有没有想过:“为什么!”x-1表示x的-1次方,而f-1显然以完全相同的形式表示函数f的反函数。一个是求幂,另一个是反函数。它们的速度不如它们快,但它们的编写方式相同。这种语言设计让人迷惑,反而喜欢以“约定俗成”为借口。如果你多读数学书籍,你会发现这只是数学语言数百年来积累的糟粕的冰山一角。数学书上全是上标和下标,带括号的上标和下标,x,y,z,a,b,c,f,g,h,各种扭曲的希腊字母,希伯来语来字母……斜体,粗体,swash、doubleshadow、……用不同的字体来表示不同的“类型”。许多符号的含义在不同的子字段中是不同的。有些人上了数学课,甚至不知道这些符号是什么意思。许多人发现学习微积分很难。其实问题不在他们,而在莱布尼茨。莱布尼茨设计的描述微积分的语言(∫,dx,dy,...),从现代语言设计的角度来看,其实是很糟糕的,可以说是一塌糊涂。我不能责怪莱布尼茨,毕竟他是几百年前的人了,很多我们现在知道的事情他都不知道。但是,古人的设计现在不认为是改进,而是作为教条灌输给学生,就是不想进步。数学语言不像编程语言。它历史悠久,没有一个系统的、周密的、统一的设计。各种数学符号的出现,往往是历史上某位数学家有一天在黑板上画了一些稀奇古怪的符号,说这个是什么意思,那是什么意思,……然后就搞定了。许多数学家只关心自己狭窄的子领域,为自己的理论设计一套符号,而不管这些符号是否与其他子领域的符号冲突。这就是为什么写在不同数学子领域的相同符号可能具有完全不同的含义。从这个意义上说,数学语言有点类似于Perl(一种非常糟糕的编程语言)。Perl胡乱地在语言中加入了各种不同的人需要的各种功能,使语言变得如此复杂,以至于Perl的创造者也无法理解它的所有功能。数学证明还使用极其松散的语言——奇怪的符号,加上模棱两可且容易被误解的人类语言。如果你知道Curry-HowardCorrespondence是什么,你就会明白每一个数学证明都只是一段代码。对于同一个定理,可以有很多不同版本的证明(代码)。这些证明有的短小精悍,有的又长又复杂,像面条一样扭来扭去,让人看不懂。你经常在数学证明中看到“未定义变量”,证明的逻辑也包含了各种隐性知识,思维跳跃,非常难以理解。很多数学证明,从程序来看,连编译都过不了,更别说运行了。数学家往往不关心证明的优雅性。他们认为只要能证明定理,我的证明简单不难懂你都无所谓。越是不明白,越是觉得我高深莫测!这种思潮在编程方面显示出它的缺点。数学家在编写代码时,往往会忽略代码的优雅、简洁、模块化、可读性、性能、数据结构等重要因素,认为代码只需要能够计算出结果即可。他们把代码当作证明一样的一次性的东西,所以他们的代码往往不能满足实际工程的严格要求。编程是一门艺术由以上所述,你可能已经明白,普通程序员使用的编程语言,即使是像C++这样问题多多的语言,其实也比数学家使用的语言要好得多。计算机科学不是数学的一个分支,它在很大程度上优于数学,高于数学。数学的一些基础理论可以被计算机科学所利用,但计算机科学不属于数学。数学在语言方面历史遗留下来的糟粕太多了。实为泥菩萨过河。它无法保护自己。根本解决不了编程中遇到的实际问题。编程真的是一门艺术,因为它符合艺术的各种特点。艺术可以使用科学提供的工具,但它不是科学的一部分,也不低于科学。和所有的艺术一样,编程可以解决科学无法解决的问题,满足人们新的需求,开辟新的天地。所以亲爱的程序员,不要再担心不懂很多数学了。数学不能帮助你写出好的程序,但是能写出好的程序的人才能更好地理解数学。我建议你先学编程,再看数学。
