'聽Ruby之父這麼說,我也想創造一門新編程語言了'

"
"
聽Ruby之父這麼說,我也想創造一門新編程語言了

本文作者:Ruby之父松本行弘。

大家有過創造編程語言的經歷嗎?我想大多數人會回答沒有。

對於有編程經歷的人來說,編程語言是非常親切的存在,我們習慣了接受現成的編程語言,可能沒有想過要自己去創造一門新的編程語言。這也是情理之中的事情。

但其實我們大家都知道,世界上所有的編程語言都是由某個地方的某個人創造的。它們不是自然產生的,而是根據明確的意圖和目的被設計並實現的。如果過去沒有這些創造編程語言的人(編程語言的作者),可能我們今天還在用匯編語言編程吧。

其實,創造編程語言不僅可以提升我們作為技術者的價值,而且還可以使我們從中獲得很大的樂趣。而且隨著開源的普及,創造新編程語言的門檻一下子降低了許多。通過實際創造一門新的編程語言,我們可以學到編程語言的設計思路和實現方法。

可能有的讀者會想:“現在再創造編程語言還有什麼意義呢 ?”我們稍後回答這個問題,現在我們先來看一下編程語言的歷史。

在人們剛開始編程時,編程語言就隨之出現了,可以說編程的歷史就是編程語言的歷史。

個人創造編程語言的歷史

早期的編程語言是由在工作中切切實實與編程語言打交道的人創造的,這些人大多就職於企業的研究所(比如 FORTRAN、PL/1 的發明)、大學(比如 LISP)以及標準委員會(比如 ALGOL、 COBOL)等。也就是說,設計開發編程語言是專業人士的工作,但是這個傳統隨著 20 世紀 70 年代計算機的普及開始發生了變化。一些計算機愛好者在擁有了自己的計算機後,出於興趣開始編程,甚至開始開發新的編程語言。

其中最具有代表性的就是 BASIC 語言。BASIC 語言原本是美國達特茅斯學院用於教學的編程語言,它的語法非常簡單,用極少的代碼實現了最基本的功能,所以深受 20 世紀 70 年代編程愛好者的喜愛,並被他們廣泛使用。

這些編程愛好者也開始開發自己版本的 BASIC 語言。當時,個人計算機① 的內存頂多幾千兆,他們開發的 BASIC 語言就是可以在內存如此之小的機器上工作的小規模版本。這些小規模的 BASIC 程序大小不到 1 KB,它們在 4 KB 左右的內存上也能工作,跟現在需要大內存的語言處理器比起來真是令人驚訝。

① 通常稱為微機。微機是微型計算機、微型機的簡稱。

微機雜誌的時代

以個人開發的 BASIC 為代表的小規模語言(Tiny 語言)處理器不久便以各種各樣的形式進行了發佈。當時的軟件有的以 Dump list 的形式刊登在計算機雜誌上,有的將程序數據進行音頻轉換後收錄在雜誌附帶的薄膜唱片(sonosheet)中發佈。現在的人恐怕已經不知道薄膜唱片了吧。薄膜唱片是指塑料做的薄薄的唱片,不過唱片這個詞幾乎沒有人用了。據說當時的計算機愛好者都用唱片播放器連接計算機來讀取數據,而不使用磁帶錄音機這個最普遍的外部存儲設備。

20 世紀七八十年代是計算機雜誌(當時稱為微機雜誌)的全盛時期,在日本以下 4 種雜誌競爭激烈。

  • RAM (廣濟堂出版)
  • My Computer (電波新聞社)
  • I/O (工學社)
  • ASCII (ASCII 公司)

這 4 種雜誌中現在只有 I/O 仍在發行,不過也大不如前了。作為一個瞭解當時情況的人,我的內心充滿了無限感慨。

這之後,My Computer 雜誌派生出了 My Computer BASIC Magazine,又發生了很多事情,繼續講下去恐怕就會變成上歲數人的敘舊了,所以點到為止吧。如果去問問現在三四十歲的程序員,相信他們中間很多人都會眉飛色舞地講起那個年代的事情。

當時的微機雜誌附帶了收錄 BASIC 的薄膜唱片,除此之外還介紹了其他幾個小規模語言,如 GAME、TL/1 等。這些語言都反映了當時那個時代的特色,非常有趣,我們在本文的最後對其進行了介紹,請大家務必讀一讀。

個人創造編程語言的現狀

為什麼從20 世紀70 年代後期到80 年代前期開始興起個人創造編程語言了呢?我認為最大的原因是當時難以獲取開發環境。

20 世紀70 年代後期廣泛使用的微機是TK-80(圖1)那樣的主板裸露在外的單板機,很多都是半成品,需要自己去釺焊。這樣的機器不可能自帶開發環境之類的東西,軟件都要自己輸入機器語言之後才會工作。

"
聽Ruby之父這麼說,我也想創造一門新編程語言了

本文作者:Ruby之父松本行弘。

大家有過創造編程語言的經歷嗎?我想大多數人會回答沒有。

