深奧的編程語言

深奧的編程語言（Esoteric programming language，有時簡寫為Esolang）是一類編程語言，它們被設計用於測試計算機語言表達的極限，或者作為一個概念的證明(POC)，或僅僅是一個程序員的冷玩笑。esoteric將它們與開發人員真正用於編寫軟件的語言區別開來。通常情況下，Esolang的創作者通常並不打算讓它成為主流編程語言，儘管如此，一些深奧的功能如視覺空間，啟發了在藝術中的實際應用。這種語言在黑客和愛好者之間通常較流行。
設計者幾乎不會以提高該語言的易用性為目標，但會保證邏輯上的可用性。設計者通常會移除或取代傳統語言的常見功能，但仍會強調並保持圖靈完備性。

**歷史**
最早、且仍是深奧語言典型案例的是INTERCAL，由Don Woods (programmer)和詹姆斯·里昂在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的Befunge（類似FALSE，但有一個二維的指令指針）一道，成為現今最為廣泛支持的深奧編程語言。這些都是最小化圖靈焦油坑、和多餘的語言混淆功能的典型例子。brainfuck的極小化設計兼具了優雅和純淨；實際上它與圖靈機P′′系列有關。

**術語**

**圖靈焦油坑**
圖靈焦油坑（Turing tarpit）是具有圖靈完備性的編程語言，但它的指令、操作數或等效對象非常少。其中包括brainfuck（8個指令，0個操作數），單一指令計算機（1個指令，2至3個操作數）和Thue（1個指令，2個操作數）。
Turning tarpit是有狀態編碼的圖靈焦油坑，即語言中的命令用於從一個有限的範圍內選擇操作，然後將這些操作應用到程序的當前狀態中。這樣的例子包括reMorse、Whirl，也許還包括INTERCAL。

**有狀態編碼**
一種編寫程序的方式，使得代碼中的每一個子串：
#定位到列表中的下一條指令，且
#應用到轉換當前的程序狀態。
注意每一個單一的指令總是包含兩個連續的階段：選擇一個操作，並執行它。操作列表可能是靜態的——如reMorse或THRAT，或動態的——如reMorse4ever。
下面是一個reMorse或THRAT的例子:
Select Next Operation in list
Perform Operation

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

**Funges**
funge是一類深奧的編程語言，其程序是基於度量空間中的座標系的（通常為笛卡爾座標系，但不一定是）。運行時，通過在程序空間中通過移動指令指針（用一個位置矢量表示當前執行的指令），以確定空間中的點，從而執行指令。不同的指令指示了指令指針的移動方向，並因此決定指令的執行順序。
目前，這些語言行為的官方標準是Funge-98規範。這個規範是Befunge語言——一個有二維環面拓撲結構的語言——語義的一個概括。嚴格遵守這個標準的語言有時也被稱為funges，如Unefunge（一維）和Trefunge（三維），而更多有顯著差異的“遠親”被稱為fungeoids，如Wierd。

**非確定性語言**
對於確定性語言，如果給定程序的當前狀態，則總是可以預測它的下一個狀態。但非確定性語言就不是這樣。大多數的語言都是確定性的，但某些語言提供了一個內置的隨機指令，例如Befunge。此外，有些語言，如Java2K只有隨機指令。因此，即使編一個像有可靠輸出這樣簡單的程序，往往都是一項艱鉅的任務。
非確定性語言可以用來搜索大範圍空間，例如對於語法，窮舉搜索是不切實際的。隨機文本生成器，例如Dada Engine和rmutt都是非確定性語言的例子。
更神奇的是，不確定性算法已經用於了超計算的理論研究中。

**互聯網社區**
在互聯網上，有一個規模小、但有活力的社區，聚集了使用和設計語言的愛好者，目前主要圍繞著Esolang wiki進行（見下文）。
esolang社區偶爾會活躍，討論的範圍從爭論某個語言是否圖靈完備，到如何在編程環境中，將形象化的數學概念弄得抽象和難理解。有一個郵件列表，但幾乎廢棄不用，大多數時候是在wiki或在IRC上討論。
圖靈完備性是一個熱門的討論話題，因為語言的圖靈完備性絕不是一眼就能看出的，而且往往需要證明方法上的飛躍才能解決。新語言和新功能不斷被創造出來，因此，證明圖靈完備性始終是一個挑戰。
編程語言愛好者的另一個相關追求是混淆代碼。

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

**///**
///是一門由坦納斯·韋特（Tanner Swett）在2008年發明的編程語言。該編程語言只含有一個操作符——“/”，功能是替換字符串。
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設計，目的是使程序看起來像菜譜。程序中包括標題、列表中的變量和值，和操作堆棧的指令列表。儘管首次提出時，它的設計原則是“程序菜譜不僅應能產生有效的輸出，還能以此方便地準備美味的食物”，然而，如果真按大部分程序中原料的組合和數量，則會做出難以下嚥的食物（如果有的話）。

**FALSE**
FALSE是一種面向堆棧的編程語言，有單字符命令和變量。例如，3+1的結果可以通過執行(λ x → x + 1)(3)得出：31+!

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

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

**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設計的，這個語言的程序是點陣圖，看起來像抽象藝術。編譯器由一個“指針”引導，在圖像中從一個色塊移動到下一個。指針移出一個區域時執行一個操作。
20種顏色有指定的行為：18種“彩”色，依6步色調週期和3步亮度週期排序；黑色和白色未排序。當由一種“彩”色進入到另一種時，執行的操作由色調和亮度的變化數確定。黑色不能進入，當指針試圖進入一個黑色的區域時，將會改變選擇下一個塊的規則。如果所有可能的規則都嘗試過了，則程序終止。圖像邊界以外的地方也被視為黑色。白色不執行操作，但允許指針“通過”。20種指定以外的顏色行為由編譯器或解釋器指定。
變量以有符號整數存儲在內存中的單一堆棧內。大多數操作是在這個堆棧上進行的，其他操作則可以在棧上進行輸入/輸出，或告訴編譯器移動指針的規則。
Piet是以荷蘭畫家皮特·蒙德里安（Piet Mondrian）命名的。原定的名稱Mondrian已經被佔用了。

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

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

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

**相關條目**
 IOCCC

**參考文獻**

**外部鏈接**
  Esolang date=20210420163702  — 致力於深奧編程語言的維基站點。- EsotericProgrammingLanguage，位於WikiWikiWeb

**列表**
  esolang wiki上的esolang列表 date=20210421092741 - Obfuscated Programming Languages