跳至內容

深奧的程式語言

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書

深奧的程式語言Esoteric programming language,有時簡寫為Esolang)是一類程式語言,它們被設計用於測試電腦語言表達的極限,或者作為一個概念的證明(POC),或僅僅是一個程式設計師的冷玩笑。esoteric將它們與開發人員真正用於編寫軟件的語言區別開來。通常情況下,Esolang的創作者通常並不打算讓它成為主流程式語言,儘管如此,一些深奧的功能如視覺空間英語Spatial–temporal reasoning語法英語Syntax (programming languages)[1],啟發了在藝術中的實際應用。這種語言在黑客和愛好者之間通常較流行。

設計者幾乎不會以提高該語言的易用性為目標,但會保證邏輯上的可用性。設計者通常會移除或取代傳統語言的常見功能,但仍會強調並保持圖靈完備性

歷史

[編輯]

最早、且仍是深奧語言典型案例的是INTERCAL英語INTERCAL,由唐·伍茲英語Don Woods (programmer)和詹姆斯·里昂在1972年設計,意在於創造一種與他們知道的語言所不同的語言。[2]戲仿了當時通用的語言,如FortranCOBOL組譯

INTERCAL的早期實現嘗試是在IBM System/360和一台身份不明的雅達利電腦(可能是Atari 2600)上進行的,但沒有成功。多年來,INTERCAL僅僅只存在於INTERCAL手冊中。1990年Unix中C語言的實現復興了這個語言,刺激了深奧電腦語言的設計熱潮。

1992年,Wouter van Oortmerssen建立了一個小的堆疊導向的程式語言叫做FALSE,它的語法設計成本身就能使代碼混淆、混亂,並且難以閱讀。值得注意的是,它有一個只有1024位元組的編譯器。這啟發了Urban Müller建立一個更小的語言,也就是現在著名的brainfuck,其中只包括了八個可辨識字元。它與Chris Pressey的Befunge英語Befunge(類似FALSE,但有一個二維的指令指標)一道,成為現今最為廣泛支援的深奧程式語言。這些都是最小化圖靈焦油坑、和多餘的語言混淆功能的典型例子。brainfuck的極小化設計兼具了優雅和純淨;實際上它與圖靈機P′′英語P′′系列有關。

術語

[編輯]

圖靈焦油坑

[編輯]

圖靈焦油坑(Turing tarpit)是具有圖靈完備性的程式語言,但它的指令、運算元或等效對象非常少。其中包括brainfuck(8個指令,0個運算元),單一指令電腦(1個指令,2至3個運算元)和Thue(1個指令,2個運算元)。

Turning tarpit是有狀態編碼的圖靈焦油坑,即語言中的命令用於從一個有限的範圍內選擇操作,然後將這些操作應用到程式的當前狀態中。[3]這樣的例子包括reMorse[4]、Whirl,也許還包括INTERCAL英語INTERCAL

有狀態編碼

[編輯]

一種編寫程式的方式,使得代碼中的每一個子串:

  1. 定位到列表中的下一條指令,且
  2. 應用到轉換當前的程式狀態。

注意每一個單一的指令總是包含兩個連續的階段:選擇一個操作,並執行它。操作列表可能是靜態的——如reMorse[4]或THRAT[5],或動態的——如reMorse4ever。

下面是一個reMorse或THRAT的例子:

Select Next Operation in list
Perform Operation

語言範式

[編輯]

程式語言的範式可以分為若干類別,這些類別可以用來大致了解特定語言的操作方式。其中包括命令式語言,如brainfuck,其指令描述了如何修改數據;函數式語言,如Unlambda英語Unlambda,其中的數據和代碼都或多或少地可交換,而程式的執行是通過重複迭代呼叫函數實現的;和重寫語言,如Thue,其中可以使用變換函數使狀態初始化。

Funges

[編輯]

funge是一類深奧的程式語言,其程式是基於度量空間中的坐標系的(通常為笛卡爾坐標系,但不一定是)。執行時,通過在程式空間中通過移動指令指標(用一個位置向量表示當前執行的指令),以確定空間中的點,從而執行指令。不同的指令指示了指令指標的移動方向,並因此決定指令的執行順序。

目前,這些語言行為的官方標準是Funge-98規範。這個規範是Befunge英語Befunge語言——一個有二環面拓撲結構的語言——語意的一個概括。嚴格遵守這個標準的語言有時也被稱為funges,如Unefunge(一維)和Trefunge(三維),而更多有顯著差異的「遠親」被稱為fungeoids,如Wierd。