對於有編程經歷的人來說,編程語言是非常親切的存在,我們習慣了接受現成的編程語言,可能沒有想過要自己去創造一門新的編程語言。這也是情理之中的事情。

但其實我們大家都知道,世界上所有的編程語言都是由某個地方的某個人創造的。它們不是自然產生的,而是根據明確的意圖和目的被設計並實現的。如果過去沒有這些創造編程語言的人(編程語言的作者),可能我們今天還在用匯編語言編程吧。

其實,創造編程語言不僅可以提升我們作為技術者的價值,而且還可以使我們從中獲得很大的樂趣。而且隨著開源的普及,創造新編程語言的門檻一下子降低了許多。通過實際創造一門新的編程語言,我們可以學到編程語言的設計思路和實現方法。

可能有的讀者會想:“現在再創造編程語言還有什麼意義呢 ?”我們稍後回答這個問題,現在我們先來看一下編程語言的歷史。

在人們剛開始編程時,編程語言就隨之出現了,可以說編程的歷史就是編程語言的歷史。

個人創造編程語言的歷史

早期的編程語言是由在工作中切切實實與編程語言打交道的人創造的,這些人大多就職於企業的研究所(比如 FORTRAN、PL/1 的發明)、大學(比如 LISP)以及標準委員會(比如 ALGOL、 COBOL)等。也就是說,設計開發編程語言是專業人士的工作,但是這個傳統隨著 20 世紀 70 年代計算機的普及開始發生了變化。一些計算機愛好者在擁有了自己的計算機後,出於興趣開始編程,甚至開始開發新的編程語言。

其中最具有代表性的就是 BASIC 語言。BASIC 語言原本是美國達特茅斯學院用於教學的編程語言,它的語法非常簡單,用極少的代碼實現了最基本的功能,所以深受 20 世紀 70 年代編程愛好者的喜愛,並被他們廣泛使用。

這些編程愛好者也開始開發自己版本的 BASIC 語言。當時,個人計算機① 的內存頂多幾千兆,他們開發的 BASIC 語言就是可以在內存如此之小的機器上工作的小規模版本。這些小規模的 BASIC 程序大小不到 1 KB,它們在 4 KB 左右的內存上也能工作,跟現在需要大內存的語言處理器比起來真是令人驚訝。

① 通常稱為微機。微機是微型計算機、微型機的簡稱。

微機雜誌的時代

以個人開發的 BASIC 為代表的小規模語言(Tiny 語言)處理器不久便以各種各樣的形式進行了發佈。當時的軟件有的以 Dump list 的形式刊登在計算機雜誌上,有的將程序數據進行音頻轉換後收錄在雜誌附帶的薄膜唱片(sonosheet)中發佈。現在的人恐怕已經不知道薄膜唱片了吧。薄膜唱片是指塑料做的薄薄的唱片,不過唱片這個詞幾乎沒有人用了。據說當時的計算機愛好者都用唱片播放器連接計算機來讀取數據,而不使用磁帶錄音機這個最普遍的外部存儲設備。

20 世紀七八十年代是計算機雜誌(當時稱為微機雜誌)的全盛時期,在日本以下 4 種雜誌競爭激烈。

  • RAM (廣濟堂出版)
  • My Computer (電波新聞社)
  • I/O (工學社)
  • ASCII (ASCII 公司)

這 4 種雜誌中現在只有 I/O 仍在發行,不過也大不如前了。作為一個瞭解當時情況的人,我的內心充滿了無限感慨。

這之後,My Computer 雜誌派生出了 My Computer BASIC Magazine,又發生了很多事情,繼續講下去恐怕就會變成上歲數人的敘舊了,所以點到為止吧。如果去問問現在三四十歲的程序員,相信他們中間很多人都會眉飛色舞地講起那個年代的事情。

當時的微機雜誌附帶了收錄 BASIC 的薄膜唱片,除此之外還介紹了其他幾個小規模語言,如 GAME、TL/1 等。這些語言都反映了當時那個時代的特色,非常有趣,我們在本文的最後對其進行了介紹,請大家務必讀一讀。

個人創造編程語言的現狀

為什麼從20 世紀70 年代後期到80 年代前期開始興起個人創造編程語言了呢?我認為最大的原因是當時難以獲取開發環境。

20 世紀70 年代後期廣泛使用的微機是TK-80(圖1)那樣的主板裸露在外的單板機,很多都是半成品,需要自己去釺焊。這樣的機器不可能自帶開發環境之類的東西,軟件都要自己輸入機器語言之後才會工作。

聽Ruby之父這麼說,我也想創造一門新編程語言了

圖1 TK-80

20 世紀70 年代末期才出現PC-8001 和MZ-80 那樣的“成品計算機”。然而,這種計算機頂多帶一個BASIC 開發環境,因此人們很難自由地選擇開發語言。雖說市面上也有商用的語言處理器,但C 編譯器的定價就要19.8萬日元(約等於13.1萬人民幣),這不是普通人可以輕易買得起的。於是,人們便有了熱情去創造一門自己的編程語言。

