一種很簡單的編程語言

——Brainfuck!

  BF語言——夠簡單了吧?一共只有8條指令……

  但這篇文章不會就此結束,BF也不見得“簡單”,請看http://esolangs.org/wiki/BF_instruction_minimalization (我是用chorme瀏覽器翻譯的)。在這一“行業”,還可以再認真一點……(何況還有傳說中的“單指令計算機”,我不能聞其詳)但是我們得再次哲學起來:我們在幹什麼?

  什麼叫簡單的編程語言?或者更“本初”的問題,什麼是編程語言?一個引導性的問題:Brainfuck算是彙編還是機器語言?(網上能看到用C實現Brainfuck,莫名喜感)我們知道“複雜指令集”和“精簡指令集”,而對於後者,百科給出的指令數目是“小於100條”——但是似乎連大多數編程語言的字符可以都少於100個——我知道你要說什麼,Brainfuck的每一個字符都是一條【指令】,但是彙編又如何呢?彙編指令常常是帶參數的,可見彙編“遠比BF複雜”……——所以,從圖靈機模型到8086級別,發生了什麼?以及,高級語言是怎麼回事?

  我們先不談“語言”,先談“操作”。“操作”可算是編程中最底層的東西了。操作是什麼?我們可以簡單定義:1.數個操作組合仍爲操作;2.CPU指令都是操作。但這麼一來,BF還比彙編高級了?!因此得出“操作基於某一具體處理器”,或者“操作基於底層操作”。我不知道傳統CPU有沒有“寄存器+1”這個指令,假設沒有,那麼傳統彙編和BF就是可以互相表示並且沒有高低之分的。這也警示我們,高級語言的高級也並非在指令上。

  我暫時使用“處理器接口”這一詞彙,並且再添2個:“傳統處理器”和“BF處理器”。——等等,我好像忘記了BF的最後2個指令?!——不,(應該)還是可以補償的,或者(也應該)可以修改這條指令,使之成爲常見的條件跳轉,只需要增加一個地址參數(我真是天才!)我索性創造一種【類BF語言】好了,而且按慣例無視輸入輸出——

  • 你需要:一串足夠長地址,寄存器A和M;一臺處理器,不斷執行A對應地址中指令
  • 指令1:後接一個參數x,將地址爲x的值放入M,A+=2
  • 指令2:後接一個參數x,將M放入地址爲x處,A+=2
  • 指令3:後接一個參數x,將地址爲x的值加上M放入M,A+=2
  • 指令4:後接一個參數x,將地址爲x的值放入A
  • 指令5:後接一個參數x,如果M爲0,將地址爲x的值放入A;否則A+=2
  • 指令6:停機

  我意識到一個問題:我好像不會證明圖靈完備?!雖說有個懶辦法,直接實現並寫數個程序即可。更懶的辦法是,實現BF。但是用C實現BF以證明C語言是圖靈完備的,這未免……?

  另一個問題是,switch讓多條指令變成一條,也就是以上6條指令,等價於一條switch(可以再用一個寄存器,也可以指定一個地址)。雖然,有什麼意義呢?(CPU即switch,見上一篇文)其實還有一個問題,2個寄存器究竟是多了還是少了?

  剛纔又想到另一個問題:能不能說“固定地址跳轉”比BF中的“跳轉到相應……”更“簡單”?所謂的“相應”是高級表述,而地址跳轉是低級表述?顯然二者等價,但有高低之分;但++和+=x呢?(說起來剛纔的“類BF語言”缺少減法或者取反)——且慢,我們在幹什麼?我說了這麼久,但似乎漫無目的(嗎?)?

  我承認在一開始我沒有單刀直入,我寫文章也不會刻意安排。那麼——

  • BF語言簡單嗎?
  • BF和彙編有何關係?
  • 怎樣的語言是簡單的?什麼叫簡單?

  第一個問題是不用多想的,辯證否定,就指令數量而言,BF很簡單,但能更簡單。這也部分回答了第三個問題,當“簡單”特指指令數量而言時。對於第二個問題,有必要談一談編程語言。編程語言是從結構主義開始的,即(“主要是”)我們服從機器習慣。但現在的高級語言開始講究機能主義,讓機器服從我們的習慣(但大體還是延續傳統,並不見人直接從需求開始向下設計?)。按地址跳轉是(傳統)機器習慣,按匹配跳轉是人的習慣。指令默認按序執行是人的習慣,但和機器不矛盾(剛纔類BF語言每個指令附帶的A+=2,其實可以改成任何固定跳轉);加減乘除是人的習慣,加法和取反是邏輯底層,++是邏輯更底層。但是條件轉移和重複是貫穿始終的,以列豎式算除法爲例,此過程是很標準的循環操作。重複在機器層可以不看做指令,因爲跳轉就可以做到;但在高級語言層,這一過程還是被封裝了起來,甚至跳轉被隱藏掉了(萬能exec不算)。讓人想起了20步還原魔方的典故——“上帝視角”:充滿goto的代碼“只有上帝看得懂”,但是對於只有數條指令的CPU,它甚至不知道上層封裝。無論多精妙的軟件,最終是由簡單指令組合而成,但用匯編直接寫……(我不知道,我聽說過Warez……)於是我們回答第三問的第二個角度:簡單可以指“偏向人的習慣”,但人和機器也可能在某些方面是一致的。所以顯然BF(在此層面)不簡單了。現在我們只剩第二個問題了,我們不妨加一問:語言是什麼?之前說到操作,操作是什麼很明晰了;我們現在說“指令”,請注意“指令”既包括語義,又包括形式。我們不妨給“簡單”再加一個維度作爲參考:“用於表示的符號數目”。機器語言只有1和0,毫無疑問是最簡單的(BF要8個,類BF還需要參數)。但仔細想想會發現這個維度沒什麼意義:我們把C程序中的字符全用二進制ASCII取代,C還是C。——題外話:我們可謂是在研究編程中的語言學了,但是謝天謝地編程中的句子必須是操作(嗎?!)——不過這麼一想不對勁:要是關鍵字可以隨意換,那C豈不成python的子集了?(引用若干庫)語言差別何在?或許就在於這集合關係——既然有Cpython,那麼py能做的C必能做(誤,我只能肯定py能做的彙編必能做),那語言的意義是什麼?再問個問題:【抽象】的意義何在?畢竟語言的意義只能在於抽象了。語言(在這裏)當是脫離符號本身談論的(【語法糖就是語法本身!!】——我覺得我說了一句經典,呵呵)(在(我的)語言學裏,符號也該作爲語義談論)很好,所以編程語言的意義就是向上封裝。不管是從結構主義還是從機能主義角度。向上封裝有利於結構主義向上,也利於機能主義向下。


(這段意識流給我一個啓示:人的思維“以目的爲導向”沿語義網走,當走到盡頭就開始回溯直到走完可能分支。另外這裏的“語義網”和專有名詞略有區別)


  所以我想設計一門語言,從機器到人。我懂哲學,但我連彙編都不會,怎麼辦呢?

(2018-1-7 於地球, 完)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章