王垠:數學和編程

jopen 9年前發布 | 20K 次閱讀 編程

文/王垠

好些人來信問我,要成為一個好的程序員,數學基礎要達到什么樣的程度?十八年前,當我成為大學計算機系新生的時候,也為同樣的問題所困擾。面對 學數學,物理等學科的同學,我感到自卑。經常有人說那些專業的知識更加精華一些,難度更高一些,那些專業的人畢業之后如果做編程工作,水平其實比計算機系 畢業的還要高。直到幾年前深入研究程序語言之后,對這個問題我才得到了答案和解脫。由于好多編程新手遇到同樣的困擾,所以我想在這里把這個問題詳細的闡述 一下。

數學并不是計算機科學的基礎

很多人都錯誤的認為,計算機科學是數學的一個分支,數學是計算機科學的基礎,數學是更加博大精深的科學。這些人以為只要學會了數學,編程的事情全都不在話下,然而事實卻并非如此。

事實其實是這樣的:

  • 計算機科學其實根本不是數學,它只不過借用了非常少,非常基礎的數學,比高中數學還要容易一點。所謂“高等數學”,在計算機科學里面基本用不上。
  • 計算機是比數學更加基礎的工具,就像紙和筆一樣。計算機可以用來解決數學的問題,也可以用來解決不是數學的問題,比如工程的問題,藝術的問題,經濟的問題,社會的問題等等。
  • 計算機科學是完全獨立的學科。學習了數學和物理,并不能代替對計算機科學的學習。你必須針對計算機科學進行學習,才有可能成為好的程序員。
  • 數學家所用的語言,比起常見的程序語言(比如C++,Java)來說,其實是非常落后而糟糕的設計。所謂“數學的美感”,其實大部分是夜郎自大。
  • 99% 的數學家都寫不出像樣的代碼。

數學是異常糟糕的語言

這并不是危言聳聽。如果你深入研究過程序語言的理論,就會發現其實數學家們使用的那些符號,只不過是一種非常糟糕的程序語言。數學的理論有些是 有用的,然而數學家門用于描述這些理論所用的語言,卻是紛繁復雜,缺乏一致性,可組合性(composability),簡單性,可用性。這也就是為什么 大部分人看到數學就頭痛。這不是他們不夠聰明,而是數學語言的“設計”有問題。人們學習數學的時候,其實只有少部分時間在思考它的精髓,而大部分時間是在折騰它的語法。

舉一個非常簡單的例子。如果你說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,各種扭來扭去的希臘字母,希伯來字母…… 斜體,黑體,花體,雙影體,……用不同的字體來表示不同的“類型”。很多符號的含義,在不同的子領域里面都不一樣。有些人上一門數學課,到最后還沒明白那 些符號是什么意思。

很多人學習微積分都覺得困難,其實問題不在他們,而在于萊布尼茲(Leibniz)。萊布尼茲設計來描述微積分的語言(∫,dx, dy, ...),從現代語言設計的角度來看,其實非常之糟糕,可以說是一塌糊涂。我不能怪萊布尼茲,他畢竟是幾百年前的人了,他不知道我們現在知道的很多東西。 然而古人的設計,現在還不考慮改進,反而當成教條灌輸給學生,那就是不思進取了。

數學的語言不像程序語言,它的歷史太久,沒有經過系統的,考慮周全的,統一的設計。各種數學符號的出現,往往是歷史上某個數學家有天在黑板上隨 手畫出一些古怪的符號,說這代表什么,那代表什么,…… 然后就定下來了。很多數學家只關心自己那塊狹窄的子領域,為自己的理論隨便設計出一套符號,完全不管這些是否跟其它子領域的符號相沖突。這就是為什么不同 的數學子領域里寫出同樣的符號,卻可以表示完全不同的涵義。在這種意義上,數學的語言跟 Perl(一種非常糟糕的程序語言)有些類似。Perl 把各種人需要的各種功能,不加選擇地加進了語言里面,造成語言繁復不堪,甚至連 Perl 的創造者自己都不能理解它所有的功能。

數學的證明,使用的其實也是極其不嚴格的語言——古怪的符號,加上含糊不清,容易誤解的人類語言。如果你知道什么是 Curry-Howard Correspondence 就會明白,其實每一個數學證明都不過是一段代碼。同樣的定理,可以有許多不同版本的證明(代碼)。這些證明有的簡短優雅,有的卻冗長繁復,像面條一樣繞來 繞去,沒法看懂。你經常在數學證明里面看到“未定義的變量”,證明的邏輯也包含著各種隱含知識,思維跳躍,非常難以理解。很多數學證明,從程序的觀點來 看,連編譯都不會通過,就別提運行了。

數學家們往往不在乎證明的優雅性。他們認為只要能證明出定理,你管我的證明簡不簡單,容不容易看懂呢。你越是看不懂,就越是覺得我高深莫測!這 種思潮到了編程的時候就顯出弊端了。數學家寫代碼,往往忽視代碼的優雅性,簡單性,模塊化,可讀性,性能,數據結構等重要因素,認為代碼只要能算出結果就 行。他們把代碼當成跟證明一樣,一次性的東西,所以他們的代碼往往不能滿足實際工程的嚴格要求。

編程是一門藝術

從上面你也許已經明白了,普通程序員使用的編程語言,就算是 C++ 這樣毛病眾多的語言,其實也已經比數學家使用的語言高明很多。計算機科學并不是數學的一個分支,它在很大程度上是優于數學,高于數學的。有些數學的基本理 論可以被計算機科學所用,然而計算機科學并不是數學的一部分。數學在語言方面帶有太多的歷史遺留糟粕,它其實是泥菩薩過河,自身難保,它根本解決不了編程 中遇到的實際問題。

編程真的是一門藝術,因為它符合藝術的各種特征。藝術可以利用科學提供的工具,然而它卻不是科學的一部分,它的地位也并不低于科學。和所有的藝 術一樣,編程能解決科學沒法解決的問題,滿足人們新的需求,開拓新的世界。所以親愛的程序員們,別再為自己不懂很多數學而煩惱了。數學并不能幫助你寫出好 的程序,然而能寫出好程序的人,卻能更好的理解數學。我建議你們先學編程,再去看數學。

來自: www.yinwang.org

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!