可現在獲取語言的開發環境已經不再是麻煩事了。各種編程語言和開發環境作為開源軟件被公開,即使是非開源的,也可以輕鬆地通過網絡得到免費版本。

這樣一來,現在自己創造編程語言豈不是沒有任何意義嗎?我認為,這個問題的答案為“否”。即使是現在,自己創造一門新的編程語言也是有意義的,而且有很重要的意義。

而且現在很多廣泛使用的編程語言也都是在開發環境容易獲取的情況下,由個人設計和開發出來的。如果個人開發編程語言真的沒有意義,那麼Ruby、Perl、Python 和Clojure 這些語言也就不會誕生了。

不過即便如此,我認為Java、JavaScript、Erlang 和Haskell 這些語言也可能會以其他形式出現,因為它們會作為業務和研究的一環被開發出來。

為什麼要創造新的編程語言

那麼如今個人設計開發編程語言的動力究竟是什麼呢?

回顧我自身的經歷以及參考其他語言作者的意見,我認為有以下幾點理由。

  • 提高編程能力
  • 提高設計能力
  • 打造個人品牌
  • 獲得自由

首先,編程語言的實現可以說是計算機科學的綜合藝術。作為語言處理器的基礎,詞法分析和語法分析也可以應用在網絡通信的數據協議的實現等方面。

實現語言功能的庫和實現其中的數據結構,這正是計算機科學要做的事情。尤其是編程語言的應用範圍廣泛,很難事先預測會被用於什麼方面,因此庫和數據結構的實現難度也就更大,但也變得更加有意思了。

另外,編程語言還是人與計算機間的接口。設計這樣的接口,就需要深入考察人是如何思考問題的、下意識中有什麼樣的期待。反覆進行這樣的考察,對編程語言之外的應用程序接口(API)設計、用戶界面(UI)設計,甚至用戶體驗(UX)設計都是有益的。

提升個人品牌

也許有人會感到意外,實際上在IT 行業,對編程語言感興趣的人不在少數。這是毋庸置疑的,因為編程與編程語言有著切不斷的關係。以編程語言為主題的活動和會議等往往都會吸引很多人蔘加,由此我們也能感受到編程語言的魅力。正因如此,很多人在網上發現新的語言後就會開始嘗試。就拿Ruby 來說,它在1995 年被髮布到網上之後,僅僅2 周左右就吸引了200 多人加入郵件列表,著實令人驚訝。

可是,雖然有很多人願意嘗試使用新的編程語言,卻幾乎沒有人會去設計並實現一門編程語言,而且是超越雜誌提及的“小兒科語言”那種程度的能夠實用化的編程語言。但我保證,僅憑設計出一個實用的編程語言這一點,你就會得到人們的尊敬。

在這個開源的時代,技術人要想生存下去,在技術社區的存在感是非常重要的。雖然技術人只要開源其軟件就能達到站穩腳跟的效果,但編程語言的“特殊感”會進一步提升其品牌效應。

樂趣第一

另外,編程語言的設計與實現比任何事情都更有趣。的確如此。與計算機科學相關的具有挑戰性的工程也是這樣。設計編程語言還可以幫助使用這門語言的程序員思考,甚至左右他們的想法,這一點也非常有意思。

通常來說,編程語言有一種從別處獲取的、不容侵犯的感覺。如果是自己創造編程語言,就完全沒有這個問題。你可以按照自己的喜好進行設計,如果不滿意或者有更好的想法,也可以自由地修改。從某種意義上來說,這是終極的自由。

編程在某種意義上是對自由的追求。通過親自編程,我們可以獲得單純使用他人的軟件時享受不到的自由。至少對我來說,這是編程的一個重要動機。於我而言,創造編程語言是獲取更高程度自由的手段,也是我的樂趣與快樂的源泉。

為什麼創造新編程語言的人不多

雖說自己創造一門編程語言有這麼多好處,但並不是每個人都會去做。正如上文所說的那樣,對編程語言感興趣的人雖然有一些,但著手去創造編程語言的人幾乎沒有。說是“感興趣的人有一些”,但從佔總人口的比例來看,其實少到可以算作誤差範圍的程度,更不用說有動力去創造新編程語言的人了,就算沒有也不足為奇。

我自己在關注編程語言幾年後就著了迷,但是在進入大學主修計算機科學之後,才注意到並不是所有人都對編程語言感興趣。這是因為我在偏僻的鄉下長大,周圍沒有喜歡編程的人可供比較。

這一點對我來說也不知道是幸還是不幸。

“難道我跟別人不一樣?”意識到這一點的時候,我很震驚。因為當時的微機雜誌上刊登了很多關於TL/1 等編程語言的文章。我本以為對編程感興趣的人(和我一樣)很可能也會對編程語言著迷,但實際上並非如此。

本來就對編程語言不感興趣的人自不用說,即使是感興趣的人,也很難走到自己設計並實現編程語言這一步。

