學習程式語言不變的部分

Ching Yi, Chan
Jul 10, 2022

在進行程式語言的教學、學習或訓練時,我個人喜歡把核心放在「資料型別 (data type)」與「生命週期 (symbol 的 scope)」,最後才是「語法 (syntax)」。

語法放在最後,倒不是它不重要。而是多數的書籍或影音資源都會充份地解說語法,也是新手或初見的學習者最容易「觀察」並「模仿」的部分。在學習新東西的初期,所有的心力大多投入在語法的問題上了,以我的觀點,那是最不需要投入的部分。不管理解程度多少,學習者總是在輸入著程式,抄寫著程式,改寫著網路上查到的範例,語法的形狀遲早會熟悉的。這麼「反覆」使用的東西,不必刻意花時間記住,也能自然地刻印在心上。

相對於「外顯」且易於覺察到的語法,「語意」部分沒特別提醒的話,多數的學習者並沒有特別去下功夫。儘管「語意」聽起來抽象,程式語言至少不像我們日常使用的語言那樣的多變不可捉摸!對程式語言來說「語意」的主軸就是資料型別符號的可視範圍 (即生命週期的意思),再加上各種細瑣的語言特性。

細瑣的語言特性挺多元的,舉個初學者有機會寫到的華氏與攝氏溫度轉換,其實就是針對資料的型別轉換特性而設計的組合,相關概念有:

  • Conversions and Promotions
  • Implicit vs Explicit Type Conversion

回到核心部分,語意值得下功夫,因為它大多是「可攜式 (portable)」的知識,就算你換了其他語言,大概還是會有相同的概念存在。不同的語言在語法上,可能變化很大,但在語意的部分變化的部分會比想像中的小。

因此,要能承受較小痛苦去面對新語言,那就是得在自己的「母語」的語意上有強健的認識,語法什麼的靠小抄就行了。「語意」這種東西,就像文化底蘊一樣的,只要文化圈沒差距太大,是可以互通的。

資料型別

要上手資料型別就是先區分得出「基礎型別」與「自訂型別」。有些程式語言,例如 Java 有原生型別 (Primitive Type) 就是基礎型別。那麼基礎與否的分界在哪呢?特別是有些語言並沒有很明確地列出它有哪些基礎型別,或是因為「豐富的語言特性,而模糊了分界」。

我個人是這樣區分的,在不特別加工的情況下,資料可以直接參與運算。直白地講,可以使用 + - * / 等算數運算,或 > < == 之類的邏輯運算。只要是該語言定義的運算子,並且可以直接使用在「運算式」中的資料型別就是基礎型別

認識了「基礎型別」之後,我得到什麼益處了嗎?目前還沒有,但在提到「自訂型別」前,先提個特例「字串 (string)」,有的語言放在基礎型別,而有的語言並不是。傾向將它放在基礎型別的語言,至少會讓你可以用 ++= 來串接字串,但是支援程度不同的語言是有差異的,有的可以讓字串與非字串的型別串接,有的要求只能字串之間串接。所以,有些語言你串接字串與非字串前,要先透過轉型或特別的處理,將非字串的資料轉成字串。

字串在多數的程式語是「自訂型別」附加「可加法運算」的例外。

那麼我們怎麼看待「自訂型別」呢?它其實就是「自訂型別」與「基礎型別」的聚合物,透過特定的程式語法,將多種資料綑綁在一起使用。先前提到的「分界」是能不能參與基本運算,而自訂型別的「運算」就是「函式」。我們可以自然地想,函式就是自訂的運算子

這也是為什麼定義函式,是多數語言都有提供的功能,因為它們都支援著自訂的型別。但最終,能真的參與運算式的只有基礎型別,無論型別之間怎麼包裝,自訂函式中做了哪些運算,最終都回到了基礎型別的操作。

有了這些知識,我們就可以這麼應用:

Thought processes

寫程式不管邏輯如何實作,都是在「參與運算式」或「呼叫函式」前,把資料轉成運算子可接受的型別罷了。因此,對新手來說,除了基礎型別的運算會寫,還要會「查詢」且「識讀」函式參數們的型別,與回傳值的型別。

符號的可視範圍

在程式語言中最常見的符號 (Symbol) 就是變數,而最常被忽略的符號是函式 (及其容器,例如類別或模組)。在不同的程式語言,可視範圍 (Scope) 的建立時間不完全相同,但底層的技術大多是 Call Stack 與 Frame 去實作的。

當你已經有程式語言經驗後,接觸一個新的語言時,優先弄懂 Scope 是個好主意。這樣可以避免你寫出語意不清的東西,例如不小心把同名的變數遮蔽 (Shadowing/Hidding) 掉。不見得每個語言都會提醒你,有個同名的 OOO 變數或函式被新的定義取代了。Scope 本身不難,但巿面上一些書籍不見得有開立章節介紹,或是介紹得不太明顯,導致學習者沒有察覺正在教導 Scope 的知識。

目前,我見過最棒的 Scope 教學首推 CS61A,它用 Call Stack 與 Frame 的模擬來傳授 Scope 的概念,這門課真的相當值得觀看。

結語

要上手一個新的程式語言,我推薦的就是這二個主要概念:

  • 資料型別
  • 符號可視範圍

其他的部分,若干都是「領域知識」相關的操作,再依需要的主題慢慢克服就行了。

--

--