程式語言重不重要?是否要學多種程式語言?這類爭論也是經常出現在開發者之間,姑且不考量軟體開發時開發工具、流程等其他工具因素之影響,在網路文件豐富的時代,隨意找些教學,兩三小時就可上手一門語言的大有人在,只是,這類人也略分為兩派,各自主張程式語言重要與否!

語法層次的重要性

主張程式語言不重要的人,多半持有的論點是:「反正每個程式語言都很像,根本不用學,要用的時候,google一下就可以上手了」。

誠然,程式語言基本流程語法多半就是條件判斷、反覆等,物件導向語法多半支援類別、繼承,主流語言也會吸收彼此優良元素,像是近來不少語言紛紛支援一級函式概念,這種種因素,使得不少語言彼此之間的相似性越來越高,表面看來似乎只是語法關鍵字不同。

程式語言要解決的問題集合,基本上存在著重疊之處,因此用來解決問題的元素也會有所重疊,吸收彼此優良元素,則是將重疊問題上本身原本不擅長的部份,以其他語言擅長的元素來解決,這有助於開發者在轉換語言時,可以立即解決通用性的問題,這就是所謂「google一下就可以上手」的部份,然而,這麼設計的目的,除了吸引其他語言開發者跳槽之外,更重要的是,讓開發者能在很短的時間內,就將注意力放在該語言所專精、非通用的問題領域之上。

不同語言的重要性,往往就在於非通用的問題領域上。

舉JavaScript為例,雖然支援物件導向,但在它不被重視的那個年代,往往被從基於類別的角度來說明或認識,少於著重在其基於原型的特性,也甚少提及它的一級函式特性,多半當作程序函式或物件上的方法來解釋,直到Ajax概念重新興起,使用JavaScript從無到有打造了整個前端生態系,才發現JavaScript原型與一級函式的獨到之處,甚至,後來也打造了整個非同步為主軸概念的後端生態系。

不同語言的重要性,也往往在那些獨到的語法,這有正反兩面,有時它們是優點,像是Ruby特有的區塊語法,是形塑DSL(Domain-Specific Language)時很重要的元素;有些是所謂的Caveat,也就是那些一開始忽略沒考量到的語法陷阱,或者是一開始用意是好的,但後來遭到誤用,甚至惡意使用的語法。

各種語言都可能有這類問題,只看到解決通用問題領域的語法,就天真地認為語言不重要,卻忽略了語言中Caveat的部份,就容易導致臭蟲、效能不彰,甚至安全問題。

語言慣例與典範的重要性

「無論任何領域,文化都是最重要也最難學習的!」我先前曾在數篇專欄中,提及程式語言背後文化、慣例、典範等的重要性。從語言來說,如何讓語言撰寫時,符合該語言的慣例與典範,就不單只是google一下,語言教學就能馬上融入的。

拿Java寫C,拿JavaScript寫Java,在C#程式碼中可以明顯看得出,哪些部份是習慣使用Java的開發者寫的,哪些又是習慣C#的開發者寫的,這些都是沒能掌握語言獨特慣例的鮮活例子。

如果號稱可以隨時上手多門語言,卻無法道出或實作出各語言應有的典範,那語言對這類開發者來說,確實也沒什麼好學的,充其量只是浪費時間在學習相同元素上而已。即使是同一問題,各語言也可從通用的觀點來解決,然而真正重要的是,是瞭解同一問題在各語言的特有觀點下各自如何解決,這樣學習多門語言才有意義。

學得廣而重複是沒有意義的,若想學得廣,也要學到能運用典範的深度。

有些語言非常堅守慣例與典範,即使在演化語言的過程中,是否加入某些特性也以此為據。

像是Python在是否決定支援尾端遞迴消去時,社群中有過不少爭論,Python創建者Guido van Rossum此時以仁慈獨裁者(benevolent dictator for life, BDFL)身份做了不支援此特性的決定,理由是「it's simply unpythonic」,也就是這不符合Python慣用法,在這類語言中,若無法融入慣例或典範下撰寫程式,只會覺得處處受限,甚至破壞了既有程式碼的穩定性。

從DSL看到多語言的重要性

實際上,程式開發至今在常見、通用的問題領域上,已累積了不少經驗,以及豐富的文件,使得開發者在解決通用問題時,能得心應手,然而,在另一方面,使得解決特定問題領域的語言也開始展露頭角。

近來最顯著的實例就是,一度被視為學術意味濃厚的函數式語言,通過了時代的考驗,除了純函數式語言的討論度提昇之外,各通用語言中也吸收越來越多函數式的元素,有些已使用語法支援,有些透過程式庫或框架來協助實現。

學習多門語言的重要性,完全不在解決通用問題的部份,而在於學習語言如何解決特定的問題,因而開發者可以從多語言的學習中,瞭解到物件導向、開發速度、非同步處理、平行、測試、可讀性等在各語言下是如何實現;甚至,可在無法採用特定語言解決特定問題的情況下,在原專案使用之語言上,實作出特定語言的子集,像是在JavaScript實現基於類別的封裝與繼承,在Java上實現惰性求值與函數式概念的平行,在強力支援meta-programming的語言中,實現各種領域專用語言。

如果學習多個語言不重要,那DSL概念也就不會受到重視。

DSL其實也告訴開發者,真正要學習的是如何解決特定問題,只不過,多數開發者要透過DSL的引導先去認識問題本身。Richard Warburton在《Java 8 Lambdas》中提到:「人類是藉由重複領悟簡單範例來學習,並從中發展出理解模式」,當開發者無法直接理解特定問題領域,透過學習DSL的語法元素會是個不錯的開始。擴大來看,當開發者學習一門語言時,透過語法元素真正該習得的,是如何解決特定問題。

不同語言形塑不同開發者

圖靈獎得主Edsger W. Dijkstra,他在〈Dijkstra on Haskell and Java〉信中提到:「不僅是小提琴塑造了小提琴家,我們訓練自己使用的工具也塑造了我們,而在程式語言這方面有著深遠的影響,它們塑造了我們的思考習慣」,他的目的是力勸德州大學預算委員會,別使用Java來取代Haskell,作為大學程式設計入門課程的語言。從另一個角度來看,這也部份說明了多語言學習的重要性,以免被單一工具束縛了思想。

在其他領域確實也有類似現象。近來,由於有機會接觸小提琴,我親身體會了小提琴在練習過程循規蹈矩、一絲不拘的要求,對「小提琴塑造了小提琴家」產生更深的體會。不過,並不是每個人都能接受這樣的過程形塑,實際上,在音樂領域中,不同的樂器會塑造不同的樂手,因每個樂手特質的不同,最終會選擇最擅長的樂器,然而對其他樂器保持一定的熟悉度或認識,這會產生正向回饋從而改善演奏技巧。

回到程式語言這個主題,如我在先前專欄〈程式語言與人格特質〉談過的,因開發者特質的不同,實際上,最後選擇專精的語言會各不相同,這也會反過來形塑出他人眼中開發者的形象。

不少開發者也具有這類的經驗,在接觸過一門或多門(厭惡的)語言之後,終於發現適合自身特質的語言。因此,若能多接觸不同的語言,不單是認識更多解決問題的角度,也是一種發掘開發者自身特質非常好的管道!

專欄作者

熱門新聞

Advertisement