關於這個問題的原因,我思考過很長時間。作為編程語言設計者,在參加編程語言相關的活動時,我也曾以過來人的身份鼓勵別人嘗試一下,但結果總是不盡如人意。當然,萬事開頭難,開始一件新的事情是需要很大勇氣的。但即使是這樣,反響也太差了。

沒必要想得很難

問了很多人之後,我才知道大家為什麼不去著手嘗試了。那是因為就算有興趣創造一門新的編程語言,在開始之前多半也會有某種心理障礙,也就是覺得“編程語言有現成的,本來就不需要自己去設計和開發”。難得有那麼幾個人不會產生這種心理障礙,卻又覺得語言的實現似乎很難。也就是說,他們覺得編程語言很有趣,自己也想做做看,卻不知道如何去實現。

仔細想來,關於編程語言的實現的書雖然出乎意料地出版了很多,但大部分都是大學教材的難度,非常不容易理解。另外,與編譯原理有關的“文法類型”和“Follow 集合”等晦澀的術語也頻繁出現。

但是認真想一想,我們的目的是出於興趣創造自己的編程語言,而不是去掌握編程語言的實現所需的所有知識。如果你認為在沒有完全掌握正確的知識之前就無法著手創造編程語言,那就大錯特錯了,你的熱情會被逐漸消磨殆盡。

成就一番偉大的事業首先需要的就是熱情,不能保持熱情是不行的。一旦有了創造編程語言的熱情,就應儘快開始,以後再根據需要慢慢地掌握所需的知識即可。

這推薦松本行弘新書《松本行弘:編程語言的設計與實現》。

本書主要介紹創造簡單的語言處理器所需要的基本知識以及工具的使用方法,並不涉及編程語言實現的較難部分。相較於理論背景,作者把重點放在瞭如何設計編程語言上。

微機雜誌中介紹的Tiny語言

GAME

GAME(General Algorithmic Micro Expressions)是由BASIC 派生的Tiny語言。它最大的特徵是關鍵字全部是符號,以及所有的語句都是賦值語句。

例如賦值給“?”時會輸出數值,反過來將“?”賦值給變量時會要求輸入數值。字符串的輸入輸出使用“$”。另外,將行號賦給“#”時為goto語句,將行號賦給“!”時為gosub語句(調用子程序)。

另外,像"ABC"這樣的一個字符串語句會打印出字符串,後面有“/”的話會換行。

這是一門非常有意思的編程語言,示例代碼如圖1-A所示。它既像BASIC,又不像BASIC,請大家好好感受一下。

100---------------- Comment -------------------
110| 如果緊接在行號之後的不是空白,則將該行作為註釋
120--------------------------------------------
130
200 / " FOR循環語句 是 變量名=初始值,最終值 ... @=(變量名 + 步長) " /
210 A=1,10
220 ?(6)=A
230 @=(A+1)
240
300 / " IF語句的例子 " /
310 B=1,2
320 ;=B=1 " B=1 " /
330 ;=B=2 " B=2 " /
340 @=(B+1)
350
400 / " 數值輸入與計算 " /
410 "A = ?" A=?
410 "B = ?" B=?
420 "A + B = " ?=A " + " ?=B " = " ?=A+B /
430 "A * B = " ?=A " * " ?=B " = " ?=A*B /
440
500 / " 數組與字符輸出 " /
505--------令數組的地址為$1000
510 D=$1000
520 C=0,69
525--------作為2字節數組寫入
530 D(C)=(C+$20)*256+C+$20
540 @=(C+1)
560 C=0,139
570--------作為1字節數組讀取,並輸出為字符
580 $=D:C)
590 @=(C+1)
600
700 / " GOTO 與 GOSUB " /
710 I=1
720 I=I+1
730 !=1000
731* ?(8)=I*I
740 ;=I=10 #=760
750 #=720
760
900 / "程序結束 " /
910 #=-1
920
1000 / " 子程序 " /
1010 ?(8)=I*I
1020 ]

圖1-A GAME 語言的示例代碼

GAME是一門非常簡潔的語言,用8080彙編語言編寫的解釋器的大小還不到1 KB。另外,由中島聰(當時居然還是高中生)開發的使用GAME編寫的GAME編譯器,代碼僅有200行左右。真不知道我們應該驚歎GAME 的語言表現能力,還是中島聰的技術能力。

TL/1

同一時期在ASCII 雜誌上發表的Tiny語言中還有TL/1(Tiny Language/1),它的名字應該是模仿了美國IBM公司開發的編程語言PL/1。與受BASIC影響使用符號的GAME語言不同,TL/1擁有類似於Pascal的語法,讓人覺得更加“正常”。另外,TL/1的語言處理器是編譯型的,與主體為解釋型的GAME比起來速度更快。但實際上GAME也有編譯器,這一點我們在文中介紹過。

TL/1的特徵是語法類似於Pascal,以及變量類型只有1字節的整數。各位讀者也許會想這樣怎麼編寫代碼,不過當時的主流CPU是8位的,所以TL/1設計成這樣也不是很怪異。雖說是運行在8位CPU 上,但包括GAME 在內的其他語言都提供了16位的整數類型。