非確定性語言

[編輯]

對於確定性語言,如果給定程式的當前狀態,則總是可以預測它的下一個狀態。但非確定性語言就不是這樣。大多數的語言都是確定性的,但某些語言提供了一個內建的隨機指令,例如Befunge。此外,有些語言,如Java2K[6]只有隨機指令。因此,即使編一個像有可靠輸出這樣簡單的程式,往往都是一項艱巨的任務。

非確定性語言可以用來搜尋大範圍空間,例如對於語法,窮舉搜尋是不切實際的。隨機文字生成器,例如Dada Engine[7]和rmutt[8]都是非確定性語言的例子。

更神奇的是,不確定性演算法已經用於了超計算的理論研究中。

互聯網社區

[編輯]

在互聯網上,有一個規模小、但有活力的社區,聚集了使用和設計語言的愛好者,目前主要圍繞着Esolang wiki進行(見下文)。

esolang社區偶爾會活躍,討論的範圍從爭論某個語言是否圖靈完備,到如何在編程環境中,將形象化的數學概念弄得抽象和難理解。有一個郵寄清單,但幾乎廢棄不用,大多數時候是在wiki或在IRC上討論。

圖靈完備性是一個熱門的討論話題,因為語言的圖靈完備性絕不是一眼就能看出的,而且往往需要證明方法上的飛躍才能解決。新語言和新功能不斷被創造出來,因此,證明圖靈完備性始終是一個挑戰。

程式語言愛好者的另一個相關追求是混淆代碼

範例

[編輯]

下面是一些深奧的語言的典型範例:

///

[編輯]

///是一門由坦納斯·韋特(Tanner Swett)在2008年發明的程式語言。該程式語言只含有一個運算子——「/」,功能是替換字串[9][10]

Hello World程式範例:

Hello, world!

稍微複雜的Hello World:

/ world! world!/Hello,/ world! world! world!

在上列代碼中,第一次出現的「 world! world!」 先被替換為「Hello,」,得到了「Hello, world!」。隨後的代碼的功能為列印。

Befunge

[編輯]

Befunge類語言允許使用代碼,讓指令指標在多個維度中漫遊。例如,下面的程式將「Hello World」字元以相反的順序壓入棧,然後通過指令[>]、[:]、[v]、[_]、[,]和[^]以順時針方向迴圈,並在迴圈中列印字元。

"dlroW olleH">:v
             ^,_@

二元Lambda演算

[編輯]

二元Lambda演算是從演算法資訊論的角度設計的,以便在最少的陳述式意義下寫出儘可能密集的代碼。它有一個29位元組的自直譯器,一個21位元組的素數篩選器,和一個112位元組的Brainfuck直譯器。

Brainfuck

[編輯]

Brainfuck的語言設計極為精簡,並且能輕易寫出混亂的代碼。它的程式中只有8個不同的字元。例如,下面的程式輸出「Hello World」:

 ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++
 ..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

Chef

[編輯]

Chef是一種堆疊導向的程式語言,由David Morgan-Mar設計,目的是使程式看起來像菜譜。程式中包括標題、列表中的變數和值,和操作堆疊的指令列表。[11]儘管首次提出時,它的設計原則是「程式菜譜不僅應能產生有效的輸出,還能以此方便地準備美味的食物」,然而,如果真按大部分程式中原料的組合和數量,則會做出難以下咽的食物(如果有的話)。[12]

FALSE

[編輯]

FALSE是一種堆疊導向的程式語言,有單字元命令和變數。例如,3+1的結果可以通過執行(λ x → x + 1)(3)得出:3[1+]!

INTERCAL

[編輯]

INTERCAL是「縮寫無法發音的編譯器語言」(Compiler Language With No Pronounceable Acronym)的簡稱。[2]

JSFuck

[編輯]

JSFuck(或為了避諱髒話寫作JSF*ck)是一種深奧的JavaScript編程風格。以這種風格寫成的代碼中僅使用[]()!+六種字元。與其他深奧程式語言不同的是,以JSFuck風格寫出的代碼不需要另外的編譯器或直譯器來執行,無論瀏覽器或JavaScript引擎中的原生JavaScript直譯器皆可直接執行。[13]

