彭民德:《電子計算60年》 (13) 程式語言曾被人無端稱作計算機語言

彭民德發表於2016-07-13

高階程式語言引進到我國來,在推廣中往往被稱作高階語言,因為相對於以往的機器語言和組合語言,高階很多。或者也叫演算法語言,因為用它們比較容易描述演算法。但也有個別學者不沿用國內外既有稱謂,偏偏要另起名字,把它們叫做計算機語言。這一提法最早見於上世紀80年代譚浩強先生的《BASIC語言》前言:“BASIC語言是當前國內外廣泛使用的、適合於初學者的一種計算機語言。”(譚浩強:《BASIC語言》,北京科學普及出版社,1986.8)。在其90年代寫的《C程式設計》一書前言又以“C語言是在國內外廣泛使用的一種計算機語言”開篇(譚浩強:《C程式設計》(第二版),清華大學出版社,1999.12)。他沒有對“計算機語言”加以定義,就直接把BASIC、C語言等叫做計算機語言。C++出來後,譚先生也沒有放過,他說:“近年來,有一些物件導向的計算機語言陸續問世,受到歡迎。”(譚浩強:《C程式設計》(第三版),清華大學出版社,2009年5月)於是流行的幾種程式設計語言,就都被他無端地叫計算機語言了。

如果宣告只是作為同義語,你們叫紅薯,我叫白薯,把計算機語言當作程式設計語言的等價詞倒也罷了。問題是不加說明地就把他們轉意為計算機語言,概念上便產生了混亂。其實程式語言和計算機語言是兩個不同屬性的詞,不具備互換性。前者屬於程式設計師,是程式設計師專用於編制程式的一種語言,語言規範是對程式設計師的指導和約束;後者應該屬於計算機,是計算機用來表意的語言。程式語言的屬性在人,不在計算機一方,不能直接叫做計算機語言。就如同口技者學鳥叫,雖然跟鳥有關,學得再好也只是人對鳥語的一種模仿,不能直接叫鳥語。一樣的道理,不能夠把屬於人用來寫程式的一種語言,改變其屬性直接賦予計算機。

譚先生把BASIC、C等程式語言叫做計算機語言,把一個本來已經很清楚的概念,加在一個連自己都沒有清晰界定的另一個概念上。因為其教材發行量大,影響了很多人,跟著他把程式語言叫做計算機語言,並賦予它們程式語言所不具備,只能是計算機語言應有之意,比如賦予它們控制計算機微觀動作的功能。導致在我國許多人概念混淆,認為程式語言不但可以程式設計序,更具備了計算機表意功能。而計算機的這種高階功能,不但早期計算機不具備,即便功能已經極大地增長了的當下的通用計算機,也還不具備。

好幾年前到國家圖書館網站,用“計算機語言”做文津檢索,發現已經有許多人跟著譚先生用計算機語言一詞。在僅限於“圖書”範圍,就有440個匹配項。在也包括論文、期刊報紙、文件、詞條等“全部”8個方面,有多達3900個匹配項,其中不少解釋都把機器語言、組合語言、BASIC等程式語言當作“計算機語言”。還撇開它們用於寫程式的基本面,牽強地賦予它們表達人們控制計算機微觀動作的功能,引出一些有違計算機領域常識的解釋。現在也依然在一些場合被混淆起來使用。