那麼1 字節無法表示的超過255 的數值該如何編寫呢?答案是按字節進行分割,用多個變量組合表示。比如用2 個變量保存16 位整數,邊看計算溢出時的進位標誌邊計算(圖1-Ba)。在當時的8位CPU上,大部分處理用16位整數就已經足夠了(地址用16位的話就可以訪問所有地址空間)。作為Tiny語言,這樣的功能已經足夠了。各位讀者如果有興趣,可以顯式地查看進位標誌,使用多個變量進行24位計算或32位計算。

% (a)
% 以"%"開始的行是註釋,當時不能使用日語
BEGIN
A := 255
B := A + 2 % overflow
C := 0 ADC 0 % add with carry
END
% (b)
BEGIN
WRITE(0: "hello, world", CRLF)
END

圖1-B TL/1 語言的示例代碼

可以處理指針和字符串

另外,指針也無法僅用1字節來表示。這裡用mem數組進行訪問,也就是說,用下面表達式中hi,lo表示的16位地址來訪問指定地址的內容。

mem(hi, lo)

下面是將地址的值替換為v。

mem(hi, lo) = v

當時的個人計算機(微機)最多隻有32 KB 的內存,所以能用16 位地址訪問就已經足夠了。還有就是字符串。當然,我們也可以將字符串當作字節數組,對每個字節依次進行操作,但是這樣處理太麻煩,因此TL/1設計了用於數據輸出的WRITE語句。

例如,用TL/1開發的Hello World程序如圖1-Bb所示。TL/1中變量本應只有1字節的整數,卻出現了字符串。實際上,WRITE是為了能夠處理字符串而單獨增加的語法。

WRITE之外的語句是無法處理字符串的,所以不能進行普通的字符串處理,只能夠操作1字節的整數。現在看來可能會覺得很不可思議,但是在不屬於Tiny語言的Pascal和FORTRAN中,輸入輸出也是被特殊處理的,這在當時也許是一種比較普遍的做法。

——本文內容來源《松本行弘:編程語言的設計與實現》。

"
聽Ruby之父這麼說,我也想創造一門新編程語言了

本文作者:Ruby之父松本行弘。

大家有過創造編程語言的經歷嗎?我想大多數人會回答沒有。

對於有編程經歷的人來說,編程語言是非常親切的存在,我們習慣了接受現成的編程語言,可能沒有想過要自己去創造一門新的編程語言。這也是情理之中的事情。

但其實我們大家都知道,世界上所有的編程語言都是由某個地方的某個人創造的。它們不是自然產生的,而是根據明確的意圖和目的被設計並實現的。如果過去沒有這些創造編程語言的人(編程語言的作者),可能我們今天還在用匯編語言編程吧。

其實,創造編程語言不僅可以提升我們作為技術者的價值,而且還可以使我們從中獲得很大的樂趣。而且隨著開源的普及,創造新編程語言的門檻一下子降低了許多。通過實際創造一門新的編程語言,我們可以學到編程語言的設計思路和實現方法。

可能有的讀者會想:“現在再創造編程語言還有什麼意義呢 ?”我們稍後回答這個問題,現在我們先來看一下編程語言的歷史。

在人們剛開始編程時,編程語言就隨之出現了,可以說編程的歷史就是編程語言的歷史。

個人創造編程語言的歷史

早期的編程語言是由在工作中切切實實與編程語言打交道的人創造的,這些人大多就職於企業的研究所(比如 FORTRAN、PL/1 的發明)、大學(比如 LISP)以及標準委員會(比如 ALGOL、 COBOL)等。也就是說,設計開發編程語言是專業人士的工作,但是這個傳統隨著 20 世紀 70 年代計算機的普及開始發生了變化。一些計算機愛好者在擁有了自己的計算機後,出於興趣開始編程,甚至開始開發新的編程語言。

其中最具有代表性的就是 BASIC 語言。BASIC 語言原本是美國達特茅斯學院用於教學的編程語言,它的語法非常簡單,用極少的代碼實現了最基本的功能,所以深受 20 世紀 70 年代編程愛好者的喜愛,並被他們廣泛使用。

這些編程愛好者也開始開發自己版本的 BASIC 語言。當時,個人計算機① 的內存頂多幾千兆,他們開發的 BASIC 語言就是可以在內存如此之小的機器上工作的小規模版本。這些小規模的 BASIC 程序大小不到 1 KB,它們在 4 KB 左右的內存上也能工作,跟現在需要大內存的語言處理器比起來真是令人驚訝。

① 通常稱為微機。微機是微型計算機、微型機的簡稱。

微機雜誌的時代

以個人開發的 BASIC 為代表的小規模語言(Tiny 語言)處理器不久便以各種各樣的形式進行了發佈。當時的軟件有的以 Dump list 的形式刊登在計算機雜誌上,有的將程序數據進行音頻轉換後收錄在雜誌附帶的薄膜唱片(sonosheet)中發佈。現在的人恐怕已經不知道薄膜唱片了吧。薄膜唱片是指塑料做的薄薄的唱片,不過唱片這個詞幾乎沒有人用了。據說當時的計算機愛好者都用唱片播放器連接計算機來讀取數據,而不使用磁帶錄音機這個最普遍的外部存儲設備。

