好些人來信問我,要成為乙個好的程式設計師,數學基礎要達到什麼樣的程度?十八年前,當我成為大學計算機系新生的時候,也為同樣的問題所困擾。面對學數學,物理等學科的同學,我感到自卑。經常有人說那些專業的知識更加精華一些,難度更高一些,那些專業的人畢業之後如果做程式設計工作,水平其實比計算機系畢業的還要高。直到幾年前深入研究程式語言之後,對這個問題我才得到了答案和解脫。由於好多程式設計新手遇到同樣的困擾,所以我想在這裡把這個問題詳細的闡述一下。
數學並不是電腦科學的基礎
很多人都錯誤的認為,電腦科學是數學的乙個分支,數學是電腦科學的基礎,數學是更加博大精深的科學。這些人以為只要學會了數學,程式設計的事情全都不在話下,然而事實卻並非如此。
事實其實是這樣的:
數學是異常糟糕的語言
這並不是危言聳聽。如果你深入研究過程式語言的理論,就會發現其實數學家們使用的那些符號,只不過是一種非常糟糕的程式語言。數學的理論有些是有用的,然而數學家門用於描述這些理論所用的語言,卻是紛繁複雜,缺乏一致性,可組合性(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++這樣毛病眾多的語言,其實也已經比數學家使用的語言高明很多。電腦科學並不是數學的乙個分支,它在很大程度上是優於數學,高於數學的。有些數學的基本理論可以被電腦科學所用,然而電腦科學並不是數學的一部分。數學在語言方面帶有太多的歷史遺留糟粕,它其實是泥菩薩過河,自身難保,它根本解決不了程式設計中遇到的實際問題。
編**的是一門藝術,因為它符合藝術的各種特徵。藝術可以利用科學提供的工具,然而它卻不是科學的一部分,它的地位也並不低於科學。和所有的藝術一樣,程式設計能解決科學沒法解決的問題,滿足人們新的需求,開拓新的世界。所以親愛的程式設計師們,別再為自己不懂很多數學而煩惱了。數學並不能幫助你寫出好的程式,然而能寫出好程式的人,卻能更好的理解數學。我建議你們先學程式設計,再去看數學。
軟體程式設計與數學思維
軟體程式設計與數學思維 張水坤 大眾科學 科學研究與實踐 2007年第08期 摘要 近年來,學科的高速發展已經明確地反映出這樣乙個特點 學科基礎研究和技術開發越來越多地同數學建立更為緊密的聯絡,對各種數學工具的使用不僅越來越廣泛,而且越來越深入。要掌握好軟體程式設計,數學思維是非常重要的。先討論軟體...
程式設計與高等數學?
程式設計與高等數學?zhangyusong00 試用期 一級 最佳答案高數1 主講極限 導數 微積分學和它們一些簡單應用 高數2 主講重積分 線面積分 無窮級數和微分方程 可以說這些與你程式設計可能關係不大。其中好多東西是很難在實際中應用的,比如無窮級數 泰勒展開式 分部積分 高階無窮小等 但計算機...
《數學之美》與程式設計
2016 09 23 坐火車回家參加高中哥們兒的婚禮,車上無聊,便帶了一本 數學之美 雖然 之美 系列已經被很多人吐槽了,但是,這本書對我來說還是比較受用的。我很早之前看過這本書的目錄,之前對自然語言處理這個東西完全不感興趣,一如兩三年前對機械人技術不感興趣一樣,買了之後放了半年。現在看了這本書後,...