深奧的程式語言

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

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

歷史

最早、且仍是深奧語言典型案例的是，由和詹姆斯・里昂在 1972 年設計，意在於創造一種與他們知道的語言所不同的語言。它戲仿了當時通用的語言，如 Fortran、COBOL 和彙編。

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

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

術語

2.1 圖靈焦油坑

圖靈焦油坑（Turing tarpit）是具有圖靈完備性的程式語言，但它的指令、運算元或等效物件非常少。其中包括 brainfuck（8 個指令，0 個運算元），單一指令計算機（1 個指令，2 至 3 個運算元）和 Thue（1 個指令，2 個運算元）。

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

2.2 有狀態編碼

一種編寫程式的方式，使得程式碼中的每一個子串：

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

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

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

Select Next Operation in list

Perform Operation

2.3 語言範型

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

2.4 Funges

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

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

2.5 非確定性語言

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

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

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

網際網路社群

在網際網路上，有一個規模小、但有活力的社群，聚集了使用和設計語言的愛好者，目前主要圍繞著 Esolang wiki 進行（見下文）。

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

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

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

示例

下面是一些深奧的語言的典型示例：

4.1 ///

/// 是一門由坦納斯・韋特（Tanner Swett）在 2008 年發明的程式語言。該程式語言只含有一個運算子 ——“/”，功能是替換字串。

Hello World 程式示例：

Hello, world!

稍微複雜的 Hello World：

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

在上列程式碼中，第一次出現的 “world! world!” 先被替換為 “Hello,”，得到了 “Hello, world!”。隨後的程式碼的功能為列印。

4.2 Befunge

}}

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

"dlroW olleH">:v

^,_@

4.3 二元 Lambda 演算

}}

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

4.4 Brainfuck

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

++++++++++>+++++++>++++++++++>+++>+++.>+.+++++++

..+++.>++..+++.------.--------.>+.>.

4.5 Chef

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

4.6 FALSE

FALSE 是一種面向堆疊的程式語言，有單字元命令和變數。例如，3+1 的結果可以透過執行 (λ x → x + 1)(3) 得出：31+!

4.7 INTERCAL

}}

INTERCAL 是 “縮寫無法發音的編譯器語言”（Compiler Language With No Pronounceable Acronym）的簡稱。

4.8 JSFuck

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

4.9 LOLCODE

LOLCODE 被設計為類似 lolcat 的說話方式。以下是 “Hello World” 的例子：

HAI

CAN HAS STDIO?

VISIBLE "HAI WORLD!"

KTHXBYE

4.10 Malbolge

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

4.11 單一指令計算機

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

4.12 Piet

Piet 程式，輸出 “Piet”

Piet 的 “Hello World” 程式

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

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

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

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

4.13 Shakespeare

}}

Shakespeare 語言（SPL）的目的是使程式看起來像莎士比亞的戲劇。例如下面的語句聲明瞭程式中的一個點，可以透過一條 GOTO 語句轉到：Act I: Hamlet's insults and flattery.。

4.14 Whitespace

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

4.15 Chicken

Chicken 語言只有 “chicken” 一個關鍵字。