20 世紀七八十年代是計算機雜誌(當時稱為微機雜誌)的全盛時期,在日本以下 4 種雜誌競爭激烈。

  • RAM (廣濟堂出版)
  • My Computer (電波新聞社)
  • I/O (工學社)
  • ASCII (ASCII 公司)

這 4 種雜誌中現在只有 I/O 仍在發行,不過也大不如前了。作為一個瞭解當時情況的人,我的內心充滿了無限感慨。

這之後,My Computer 雜誌派生出了 My Computer BASIC Magazine,又發生了很多事情,繼續講下去恐怕就會變成上歲數人的敘舊了,所以點到為止吧。如果去問問現在三四十歲的程序員,相信他們中間很多人都會眉飛色舞地講起那個年代的事情。

當時的微機雜誌附帶了收錄 BASIC 的薄膜唱片,除此之外還介紹了其他幾個小規模語言,如 GAME、TL/1 等。這些語言都反映了當時那個時代的特色,非常有趣,我們在本文的最後對其進行了介紹,請大家務必讀一讀。

個人創造編程語言的現狀

為什麼從20 世紀70 年代後期到80 年代前期開始興起個人創造編程語言了呢?我認為最大的原因是當時難以獲取開發環境。

20 世紀70 年代後期廣泛使用的微機是TK-80(圖1)那樣的主板裸露在外的單板機,很多都是半成品,需要自己去釺焊。這樣的機器不可能自帶開發環境之類的東西,軟件都要自己輸入機器語言之後才會工作。

聽Ruby之父這麼說,我也想創造一門新編程語言了

圖1 TK-80

20 世紀70 年代末期才出現PC-8001 和MZ-80 那樣的“成品計算機”。然而,這種計算機頂多帶一個BASIC 開發環境,因此人們很難自由地選擇開發語言。雖說市面上也有商用的語言處理器,但C 編譯器的定價就要19.8萬日元(約等於13.1萬人民幣),這不是普通人可以輕易買得起的。於是,人們便有了熱情去創造一門自己的編程語言。

可現在獲取語言的開發環境已經不再是麻煩事了。各種編程語言和開發環境作為開源軟件被公開,即使是非開源的,也可以輕鬆地通過網絡得到免費版本。

這樣一來,現在自己創造編程語言豈不是沒有任何意義嗎?我認為,這個問題的答案為“否”。即使是現在,自己創造一門新的編程語言也是有意義的,而且有很重要的意義。

而且現在很多廣泛使用的編程語言也都是在開發環境容易獲取的情況下,由個人設計和開發出來的。如果個人開發編程語言真的沒有意義,那麼Ruby、Perl、Python 和Clojure 這些語言也就不會誕生了。

不過即便如此,我認為Java、JavaScript、Erlang 和Haskell 這些語言也可能會以其他形式出現,因為它們會作為業務和研究的一環被開發出來。

為什麼要創造新的編程語言

那麼如今個人設計開發編程語言的動力究竟是什麼呢?

回顧我自身的經歷以及參考其他語言作者的意見,我認為有以下幾點理由。

  • 提高編程能力
  • 提高設計能力
  • 打造個人品牌
  • 獲得自由

首先,編程語言的實現可以說是計算機科學的綜合藝術。作為語言處理器的基礎,詞法分析和語法分析也可以應用在網絡通信的數據協議的實現等方面。

實現語言功能的庫和實現其中的數據結構,這正是計算機科學要做的事情。尤其是編程語言的應用範圍廣泛,很難事先預測會被用於什麼方面,因此庫和數據結構的實現難度也就更大,但也變得更加有意思了。

另外,編程語言還是人與計算機間的接口。設計這樣的接口,就需要深入考察人是如何思考問題的、下意識中有什麼樣的期待。反覆進行這樣的考察,對編程語言之外的應用程序接口(API)設計、用戶界面(UI)設計,甚至用戶體驗(UX)設計都是有益的。

提升個人品牌

也許有人會感到意外,實際上在IT 行業,對編程語言感興趣的人不在少數。這是毋庸置疑的,因為編程與編程語言有著切不斷的關係。以編程語言為主題的活動和會議等往往都會吸引很多人蔘加,由此我們也能感受到編程語言的魅力。正因如此,很多人在網上發現新的語言後就會開始嘗試。就拿Ruby 來說,它在1995 年被髮布到網上之後,僅僅2 周左右就吸引了200 多人加入郵件列表,著實令人驚訝。

可是,雖然有很多人願意嘗試使用新的編程語言,卻幾乎沒有人會去設計並實現一門編程語言,而且是超越雜誌提及的“小兒科語言”那種程度的能夠實用化的編程語言。但我保證,僅憑設計出一個實用的編程語言這一點,你就會得到人們的尊敬。

