這到底是什麼語言喔齁齁齁齁: Esoteric Language

yiz
8 min readDec 26, 2021

--

「pi pi pi pi pi pi pi pi pi pi pika pipi pi pi pi pi pi pi pi pipi pi pi pi pi pi pi pi pi pi pi pipi pi pi pi pipi pi pichu pichu pichu pichu ka chu pipi pi pi pikachu pipi pi pikachu pi pi pi pi pi pi pi pikachu pikachu pi pi pi pikachu pipi pi pi pikachu pichu pichu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pipi pikachu pi pi pi pikachu ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka ka pikachu pipi pi pikachu pipi pikachu」,你能想像這樣的文字是一段完整的 Hello World 程式碼嗎?

「這到底是什麼閃現喔齁齁齁齁齁」

鼻地大師國動張葦航

像這樣的程式語言叫做 Esoteric Language 或稱作 esolang,直接翻譯是深奧的語言,絕大部分都不能用來實際生產,而且也很難理解、閱讀,甚至就是故意設計成難以理解的樣子。這樣的語言到底有什麼用?

一切的起點

說到 esolang,一定要提到最著名的 Brainfuck。Brainfuck 是早期就出現的 esoteric language,對 esolang 帶來啓發性的影響。 Brainfuck 光是名字就讓人印象深刻,而且就像他的名字一樣幹翻了一堆人的大腦,因此吸引了許多的注意。

Brainfuck 的設計目標有兩個:1. 最小 compiler 2. 讓人難以理解。最終 Brainfuck 的 compiler 只花了 240 bytes 就完成了。
Brainfuck 在執行時,會先初始 3000 個為 0 的 cell,跟一個 pointer。並透過 8 個指令來操作:

  • > : 下一個 cell
  • < : 上一個 cell
  • + : cell ++
  • - : cell –
  • [ : while cell != 0
  • ] : end while
  • , : 輸入 byte
  • . : 輸出 byte

稍微觀察就能發現這樣的設計根本就是圖靈機(Turing machine)。圖靈機是一種假想的數學計算模型,圖靈認為這樣模型可以類比人類所能進行的任何計算過程。圖靈機擁有一個無限長的紙帶來儲存資料,讀寫頭修改資料,並有規則來控制讀寫頭。並有3000 個 cell 就是紙帶,pointer就是讀寫頭,8 個指令控制讀寫頭的規則。而 brainfuck 這樣簡單的設計,帶來最小的 compiler,卻對撰寫程式碼極度的不友善,讓我們來看一下 brainfuck 的 hello world

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

OK,你知道為什麼叫做 Brainfuck 了,看完之後頭暈目眩、雙眼無神。

挑戰程式語言的界線

自從 Brainfuck 出現之後,一大堆類似的 esolang 如雨後春筍般冒出,其中的壯易一直挑戰我們對於程式語言的概念。

pi!pika! 可以是程式語言

開頭的「pika pika」就是一種叫 pikalang 的esolang,他的概念很簡單就是把 Brainfuck 的8 個符號對應到8種皮卡丘的叫聲。這樣以來就可以透過皮卡丘的叫聲寫出 brainFuck了。

  • pipi: >
  • pichu: <
  • pi: +
  • ka: -
  • pikachu: .
  • pikapi: ,
  • pika: [
  • chu: ]

類似的 esolang 還有 Whitespace、COW。用奇奇怪怪的符號,每個符號會對應到不同的操作,可能是 I/O、數字、條件判斷、流程控制。如此一來 Whitespace 就造就了整篇空白的程式碼,

https://en.wikipedia.org/wiki/Whitespace_(programming_language)#/media/File:Whitespace_in_vim2.png

或是 COW 造就了整篇 moo moo 叫的程式碼。

是舞蹈也是程式語言

Body fuck 透過姿態辨識,讓不同的姿態對應不同的 Brainfuck 符號,撰寫出 Brainfuck 來。要注意的是你沒有任何辦法刪除跳錯的符號。
雖然這只是不同的方式來「撰寫」Brainfuck,但看著程式碼被跳出來,讓人十分驚艷。

https://vimeo.com/7133810?embedded=true&source=video_title&owner=954173

是圖片也是程式語言

下圖是一張用 Piet 「撰寫」的 Hello World。

https://esolangs.org/wiki/File:Piet__World.gif

一開始的 piet 單純只是挑戰程式語言的概念,後來卻出現了 Piet 藝術家,除了會寫出可以執行的程式之外,還讓圖片盡可能的像是藝術品。

是劇本也是程式語言

Shakespeare Programming Language 簡稱 SPL 是 以劇本撰寫的程式碼,每個角色都是一個 variable,每句台詞有多少個形容詞就 assign 多少給該 variable。

寫起來大概會像這樣

Do Not Adieu, a play in two acts.Romeo, a young man with a remarkable patience.
Juliet, a likewise young woman of remarkable grace.
Ophelia, a remarkable woman much in dispute with Hamlet.
Hamlet, the flatterer of Andersen Insulting A/S.
Act I: Hamlet's insults and flattery. Scene I: The insulting of Romeo.[Enter Hamlet and Romeo]
(下略)

而且除此之外,甚至真的被演出來了!

用語言本身挑戰語言本身

除了挑戰語言的界線,Jsfuck 跟 pyfuck 用語言本身挑戰語言本身,目標是用最少的字原來表達語言本身,最後 Jsfuck 只用了 6 字元()+[]!就能寫出所有的 Javascript,Pyfuck 則用的 13 個字元[(+travels')]

Jsfuck 到底是怎麼辦到的呢? 首先我們要湊出字串來,第一個想法是透過 escape sequence 用數字湊出各個字母,例如 '\101' 代表著 A。那數字要怎麼湊呢?這就要扯到 Js 的自動轉型了,[] 在 Js 中是個 truthy value 只要被換成 boolean 再轉成 number 我們就能得到 1。而 Js 的自動轉型能輕易地做到這件事,用 ! 轉型成 boolean,!![] 得到 true,用 + 轉型成數字 1,於是 Jsfuck 就有了數字。於是我們使用反斜線配合數字,就可以湊出 「Hi」的 escape sequence '\110\151'

接著我們要把湊出的字串變成可以執行的 function,這時就要扯到 Js 的核心部分,我們需要一個function 的 constructor 來構築我們的function,像這樣 []['flat']['constructor']('alert(1)')() 我們就可以得到可以執行的 alert(1)

中間我跳掉了很多細節,方便對 Jsfuck 的原理有個比較整體的描述,有興趣的朋友可以自己去看原始 repo。雖然 Jsfuck 本身沒什麼用途,看著 Jsfuck 用 6 個字母組成 Javascript ,去理解它如何辦到這件事,這過程真的超級有趣。

小結

這些挑戰都不斷地更新我們對程式語言的認識,讓我們直視程式語言的本質。

我真的很喜歡這些esolang,雖然看起來沒有實際價值。但這些挑戰或者玩笑,帶領著我們去挑戰既有的概念,去探究程式語言的界限。

「為什麼要去做這樣的事?因為我可以。」

沒有人說過

Reference

--

--