計算機編程算是否是理科中比較偏文的科目?
學習一門編程語言就像是學習一門外語,學習編程語法就像是學習語言語法,學習標準庫就像是習誦經典文句,學習框架結構設計模式就像是學習文章組織。
就像高德納所說的 文學編程 理念那樣,編程其實和文學在某些方面是相契合的。
比如就像優秀的文學家不會拘泥於語言一樣,優秀的程序員通常也不會挑剔編程語言;
又比如就像語言表達能力越弱的人越喜歡用新奇的網路語言一樣,編程能力越差的人通常也最喜歡追求新奇的編程語言。
種種這些都能體現出編程與文學的相通點來。
那麼是否可以說計算機編程其實算是理科中比較偏文的科目呢?
PS1:
所謂偏文,其實是相對於數學物理這樣的傳統純粹的「理科」而言的。眾所周知,在數學中,我們只需基於幾條基本定義與定理推導,便能舉一反三得出各式各樣的新公式及結論。這種推導過程是純粹的邏輯,並不依賴大量的前提記憶。
而計算機編程則不是。計算機編程中,程序員往往是花費大量的腦力和精力在各種既定的規範、標誌、介面、協議等瑣事上,而真正花在邏輯演繹及推導上的其實並不多,所以在計算機編程界才會有鼎鼎大名的 RTFM 這樣的俗罵。而這和文章家寫文章時引經據典而查閱參考文獻何其相似,與數理的學習工作方法則相去甚遠。
PS2:
在數學這樣的學科發展中,其實與其說是人們發明了各種定理不如說是發現了各種定理,所以在數學中各種定理其實都是有跡可循、有路可推導的。這些定理渾然天成,並不會有矯揉造作的成份在。
而在計算機編程中,很多方面的知識(不是所有方面)其實都是人為設計和發明的,所以會有各式各樣成文規範,這些成文規範有些有邏輯但有些其實並沒有,有些有問題的成文規範可以逐步改進有些則徹底成了歷史包袱和坑。
雖然計算機編程才發展了半個世紀,但這樣的歷史包袱和坑就已經很多了,比如unix的creat系統調用(居然不是create)、time_t溢出(很低級的錯誤)、open系統調用中flags(居然不是按位或的)等等。程序員在面對這樣的情形時,只能RTFM,別無他法。可以想見,這些歷史包袱和坑只會越來越多,也會越來越禁錮和浪費程序員的腦力。
此外,編程語言本來就是給人類看的且能被計算機執行的語言。既然是給人看的,符合人類的語言習慣也沒什麼丟人的。好的代碼往往對變數與函數的取名更為考究,其實就是為了更好地適合人類的閱讀習慣,讓代碼的行文看起來更像一篇自然的文章。
我一再強調,我所說的偏文,並不是說計算機編程是文科的意思,只是說計算機編程並不只是純粹的理科性質的邏輯推理。程序員同樣需要耗費腦力了解那些沒有邏輯的成文規範,也需要花費精力將代碼組織得通俗易懂好維護。這些方面,其實所需要的思維都是偏文科的。
當然,我知道,一些程序員會覺得我所用的「文科」字眼有損他們的自尊,因為他們打心底覺得「文科」是下等學科,要是他們執意這麼理解,並且以為我是在諷刺他們(很多回答其實都有這個傾向),那我也無話可說。
這是文學:
我們家的後園有半畝空地,母親說:「讓它荒著怪可惜的,你們那麼愛吃花生,就開闢出來種花生吧。」我們姐弟幾個都很高興,買種,翻地,播種,澆水,施肥,沒過幾個月,居然收穫了。
這是編程:
我們家的後園有半畝空地,母親說:「讓它荒著怪可惜的,你們那麼愛吃花生,就開闢出來種花生吧。」我們姐弟幾個都很高興,於是我們買種,如果買種成功,我們會翻地,如果翻地成功,我們會播種,如果播種成功,我們會澆水,如果澆水成功,我們會施肥,如果施肥成功,那麼這裡我們考慮的很充分,首先,必須考慮假如幾個月內出現了不可預見的天氣問題而導致不能收穫時怎麼辦,一個辦法是讓花生髮現自己的狀態異常時對我們進行通知,然而我們發現花生本身並不帶有這種功能,於是我們兄弟姐妹已經約定,每天從年紀最大的人開始遍歷(但不包括大姐),由最近最清閑,沒有來地里時間最長的人去地里進行輪詢,如果有兩個最近一樣清閑,沒來地里時間一樣長的人,按第一個遍歷到的人為準,一旦他來地里,發現花生狀態異常,他會回屋子通知大姐,除非大姐確定接收到了通知,他必須站在屋子裡反覆通知。大姐接收到了通知,則立刻回收用於製作煮花生的鍋,調味料等東西。
「你們的方法不錯」母親說:「不過,有幾個地方有問題,首先如果大姐被派出去幹事,那麼大姐的通知者就必須反覆進行無用通知,白白浪費一個人力,這對並發來說不是好辦法,不如通知大姐10次,每次間隔1毫秒,如果大姐沒有接收到消息,則在牆上激活一個flag,然後去干其他事,而大姐每次無論出去幹什麼,回來的第一件事就是查看flag。」
「媽媽,這樣有問題吧,如果通知者發現大姐已經出門,flag被立起來,而大姐實際上處於正在出門的瞬間,大姐會不會收不到flag啊」
「不會,即使大姐在出門瞬間,那麼等大姐回來的時候還是會看到flag的,你說的這種情況是最壞情況,但正確性是保證的。」
「有道理,那就先這麼做吧!」
於是我們姐弟幾個都很高興,買種。
學習一門編程語言就像是學習一門外語,學習編程語法就像是學習語言語法,學習標準庫就像是習誦經典文句,學習框架結構設計模式就像是學習文章組織。
學習數學就像是學習一門外語,學習數學符號就像是學習語法,學習定理就像背誦經典文句,而推導練習就像是學習文章組織。
學習物理就像是學習一門外語,學習物理符號就像是學習語法,學習定理就像背誦經典文句,而做實驗就像是學習文章組織。
……類比我也會,然而並沒有什麼卵用
比如就像優秀的文學家不會拘泥於語言一樣,優秀的程序員通常也不會挑剔編程語言;
嫌棄C++的linus表示那個題主你過來,我給你加個linux專屬的buff
又比如就像語言表達能力越弱的人越喜歡用新奇的網路語言一樣,編程能力越差的人通常也最喜歡追求新奇的編程語言。
搞了Typescript的Anders默默向你投來關愛的目光。講真,人家不用針對你,和他比,我們在座各位幾乎全是垃圾。
眾所周知,在數學中,我們只需基於幾條基本定義與定理推導,便能舉一反三得出各式各樣的新公式及結論。這種推導過程是純粹的邏輯,並不依賴大量的前提記憶。
我就不信高數學的人用的定理都是自己推導出來的。
至於舉一反三,語文書上「兩顆棗樹」都能給你得出幾千字的解讀,你說數學和語文是不是挺像的?
而計算機編程則不是。計算機編程中,程序員往往是花費大量的腦力和精力在各種既定的規範、標誌、介面、協議等瑣事上,而真正花在邏輯演繹及推導上的其實並不多,所以在計算機編程界才會有鼎鼎大名的 RTFM 這樣的俗罵。而這和文章家寫文章時引經據典而查閱參考文獻何其相似,與數理的學習工作方法則相去甚遠。
你寫程序不用推導那是因為有人推導過了。和你做數學題抄人家的公式/定理,搞研究參考前人的文章一樣。還是那句話,我就不信你用的定理都是自己推導出來的。
至於既定的協議、標準、介面、規範,你搞推導的時候符號不用前人的,定義不用前人的?
至於高德納的文學編程,我去wiki上看了一下。
文學程序是用自然語言(比如英語)寫出來的對程序邏輯的解釋,程序中交織點綴著宏和傳統源代碼段。在文學編程的源文件中,宏很簡單,它或與標題類似,或是解決編程問題時用人類語言描述抽象的解釋性短語。它把代碼段或更低層次的宏隱藏了起來,且與計算機科學教學時經常用到的,用偽碼寫的演算法相似。這些任意解釋的短語成為新的精確的操作符,操作符由程序員在運行過程中創建,組成了在基本編程語言之上的「元語言」。
總結下:
- 文學編程本質上還是描述邏輯
- 文學編程主要靠宏來實現
- 宏具有語義,對讀者友好
- 宏屏蔽的具體代碼的實現細節
- 這是一種搭載在傳統語言上的新語言(編程能力挺差的人都喜歡搞這個)
這和寫傳統代碼有啥區別?
無非他老人家比較激進,把類/函數換成了宏,以獲得更強的可讀性。(宏比函數名更具有可讀性這點,你們看看Object-C就不會懷疑了)
(如果數學證明不是寫得越讓人看不懂越好的話,那麼我們是不是也可以搞個文學數學出來,好像發現了不得了的東西:)
你會覺得編程和寫文章挺像,那是因為你得聽產品經理講故事。然後根據他的故事來寫你的代碼。這個時候你跟著他的思路來改著寫有一個好,他明天把故事換了你小修小補就行了,不用從頭再來一遍。講道理的話,其實這個世界上絕大多數的程序都能從一個automata衍生出來,關鍵是你一般不會這麼搞,因為:
- 這麼搞有時候太難寫了,你不想和自己過不去
- 這麼搞有時候太難讀了,你怕同事和你過不去
- 這麼搞有時候既難寫又難讀,誰搞誰**
- 有狂戰斧我不用難道用補刀斧?
不知道。。。
首先需要說明的是,在忽略足夠多的細節時,有非常多的東西看起來都十分相似甚至一模一樣,但這並不能代表這些東西就是一樣的或者相似程度非常高的。舉個例子,我可以把任意需要寫文章的科目都說成是偏文的科目。理由如下:
1.a 寫文章的過程就是在腦中醞釀好想寫的內容,然後經過對語言的組織把腦海里想好的東西寫在紙上變成文章
1.b XX學科研究的過程就是在腦海里醞釀好想寫的東西,然後經過對語言的組織把內容寫在紙上變成論文
2.a 優秀的文學家腦海中醞釀的東西往往是深刻的、發人深省的
2.b 優秀的XX學科的學者腦海中醞釀的東西往往是深刻的、發人深省的
因此,XX學科和文學有著許多相似,它就是偏文的學科。
毫無疑問,這樣得出的結論是毫無意義的,因為得出結論的過程忽略了太多細節,以致於忽略了某些事物核心的特點,僅取了它的一些細枝末節。
那麼,編程到底是不是偏文的科目呢?我也不知道,因為我不知道「偏文」這個概念到底該如何定義,或者說,和文學有多大程度的近似就可以算偏文?但在我看來,編程本身,是很純粹的工程行為。
先來看看維基百科上是怎麼定義工程學的:「The creative application of scientific principles to design or develop structures, machines, apparatus, or manufacturing processes, or works utilizing them singly or in combination; or to construct or operate the same with full cognizance of their design; or to forecast their behavior under specific operating conditions; all as respects an intended function, economics of operation or safety to life and property.」。這個定義比較拗口,但核心思想就是,利用科學定律設計或製造東西的行為,以及在這些東西的基礎上進行改進、操作、維護等行為,都屬於工程學。不管怎麼說,工程學的東西都免不了和科學定律打交道。計算機毫無疑問是應用科學定律發展出來的機器。編程的過程就是操作計算機的過程,這個過程其實就是間接地在應用科學定律。編程和寫作的一個非常重要的區別就在於,寫作可以放開了性子隨意寫,但編程卻始終有著邊界,這些邊界有的是在物理上決定的, 有的是在數學上決定的,但無論如何,編程始終需要在某些科學定律劃定的邊界內進行。
當然了,我自己也不止一次覺得編程和寫作在很多地方都十分相似,我也經常用寫作和編程類比。但從根本上來講,我仍然覺得它們是完全不同類的兩件事情。編程,和其他工程學類似,都需要謹慎地在科學劃定的邊界內前行,而寫作則毫無疑問自由地多不不,是偏魔..法的科目.
(是在說SICP的事,沒有任何mo的意思)
如果僅針對大家上stackOverflow上摘抄名言警句這種現象而言,題主的觀點還是蠻有道理的。
順便補張圖翻了一下發現沒有人說Curry-Howard correspondence,那我來從這個角度補充一下吧。
Curry-Howard correspondence揭示了計算機程序和數學證明的對應關係,或者說類型系統和形式邏輯的對應關係。舉個例子,函數類型可以認為是一個命題,而符合該類型的一個程序可以認為是該命題的一個證明,這就是類型即命題,程序即證明。現在存在一些利用這種對應關係的證明工具,比如Coq,你可以在裡面形式化的描述你要證明的命題,形式化的寫出你的證明,然後Coq的類型系統會自動檢查你證明的正確性。
從這個角度來看,題主的對比其實不太恰當。比較計算機編程和數學,就像是比較寫數學證明和數學一樣,這樣比較下來,寫證明當然是一個相對偏文的過程。不過,就像寫證明不能代表數學一樣,寫程序也無法代表計算機科學;就像只會把各種數學定理組合起來證明命題並不能使你成為好的數學家一樣,只會調用各種框架API也不能使你成為好的計算機科學家。來來來,你先給我編300個人名出來。要求能一眼看出人物性格的那種。來吧,你想。你慢慢想。
現在的年輕人。對,我的代碼都是十四行
這是工科中偏哲學、政治的一門學科。它從一開始就探討何為第一性和世界是否是可知的,並且在語言、民族、宗教、領土問題上經常發生衝突。
哲♂學篇
許多面向對象編程的程序員認為世界是由對象組成的,所有物質(客觀實在)都是對象,世界上一切現象都產生於對象方法的調用。但他們認為世界是不完全可知的,因為對象是封裝的。我們了解的世界,都是從對象暴露出的介面中了解到的。舉一個例子:class Frog {
public eaten() {
... // 田雞被吃的種種變化,你調用了這個方法,吃了田雞
pray(); // 它死之前竟然禱告了!然而這是在函數內部的,我們不知道!
}
// 禱告是一個私有方法,我們也不知道……
private pray() {
elder.addOneSecond(); // 竟然加了一禾
}
// 竟然所有的Frog都有著同一個elder,然而我們從不知道!
static final private HumanBeing elder = new HumanBeing(...);
}
許多函數式編程的程序員認為世界是由函數和數據組成的,函數是第一類對象。我們每天之所以這麼活著,世界之所以這麼發展,都是因為有一坨坨的函數在作怪,而我們也不過是一堆函數,在世界發展的過程中起著作用罷了。由於函數內部我們看不到,所以也是不可知的。我們再舉個例子:
-- 程序員(上天?)編寫函數:天荒地老_ _ _,我為_ _ +1s。這個函數顯然不正確,僅作為示例
addOneSecond x = (fst x, snd addOneSecond( (fst x, (snd x) + 1) ) )
-- elder也是個函數,不過是個常函數
elder = ("...", leftSecond)
-- 天命註定
addOneSecond elder
面向過程編程的程序員更願意相信這事件一切的故事都是一段情,一份緣。你我相知相遇都是上巧妙安排的命中注定,只是時機未到,當然也有可能一直都等不到。由於函數對外只暴露介面,我們同樣對函數內部一無所知。最後一個例子:
typedef struct {
char name[10];
...
} Programmer;
Programmer you;
// 你只能看到一個「公平正義」的介面,然而看不到內容
// 算命先生只能會告訴你一輩子都不會有女朋友,至於為什麼,那是天機不可泄露
bool isDanShenYiBeiZi(Programmer monkey);
void getGirlFriend()
{
...
if (!isDanShenYiBeiZi(you)) {
makeCouple(you, girlFriend);
}
.
}
// 這裡就是天機,程序猿怎麼會找到女朋友,必須單身一輩子
bool isDanShenYiBeiZi(Programmer monkey) {
return TRUE;
}
政?治篇
世界上有上千種編程語言,當然絕大多數是鬧著玩的。目前真正被工業使用的語言不過百種,使用量較大的不過數十種,用戶群體龐大的不過十餘種,能決一雌雄的更是屈指可數,正如當今的世界格局一般,一超多強,弱逼一群,真正每天挑事的也就是美國、俄羅斯、中國、歐盟。
每種語言對別的語言幾乎都有競爭關係,所以語言的開發者、使用者每天也撕的不可開交。雖說PHP是世界上最好的語言無可辯駁,但是天下第二還是要爭一爭的。比如,寫C的認為C++是垃圾,C++程序員認為C#是垃圾,C#程序員覺得Java是垃圾,Java猿反咬一口:在座的各位都是垃圾。這就是語言衝突。
有一些東西,超越了語言的障礙,形成了一種文化,甚至演化出了教派。比如,有人堅持左大括弧另起一行;有人堅持同一行書寫;有人表示,在座的各位都是垃圾,但凡寫括弧的都是異端;當然也有奇葩……
function foo() {
}
function bar()
{
}
def fuck():
#define 皇上駕到,爾等刁民還不跪下 {
#define 猴耍完了,起駕,迴鑾 }
#define 吾皇萬歲萬歲萬萬歲 return 0;
int main()
皇上駕到,爾等刁民還不跪下
吾皇萬歲萬歲萬萬歲
猴耍完了,起駕,迴鑾
最後說說「領域」問題。本來後台是Java、PHP、Python的天下,最近幾年卻殺出了Node.js,讓許多後台程序員擔心自己的飯碗被前端搶了。你說JavaScript一個主要用來寫前端的語言,怎麼就跑到後台去了呢?當時我就吟了兩句詩:_ _ _ _ _ _ _, _ _ _ _ _ _ _。
這篇回答就做了些微小的貢獻,謝謝大家。「偏文偏理」的說法二元論了。不同的學科形成的是一個由硬至軟的光譜,數學最硬 &> 物理 &> 化學 &> 生物 &> 心理學 &> ... &> 文學欣賞等。碼農學的軟硬度應該和物理差不多或稍軟。總之比數學軟,比化學硬。
此為結論。至於題主長篇大論中體現出來的邏輯,給我的感覺和看崔永元反轉相似 --- 功課不能說沒做,但是缺乏基本的科學素養,對數學的了解像高中生,對本行的了解缺乏廣度,導致思路奇異。胡扯,編程明明是一門藝術。
眾所周知,在數學中,我們只需基於幾條基本定義與定理推導,便能舉一反三得出各式各樣的新公式及結論。這種推導過程是純粹的邏輯,並不依賴大量的前提記憶。
而計算機編程則不是。計算機編程中,程序員往往是花費大量的腦力和精力在各種既定的規範、標誌、介面、協議等瑣事上,而真正花在邏輯演繹及推導上的其實並不多,所以在計算機編程界才會有鼎鼎大名的 RTFM 這樣的俗罵。而這和文章家寫文章時引經據典而查閱參考文獻何其相似,與數理的學習工作方法則相去甚遠。
此言差矣。規範、標誌、介面和協議也是純粹通過邏輯演繹及推導弄出來的。不過世界上還是存在很多不是純粹通過邏輯演繹及推導弄出來的、醜陋的協議。這有三個理由
- 丑可以賺更多的錢
- 作者煞筆
- 作者覺得這根本無關緊要所以隨便弄了一個
希望題主不要被現實蒙蔽,要學習編程中的精髓。
看到下面這句話不能忍了
就像高德納所說的 文學編程 理念那樣,編程其實和文學在某些方面是相契合的
Literature Programming 和 Literature 的關係類似於 卡巴斯基 和 巴基斯坦 的關係。 Literature Programming 只是試圖讓程序結構像是自然語言,和所謂的文學性無關。
顯然題主沒有看過 Knuth 用 WEB 寫得程序
比如就像優秀的文學家不會拘泥於語言一樣,優秀的程序員通常也不會挑剔編程語言;
為什麼不試試 bash 編程呢?
另外文學家真的拘泥於語言,比如張愛玲的英文寫作
程序員往往是花費大量的腦力和精力在各種既定的規範、標誌、介面、協議等瑣事上,而真正花在邏輯演繹及推導上的其實並不多
做 Framework 的已經被踢出編程界....
不僅偏文,而且,我就是把它當外語課教的。
你以為說成偏文就能找到女朋友了嗎
我覺得題主問題的問題在於把學問單純簡化為理科和文科的一維連續譜。
然而計算機科學更傾向於虛軸上的工科。所以Knuth堅決反對Computer Science這個講法。講道理,計算機算工科,我拿的就是工學學位~~~~
編程必須是文科啊
這都屬於創作類啊,代碼和詩歌一樣美麗,程序和樂譜一樣靈動,界面和油畫一樣艷麗。
而且數學也絕逼是文科啊!數學公式的推導,就像寫偵探小說,按照蛛絲馬跡抽絲剝繭,逐漸推動劇情到高潮,哪怕是推斷錯誤,也能給人一種缺憾美,有一種我們關注的是沿途的風景的文學美感啊!
物理?跑不了必須是文科!!你在用文學描繪世界表達你的情感的時候,牛頓用一條突破天際的拋物線,設想出了繞地衛星的可能性。你還在用數學這種文學手段,比如愛情的可悲就像兩條平行線永遠不相交的時候,別人已經升華到了廣闊的宇宙空間里。
化學,藝術就是爆炸!!!迪達拉,用生命告訴你,化學是世界上最文學的文學,它的美能細微如塵,它的美能浩若煙海。
涵蓋語言學、數學、物理學、化學、哲學、軍事、經濟學、考古學等所有人類文化的編程,怎麼能不是文科?建議所有文學專業,都加開計算機編程課程,而且作為核心必修課好嗎?
明明是玄學
剛才寫了一個很長的回答來分析。不過寫完看了一遍,覺得沒必要那麼長,只需要幾句話就夠了:
題主你描述的計算機編程,是個工科。而你拿來對比的數理化,是理科。所以它們不同。這跟文科沒關係。推薦閱讀:
※試以最少的字講一個故事?
※假如每個朝代的歷史都是作家創作出來的小說,那麼單從文學性上看,哪一部小說的寫作水平、文學價值最高?
※《春江花月夜》「孤篇壓全唐」的評價是否過譽?
※你聽過最酷的一句話是哪句?說這句話的人也一樣酷么?
※如果是王家衛去拍《西遊記》會是什麼樣的故事?