在這個開源的時代,技術人要想生存下去,在技術社區的存在感是非常重要的。雖然技術人只要開源其軟件就能達到站穩腳跟的效果,但編程語言的“特殊感”會進一步提升其品牌效應。

樂趣第一

另外,編程語言的設計與實現比任何事情都更有趣。的確如此。與計算機科學相關的具有挑戰性的工程也是這樣。設計編程語言還可以幫助使用這門語言的程序員思考,甚至左右他們的想法,這一點也非常有意思。

通常來說,編程語言有一種從別處獲取的、不容侵犯的感覺。如果是自己創造編程語言,就完全沒有這個問題。你可以按照自己的喜好進行設計,如果不滿意或者有更好的想法,也可以自由地修改。從某種意義上來說,這是終極的自由。

編程在某種意義上是對自由的追求。通過親自編程,我們可以獲得單純使用他人的軟件時享受不到的自由。至少對我來說,這是編程的一個重要動機。於我而言,創造編程語言是獲取更高程度自由的手段,也是我的樂趣與快樂的源泉。

為什麼創造新編程語言的人不多

雖說自己創造一門編程語言有這麼多好處,但並不是每個人都會去做。正如上文所說的那樣,對編程語言感興趣的人雖然有一些,但著手去創造編程語言的人幾乎沒有。說是“感興趣的人有一些”,但從佔總人口的比例來看,其實少到可以算作誤差範圍的程度,更不用說有動力去創造新編程語言的人了,就算沒有也不足為奇。

我自己在關注編程語言幾年後就著了迷,但是在進入大學主修計算機科學之後,才注意到並不是所有人都對編程語言感興趣。這是因為我在偏僻的鄉下長大,周圍沒有喜歡編程的人可供比較。

這一點對我來說也不知道是幸還是不幸。

“難道我跟別人不一樣?”意識到這一點的時候,我很震驚。因為當時的微機雜誌上刊登了很多關於TL/1 等編程語言的文章。我本以為對編程感興趣的人(和我一樣)很可能也會對編程語言著迷,但實際上並非如此。

本來就對編程語言不感興趣的人自不用說,即使是感興趣的人,也很難走到自己設計並實現編程語言這一步。

關於這個問題的原因,我思考過很長時間。作為編程語言設計者,在參加編程語言相關的活動時,我也曾以過來人的身份鼓勵別人嘗試一下,但結果總是不盡如人意。當然,萬事開頭難,開始一件新的事情是需要很大勇氣的。但即使是這樣,反響也太差了。

沒必要想得很難

問了很多人之後,我才知道大家為什麼不去著手嘗試了。那是因為就算有興趣創造一門新的編程語言,在開始之前多半也會有某種心理障礙,也就是覺得“編程語言有現成的,本來就不需要自己去設計和開發”。難得有那麼幾個人不會產生這種心理障礙,卻又覺得語言的實現似乎很難。也就是說,他們覺得編程語言很有趣,自己也想做做看,卻不知道如何去實現。

仔細想來,關於編程語言的實現的書雖然出乎意料地出版了很多,但大部分都是大學教材的難度,非常不容易理解。另外,與編譯原理有關的“文法類型”和“Follow 集合”等晦澀的術語也頻繁出現。

但是認真想一想,我們的目的是出於興趣創造自己的編程語言,而不是去掌握編程語言的實現所需的所有知識。如果你認為在沒有完全掌握正確的知識之前就無法著手創造編程語言,那就大錯特錯了,你的熱情會被逐漸消磨殆盡。

成就一番偉大的事業首先需要的就是熱情,不能保持熱情是不行的。一旦有了創造編程語言的熱情,就應儘快開始,以後再根據需要慢慢地掌握所需的知識即可。

這推薦松本行弘新書《松本行弘:編程語言的設計與實現》。

本書主要介紹創造簡單的語言處理器所需要的基本知識以及工具的使用方法,並不涉及編程語言實現的較難部分。相較於理論背景,作者把重點放在瞭如何設計編程語言上。

微機雜誌中介紹的Tiny語言

GAME

GAME(General Algorithmic Micro Expressions)是由BASIC 派生的Tiny語言。它最大的特徵是關鍵字全部是符號,以及所有的語句都是賦值語句。

例如賦值給“?”時會輸出數值,反過來將“?”賦值給變量時會要求輸入數值。字符串的輸入輸出使用“$”。另外,將行號賦給“#”時為goto語句,將行號賦給“!”時為gosub語句(調用子程序)。

另外,像"ABC"這樣的一個字符串語句會打印出字符串,後面有“/”的話會換行。

這是一門非常有意思的編程語言,示例代碼如圖1-A所示。它既像BASIC,又不像BASIC,請大家好好感受一下。