LOLCODE

[編輯]

LOLCODE被設計為類似lolcat的說話方式。以下是「Hello World」的例子:

 HAI
 CAN HAS STDIO?
 VISIBLE "HAI WORLD!"
 KTHXBYE

Malbolge

[編輯]

Malbolge(地獄的第8圈)被設計為最困難和最深奧的程式語言。

單一指令電腦

[編輯]

單一指令電腦是一種只有一個操作的機器語言。這實際上是一類語言,因為對於任何給定的操作,都可以定義這樣的語言。

Piet

[編輯]
Piet程式,輸出「Piet」
Piet的「Hello World」程式

Piet是由David Morgan-Mar設計的,這個語言的程式是點陣圖,看起來像抽象藝術[14]編譯器由一個「指標」引導,在圖像中從一個色塊移動到下一個。指標移出一個區域時執行一個操作。

20種顏色有指定的行為:18種「彩」色,依6步色調周期和3步亮度周期排序;黑色和白色未排序。當由一種「彩」色進入到另一種時,執行的操作由色調和亮度的變化數確定。黑色不能進入,當指標試圖進入一個黑色的區域時,將會改變選擇下一個塊的規則。如果所有可能的規則都嘗試過了,則程式終止。圖像邊界以外的地方也被視為黑色。白色不執行操作,但允許指標「通過」。20種指定以外的顏色行為由編譯器或直譯器指定。

變數以有符號整數儲存在主記憶體中的單一堆疊內。大多數操作是在這個堆疊上進行的,其他操作則可以在棧上進行輸入/輸出,或告訴編譯器移動指標的規則。

Piet是以荷蘭畫家皮特·蒙德里安(Piet Mondrian)命名的。原定的名稱Mondrian已經被佔用了。

Shakespeare

[編輯]

Shakespeare語言(SPL)的目的是使程式看起來像莎士比亞的戲劇。例如下面的陳述式聲明了程式中的一個點,可以通過一條GOTO陳述式轉到:Act I: Hamlet's insults and flattery.

Whitespace

[編輯]

Whitespace語言只使用空白字元(空格、制表符和Enter),並忽略所有其他字元。這與傳統語言不區分不同的空白字元、不區分空格和制表符相反。這個特性還允許Whitespace程式隱藏在其他語言程式的原始碼中,例如C。

Chicken

[編輯]

Chicken語言只有「chicken」一個關鍵字[15]

相關條目

[編輯]

參考文獻

[編輯]
  1. ^ McLean, A., Griffiths, D., Collins, N., and Wiggins, G. (2010). "Visualisation of Live Code". In Electronic Visualisation and the Arts, London: 2010.
  2. ^ 2.0 2.1 Woods, Donald R.; Lyon, James M., The INTERCAL Programming Language Reference Manual, Muppetlabs.com, 1973 [2009-04-24], (原始內容存檔於2009-04-24) 
  3. ^ Turning tarpit - Esolang頁面存檔備份,存於互聯網檔案館). Esolangs.org (2011-05-26). Retrieved on 2011-11-21.
  4. ^ 4.0 4.1 reMorse
  5. ^ THRAT
  6. ^ Java2K[永久失效連結]
  7. ^ Dada Engine
  8. ^ rmutt
  9. ^ 游戏天空 - 专属于程序猿的天书! 十大最怪异的编程语言. [2017-01-14]. (原始內容存檔於2017-01-16). 
  10. ^ Esolang - ///. [2017-01-14]. (原始內容存檔於2020-11-12). 
  11. ^ DM's Esoteric Programming Languages - Chef頁面存檔備份,存於互聯網檔案館). Dangermouse.net. Retrieved on 2013-07-21.
  12. ^ DM's Esoteric Programming Languages - Chef - Hello World頁面存檔備份,存於互聯網檔案館). Dangermouse.net. Retrieved on 2013-07-21.
  13. ^ Jane Bailey. Bidding on Security. The Daily WTF. 2016-02-29 [2018-07-13]. (原始內容存檔於2016-03-02). 
  14. ^ Morgan-Mar, David. Piet programming language. 25 January 2008 [18 May 2013]. (原始內容存檔於2021-04-15). 
  15. ^ "Hello world" in Esoteric Programming Languages? (Esolangs). DEV Community. 25 July 2020 [2022-12-04] (英語). 

外部連結

[編輯]

列表

[編輯]