筆者認為,從專業角度,不應把程式語言叫計算機語言,直到目前的通用計算機,都還不具備語言能力。曾經於2013年5月在中國計算機學會的網站上寫了“慎用計算機語言一詞”(http://www.ccf.org.cn/sites/ccf/xhdtnry.jsp?contentId=2738335730369),2014年9月又在《計算機學會通訊》雜誌上寫了類似的文章:把程式語言稱作“計算機語言”之惑(《中國計算機學會通訊》2014年9月)。無奈人輕言微,被提及者並不理睬,在此重申我的觀點。因混淆者眾,現就知名的、影響較廣的一個查詢網站和一本詞典中,把程式語言當做計算機語言,並做不準確的詞義解釋再做些討論。從他們的解釋經不起推敲,就可以確信把程式語言叫做計算機語言不恰當。我認為在當今大家都忙於追趕新技術的同時,也有必要展開對一些基本概念的討論,以求得到清晰的認識。這種討論其實涉及計算機的基本特徵是什麼,計算機的微觀世界是否可控,程式設計語言能否控制計算機,把程式語言稱作計算機語言是否科學等多個方面問題。

(一) 就“百度”網站把程式語言叫做“計算機語言”的討論
百科名片(http://baike.baidu.com/view/246483.htm)

計算機語言(Computer Language)指用於人與計算機之間通訊的語言。計算機語言是人與計算機之間傳遞資訊的媒介。計算機系統最大特徵是指令通過一種語言傳達給機器。為了使電子計算機進行各種工作,就需要有一套用以編寫計算機程式的數字、字元和語法規劃,由這些字元和語法規則組成計算機各種指令(或各種語句)。這些就是計算機能接受的語言。
又說:
計算機語言的種類非常的多,總的來說可以分成機器語言 ,組合語言,高階語言三大類。

  1. 現代計算機是那麼一個場所,通電後機器啟動了,以作業系統為代表的多個程式併發地執行起來了。整個計算機,包括接通了電的外設,都忙起來了。可以用C或者BASIC等再寫新的程式,讓計算機實現你的程式功能,幫你做事。也可以不程式設計序,甚至C和BASIC都不配置。在需要跟計算機(以作業系統為代表)或者某個應用程式交換資訊的時候,在作業系統和應用程式的人機介面上用鍵盤、滑鼠等輸入裝置向計算機傳遞資訊。當今採用馮•諾依曼體系結構的機器,輸入裝置是人向計算機傳遞資訊的媒介。何以一定要經C、BASIC等程式語言作為“人與計算機之間傳遞資訊的媒介”,才能“與計算機之間通訊”呢? 再說,程式語言環境的輸入語句(比如C語言的scanf語句)也必須藉助輸入裝置才能夠實現。很多人都有體驗,在Windows環境下,需要接收鍵盤輸入的程式是某個特定的程式,還要在它有輸入焦點時輸入才能夠進行,這說明任何輸入都無法繞開作業系統和輸入裝置,程式語言無法單獨擔負“人與計算機之間傳遞資訊的媒介”。而且scanf語句實現的是人與所寫的那個程式之間的通訊,跟其它程式無關。把跟自己的一個程式的通訊說成是與整個計算機之間的通訊也不準確。

2.什麼是計算機的最大特徵計算機的基本特徵是儲存並自動地執行程式,跟過去的電子計算裝置相比,現代計算機被叫做儲存程式式計算機。計算機的特徵不是“指令通過一種語言傳達給機器”

指令在執行前駐留記憶體也不通過程式語言,在第一二代計算機上指令序列駐留記憶體的區域由人工分配,用傳送指令將程式從紙帶機上送入計算機記憶體。在當代計算機上,作為指令序列的程式駐留在何處,由作業系統決定調入,可能還要虛擬儲存,外界不知道駐留何處。沒有根據講“指令通過一種語言傳達給機器”

3.指令不能被分解為字元和語法規則。計算機指令是計算機能夠執行的最基本的操作,每條指令都是0與1的位串,不但在程式中書寫不能被分割,執行時也是不可被分割的,它已經是最小的書寫和執行單位了。怎麼能夠把指令分解,說由“字元和語法規則組成計算機各種指令”呢?

4.說由字元組成指令顛倒了時間順序。從時間順序上說,計算機上指令的概念先於字元概念。早期計算機就有指令,但是沒有字元概念。既然沒有字元,何以由字元組成指令?所以沒有理由講“由字元和語法規則組成計算機各種指令”
5. 既然所指的計算機語言實際上就是指計算機的機器語言、組合語言、高階語言這些程式設計語言,並沒有創造出新語言。這些都已經被發明者和整個計算機界統稱作程式設計語言了,而且這樣稱謂很準確,因為它們都是寫給程式設計師編制程式用的。相比之下,講它們是“計算機語言”,反而掩蓋了這些語言用於編寫程式的基本特徵,含義變得模糊了

電腦每做的一次動作,一個步驟,都是按照已經用計算機語言編好的程式來執行,程式是計算機要執行的指令的集合,而程式全部都是用我們所掌握的語言來編寫的。所以人們要控制計算機一定要通過計算機語言向計算機發出命令。
6. 在每秒執行百億條以上指令的現代計算機,包括個人機上,什麼是“電腦每做的一次動作,一個步驟”?某個儲存地址的值增1也許就需要多個元器件的狀態翻轉,每條指令的執行更需要多個步驟,多個動作。每條指令的執行都包含一系列的動作過程:依據指令暫存器所指的指令地址,把指令從記憶體送到控制器;控制器分析指令,發出從哪個記憶體單元取數和進行哪種基本操作的訊號;運算器接受訊號,對該數進行運算;控制器發出訊號,把運算結果送到應送達的單元;機器再依據指令暫存器中下一條指令地址,準備轉入執行下一條指令。而且執行每條指令的一組硬體動作還是不可被分割的。那麼電腦執行的微觀世界怎麼樣劃分為其每一個動作?又怎麼可以“控制電腦每做的一次動作”呢?

正像微觀的物理世界測不準,無法控制那樣,計算機的微觀世界也是測不準,不可控的。我們自己編寫的程式只能從功能上獲得期待的結果,這也就夠了。比如把一批資料排序,求解一個方程組,甚至可以讓電腦執行程式控制某個工業過程。但我們寫程式無法控制電腦的每個動作,也不必如此期待。為了計算機能夠正常執行,作業系統總要按其策略,不斷地檢查硬體,維護系統和資料的一致性,總在自主地執行。系統執行不受外界干預,使用者只能通過作業系統提供的使用介面和程式設計介面跟系統打交道。比如螢幕上游標在閃爍,表徵硬碟在工作的指示燈在閃爍等等,都是作業系統自主執行時電腦的動作,它們不是我們寫的程式所能控制的。我們也無法控制自己的程式執行時周圍有什麼別的程式執行,無法控制自己的程式執行時,系統中一定會發生一些什麼事件。一個程式啟動執行後,CPU此刻是否在執行這個程式中的指令等等都是無法確定的。怎麼能講程式語言(你的計算機語言)控制了計算機?

所以講要程式語言控制計算機”,以及“通過計算機語言向計算機發出命令”實在勉為其難

7.詞條作者寫道“為了使計算機…工作,就需要有一套用以編寫計算機程式的…計算機…語言”,“所以人們要控制計算機一定要通過計算機語言向計算機發出命令”

這種觀點有明顯的毛病。一是控制計算機的提法欠妥,我們剛才已經講過,不能控制計算機,程式語言也做不到。一般地,只是利用它,買計算機都是以應用驅動的,用來上網,處理照片,玩遊戲等,不是為了控制計算機。二是高估了程式語言的程式設計功能。實際上要寫程式,光有程式文字還不行,不要誇大程式文字的作用。起關鍵作用的是人。高階程式語言只是指導人們寫程式的規範,比如告訴你程式中的變數應該是什麼樣的,提供哪些型別的語句,每一種語句有什麼功能和格式。並不限定程式設計師怎麼寫具體的變數,不限定他在程式中用哪種語句。每種程式語言的規範文字都是寫給人看的。語言文字中並沒有像自然語言那樣供人們直接取用的“你好,吃了嗎?”之類有特定語義的範文,不規定具體的變數和具體的語句,每個變數和語句都得由程式設計師在程式中去確定。既然程式語言是一套規範,就好比球賽的規則,規則不是對球員的命令。講“通過計算機語言向計算機發出命令”就好比講通過球賽規則向球員發出命令一樣不能成立。語言規範不但不能控制計算機,也無法控制程式設計師的行為,它給程式設計師留有很大的發揮空間。運用程式語言,各人都可以寫出很不相同的程式。
8. 如果說啟動一個程式執行,也是在對計算機發命令,是對計算機的一種控制的話(當然只是命令計算機執行一個程式,不是對計算機每個動作的控制),程式語言本身不能等同於程式的執行,也不能等同於就有了源程式。僅有程式語言寫不出程式。程式設計師寫程式還得組織資料結構,選擇合理的演算法,即便寫一個簡單程式也得這樣。比如求n!=1×2×3×···×n,程式至少有兩種不同寫法,一種是直接用迴圈語句,做n-1次連乘實現。另一種方法是,在編譯程式支援的前提下,用遞迴實現。究竟用哪種演算法,定義什麼變數和資料結構,採用哪種迴圈的控制流結構,程式語言並不限定,都得由程式設計師確定。

每個有一定功能的程式都包含演算法,解決複雜問題需要組織更復雜的資料結構,設計更復雜的演算法。每種程式設計語言只是提供程式設計師把演算法適當地表示出來,讓後續的編譯程式能夠理解和進一步加工。語言本身一般並不包含演算法(只以標準子程式的方式提供一部分演算法)。

程式設計人員還得掌握各個層級的程式開發環境,合理地使用系統資源。比如作業系統級有大量的系統呼叫或者API函式,多媒體和網路中介軟體開發商也提供了相應的程式開發介面。不掌握它們就無法與時俱進地做程式開發。

可見沒有一定的計算機演算法和資料結構素養,不熟悉計算機系統程式開發環境的程式設計師尚且寫不出有用的程式,程式語言本身又哪裡來的那麼大本事呢?

(二) 一本大部頭的現代科學技術知識詞典(王濟昌:《現代科學技術知識詞典》,中國科技出版社,2011年10月),既正確地認可“程式設計語言”“一組用來定義的語法規則”,在同一本書裡又把同一個物件賦予“計算機語言”新稱謂和不同的詞義解釋,讓人無所適從。它對計算機語言作如下定義。
【計算機語言】( computer language)能完整、準確和規則地表達人們的意圖並用以指揮或控制計算機工作的符號系統。用於人與計算機之間的通訊,是人與計算機之間傳遞資訊的媒介。其發展經歷了從機器語言、組合語言到高階語言的歷程。機器語言是用二進位制程式碼表示的、計算機能直接識別和執行的一種機器指令的集合。它是計算機的設計者通過計算機的硬體結構賦予計算機的操作功能,具有靈活、直接執行和速度快等特點。組合語言是一種用助記符表示的仍然面向機器的計算機語言。其特點是:不僅用符號代替了機器指令程式碼,而且助記符與指令程式碼一一對應,基本保留了機器語言的靈活性。高階語言是指與自然語言相近併為計算機所接受和執行的計算機語言。

上述定義值得商榷
1. 這裡定義的計算機語言一詞所包含的內容,是從機器語言、組合語言發展到高階語言,因此現在它就是指高階程式語言。計算機業界多年來已經準確地稱之為高階程式設計語言、演算法語言,要賦予新的稱謂和新的內涵,就得指出原有解釋的不足,但是他無法指出程式設計語言稱謂有任何瑕疵。
2. 這裡把計算機語言定義為“能完整、準確和規則地”指揮控制計算機工作的符號系統。也許未來的計算機語言具備這種屬性,變得越來越人性化。但是此前的程式語言還是以機器為中心的,程式設計還停留在專業層面。而且靠一套符號系統就能夠完整、準確和規則地表達人們的意圖嗎?聰明的人用幾千年傳承發展的自然語言尚且難以做到。試讀一讀網上流傳的關於“意思”、“方便”等漢語的語言幽默就知道,同一個單詞在不同場合可能有多種不同的詞義。可見用自然語言想完整、準確地表達人們的意圖尚且不容易。在計算機面前,怎麼可以用一套符號系統就能完整、準確地表達人們的意圖?而且人們的意圖在計算機環境下表達又還必定受到軟硬體發展水平的制約。比如在計算機早期沒有字元概念,就不能寫高階語言程式,不能寫詩寫文章。後來可以寫文件了,但沒有圖形終端,就不能畫表格線,做圖表處理。只有機器發展到多媒體階段,才能處理圖形影像。到了網路時代才能看電視。計算機的發展雖然很喜人,但是目前的智慧還聽不懂人話。任何人都不可能超越計算機發展水平推出一種萬能地表達人的意願的符號語言,“程式語言”也不具備這種功能。而程式設計語言的稱謂,功能卻簡單明瞭,它就是幫助人們編制程式的。
3. 講“機器指令的集合。是計算機的設計者...賦予計算機的操作功能”,至少是一種誤解。機器指令系統也是寫給程式設計人員程式設計使用,也是程式設計用的語言,而不是直接“賦予計算機的。每臺計算機的指令集當中,除了個別語句不需要運算元,比如停機指令,可以被程式設計師直接寫到程式中,這種指令可以類比於自然語言中“停機”那樣有語義被直接使用,作為要向計算機發的命令。這條指令到了多使用者多工架構時代也不向使用者提供了。其它指令,都要具體地設計,才能寫到程式中。以一條雙運算元的加法指令為例,指令系統只規定了指令的功能和格式,要求A1和A2都是地址運算元,指令的功能是把兩個地址的內容相加,把它們的和放在A1或者A2,一般也放在某個暫存器裡,並未規定具體的A1和A2是什麼。因此文字上的指令還是不能執行的指令。程式設計人員寫到程式中的時候,要指明A1和A2,變成一條具體從哪裡取數,相加結果送往哪裡的指令。取數的地方有時還必需通過變址方式依據當時的計算結果間接地確定,“計算機的設計者”怎麼可能事先就寫好每一條供“計算機…操作”的加法指令呢?

我國DJS 21機,文字規定只有59條機器語言指令,可是用這個指令系統人工編寫的ALGOL 60編譯程式大約有16000條指令。其中的指令都是程式編寫者一條條地設計出來的,並非59條指令的簡單重複取用。

Linux程式碼超過1000萬行,Windows 7程式碼有約1億行,這類大型程式往往是幾千人幾十年的工作結果(參見B.W.Kernighan著,李鬆峰等譯:《世界是數字的》P97,人民郵電出版社 2013年7月)。

由此可見,從文字規範到有用的程式之間可能還有多麼大的距離。怎麼能夠簡單地講文字規定的指令系統“是計算機的設計者...賦予計算機的操作功能”呢?
4. 一條條機器指令都是0與1的字位序列,都板著臉孔呆板得很,“機器語言的靈活性”表現在哪裡?

上述表明,計算機語言一詞,在我國計算機界,已經包含了許多錯誤和含混的解釋,也說明其實它還是一個無法說清的概念。這或許是首提和大力推行的譚浩強先生所沒有估計到的。

(三) 國內外計算機界一些知名專家,到目前為止不把程式語言叫做計算機語言,在講解程式語言的書中不用“計算機語言”一詞

《中國大百科全書》電子學與計算機卷Ⅰ、Ⅱ( 中國大百科全書電子學與計算機編委會:《中國大百科全書》電子學與計算機 第Ⅰ、Ⅱ卷,中國大百科全書出版社 北京 上海 1986.9 )有由徐家福教授等寫的“程式設計語言”等眾多詞條,精裝大開本洋洋兩大卷,沒有收錄“計算機語言”詞條

由計算機與電子資訊領域兩院院士王大珩主編,有中科院計算所史忠植等一批研究員參編詞條的《高技術詞典》(王大珩主編,《高技術詞典》清華大學出版社,科學出版社2000.1),收錄了業內流行的種種詞條,包括“程式設計語言”,但也沒有“計算機語言”

我們前面已經引述,國際標準化組織推薦ALGOL的文字名字就叫《程式設計語言ALGOL》,不是計算機語言。

C語言的發明者宣示C語言是程式設計語言“programming language”(D.M.Ritchie & B.W.Kernighan:“The C Programming language”),在整本“The C Programming language”書裡都沒有“計算機語言”一詞。該書最早翻譯成中文時,也是保持書名用《程式設計語言C》。而在譚先生的書中,卻完全去掉了對於C的這種正確的稱謂。

C++的發明人本賈尼•斯特勞斯特魯普(Bjiarne Stroustrup)在接受採訪時表示,對一個程式設計語言的“度量方式是在多大程度上告訴程式設計師應該做什麼”,這明確地表示,包括他的C++在內的所有程式設計語言都是面向程式設計師的,他也沒有把C++跟“計算機語言”做任何關聯。(參見金芝等:《專訪C++的發明人Bjiarne Stroustrup》,《中國計算機學會通訊》2014年12月)

在UNIX環境下,有比C語言更高階的程式語言Shell, 它以系統中的命令和其它可執行程式為加工的元素,不但可以定義變數,if、for、do、while、case等控制流結構一應俱全,還支援一組元字元,功能強大。在相關經典著作(B.W.Kernighan等:“The UNIX Programming Environment” PRENTICE-HALL.INC 1984 該書中譯本見陳向群:《UNIX程式設計環境》機械工業出版社 1999)中,作者們宣示它也是一種程式設計語言,而不叫計算機語言。

B.W.Kernighan的一本近著《世界是數字的》(B.W.Kernighan著,李鬆峰等譯:《世界是數字的》,人民郵電出版社 2013),介紹資訊社會每個公民,包括總統在內都應掌握的關於計算機和通訊方面的知識,其中第5章“程式設計與程式語言”,第7章“ 學習程式設計”,提到BASIC、C、JAVA、JAVAScript、HTML等許多正在使用的程式語言,也沒有用計算機語言一詞。

(四)、幾點拙見
1. 科技名詞的命名、改名權應該屬於原創人員和相關專業的名詞審定學術組織。嚴肅的推廣人應該照用,不應隨意改動。把程式語言叫做計算機語言已經在計算機界引起了混亂。
2. 程式語言是面向程式設計師,用來寫計算機程式的語言,只在幫助寫源程式這個層面關注它們就夠了。而且寫好程式的關鍵因素是寫程式的人而不是語言。不應誇大語言文字的作用,更不應延伸說它們就是計算機語言
3. 把可執行程式叫做計算機語言也不準確
經編譯生成的可執行程式,是一系列脫離了程式語言的機器指令集合,程式後續的駐留和執行是作業系統的任務,與程式語言無關。可執行程式不再歸宿於程式設計師,也不是計算機特有的,任何一個應用程式對於計算機而言都是可配可不配的。它的屬性應該歸程式的使用者。對於使用者啟動的任何應用程式,系統只從時間和空間及資源需求上保證程式的執行。作為計算機系統基本組成部分的硬體和作業系統都不懂得,也不關注程式的語義。執行一個程式並不意味著計算機在向外界表達什麼,那麼何以要把計算機執行一個程式叫計算機語言呢?

容易發現,洗衣機、電梯等機電裝置,都能夠依據人的意圖執行事先編寫的程式,但人們並不據此就稱之為洗衣機語言、電梯語言等等,道理是一樣的。
4. 計算機微觀不可控,不應企求通過“控制計算機每個動作”去利用計算機,只能通過編寫和執行程式利用計算機。

作業系統支援和保證每個程式執行,最終實現其在外界所看到的功能。從微觀上看,現代計算機中可能存在大量程式和執行緒,它們生生滅滅,走走停停,併發地執行著,具有隨機性。計算機中還會有種種來自外部和內部的“事件”,事件的出現和處理也將導致大量隨機的併發活動,也是不可預期和不可控的。系統的瞬時狀態總處在快速變化中,對其測試和控制無法準確地進行。

說要利用計算機,就要控制計算機,這是一種想當然的看法。類比一個例子吧。在北京市任何一個地方,總可以有方案乘公交車(包括地鐵)到達天安門廣場,時間、車次還可能有多種選擇。在這裡,公交系統就是計算機,某個乘車方案就是程式,一次具體實現就是由他參與在公交系統上執行程式。他並不是通過控制公交系統到達天安門廣場的。哪個乘車人有本事控制公交系統?
5. “計算機語言”一詞應該屬於新的智慧計算機。
隨著計算機技術的進步,曾經出現過許多新名詞,比如計算機影像、計算機動畫等,它們都有確切的含義。但計算機語言一詞目前還不能明確地界定其含義。因為現有的通用計算機還沒有意識,因而沒有語言能力,不應該過早地強行把“語言”和“計算機”綁在一起。思維是語言的內涵,語言是思維的外殼。有意識、有學習能力、能夠自主控制的,因而有計算機語言能力的智慧計算機,還處在研發湧現和不斷完善階段。具備計算機語言能力的新型智慧計算機和智慧機器人前景廣闊,真正的計算機語言值得關注和期待。我相信對計算機語言的準確定義也會被這方面的專家給出。

(與本文相關的更多內容,可參看 彭民德《電子計算60年》第3章 二代計算硬體獨唱 電子工業出版社)

相關文章