100---------------- Comment -------------------
110| 如果緊接在行號之後的不是空白,則將該行作為註釋
120--------------------------------------------
130
200 / " FOR循環語句 是 變量名=初始值,最終值 ... @=(變量名 + 步長) " /
210 A=1,10
220 ?(6)=A
230 @=(A+1)
240
300 / " IF語句的例子 " /
310 B=1,2
320 ;=B=1 " B=1 " /
330 ;=B=2 " B=2 " /
340 @=(B+1)
350
400 / " 數值輸入與計算 " /
410 "A = ?" A=?
410 "B = ?" B=?
420 "A + B = " ?=A " + " ?=B " = " ?=A+B /
430 "A * B = " ?=A " * " ?=B " = " ?=A*B /
440
500 / " 數組與字符輸出 " /
505--------令數組的地址為$1000
510 D=$1000
520 C=0,69
525--------作為2字節數組寫入
530 D(C)=(C+$20)*256+C+$20
540 @=(C+1)
560 C=0,139
570--------作為1字節數組讀取,並輸出為字符
580 $=D:C)
590 @=(C+1)
600
700 / " GOTO 與 GOSUB " /
710 I=1
720 I=I+1
730 !=1000
731* ?(8)=I*I
740 ;=I=10 #=760
750 #=720
760
900 / "程序結束 " /
910 #=-1
920
1000 / " 子程序 " /
1010 ?(8)=I*I
1020 ]

圖1-A GAME 語言的示例代碼

GAME是一門非常簡潔的語言,用8080彙編語言編寫的解釋器的大小還不到1 KB。另外,由中島聰(當時居然還是高中生)開發的使用GAME編寫的GAME編譯器,代碼僅有200行左右。真不知道我們應該驚歎GAME 的語言表現能力,還是中島聰的技術能力。

TL/1

同一時期在ASCII 雜誌上發表的Tiny語言中還有TL/1(Tiny Language/1),它的名字應該是模仿了美國IBM公司開發的編程語言PL/1。與受BASIC影響使用符號的GAME語言不同,TL/1擁有類似於Pascal的語法,讓人覺得更加“正常”。另外,TL/1的語言處理器是編譯型的,與主體為解釋型的GAME比起來速度更快。但實際上GAME也有編譯器,這一點我們在文中介紹過。

TL/1的特徵是語法類似於Pascal,以及變量類型只有1字節的整數。各位讀者也許會想這樣怎麼編寫代碼,不過當時的主流CPU是8位的,所以TL/1設計成這樣也不是很怪異。雖說是運行在8位CPU 上,但包括GAME 在內的其他語言都提供了16位的整數類型。

那麼1 字節無法表示的超過255 的數值該如何編寫呢?答案是按字節進行分割,用多個變量組合表示。比如用2 個變量保存16 位整數,邊看計算溢出時的進位標誌邊計算(圖1-Ba)。在當時的8位CPU上,大部分處理用16位整數就已經足夠了(地址用16位的話就可以訪問所有地址空間)。作為Tiny語言,這樣的功能已經足夠了。各位讀者如果有興趣,可以顯式地查看進位標誌,使用多個變量進行24位計算或32位計算。

% (a)
% 以"%"開始的行是註釋,當時不能使用日語
BEGIN
A := 255
B := A + 2 % overflow
C := 0 ADC 0 % add with carry
END
% (b)
BEGIN
WRITE(0: "hello, world", CRLF)
END

圖1-B TL/1 語言的示例代碼

可以處理指針和字符串

另外,指針也無法僅用1字節來表示。這裡用mem數組進行訪問,也就是說,用下面表達式中hi,lo表示的16位地址來訪問指定地址的內容。

mem(hi, lo)

下面是將地址的值替換為v。

mem(hi, lo) = v

當時的個人計算機(微機)最多隻有32 KB 的內存,所以能用16 位地址訪問就已經足夠了。還有就是字符串。當然,我們也可以將字符串當作字節數組,對每個字節依次進行操作,但是這樣處理太麻煩,因此TL/1設計了用於數據輸出的WRITE語句。

例如,用TL/1開發的Hello World程序如圖1-Bb所示。TL/1中變量本應只有1字節的整數,卻出現了字符串。實際上,WRITE是為了能夠處理字符串而單獨增加的語法。

WRITE之外的語句是無法處理字符串的,所以不能進行普通的字符串處理,只能夠操作1字節的整數。現在看來可能會覺得很不可思議,但是在不屬於Tiny語言的Pascal和FORTRAN中,輸入輸出也是被特殊處理的,這在當時也許是一種比較普遍的做法。

——本文內容來源《松本行弘:編程語言的設計與實現》。

聽Ruby之父這麼說,我也想創造一門新編程語言了

為什麼要創建一門新語言?新語言開發中會遇到什麼困難?

C、Java、Python等語言的設計為什麼是現在這樣?

什麼樣的語法不會給使用者造成負擔?

Ruby 之父松本行弘全面披露新語言開發的整個過程,以新語言Streem 的設計與實現過程為例,作者從設計新語言的動機開始講起,由淺入深,詳細介紹了新語言開發中的各個環節,以及語言設計上的糾結與取捨,其中也不乏對其他編程語言的調查與思考,向我們展示了創建編程語言的樂趣。

"

相關推薦

推薦中...