深奥的编程语言 (Esoteric programming language ,有时简写为Esolang )是一类编程语言 ,它们被设计用于测试计算机语言表达的极限,或者作为一个概念的证明(POC),或仅仅是一个程序员的冷玩笑。esoteric 将它们与开发人员真正用于编写软件的语言区别开来。通常情况下,Esolang 的创作者通常并不打算让它成为主流编程语言,尽管如此,一些深奥的功能如视觉空间 语法 [ 1] ,启发了在艺术中的实际应用。这种语言在黑客 和爱好者之间通常较流行。
设计者几乎不会以提高该语言的易用性为目标,但会保证逻辑上的可用性。设计者通常会移除或取代传统语言的常见功能,但仍会强调并保持图灵完备性 。
历史
最早、且仍是深奥语言典型案例的是INTERCAL ,由唐·伍兹 和詹姆斯·里昂在1972年设计,意在于创造一种与他们知道的语言所不同的语言。[ 2] 它戏仿 了当时通用的语言,如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是有状态编码的图灵焦油坑,即语言中的命令用于从一个有限的范围内选择操作,然后将这些操作应用到程序的当前状态中。[ 3] 这样的例子包括reMorse[ 4] 、Whirl,也许还包括INTERCAL 。
有状态编码
一种编写程序的方式,使得代码中的每一个子串:
定位到列表中的下一条指令,且
应用到转换当前的程序状态。
注意每一个单一的指令总是包含两个连续的阶段:选择一个操作,并执行它。操作列表可能是静态的——如reMorse[ 4] 或THRAT[ 5] ,或动态的——如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[ 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语言只使用空白字符(空格、制表符和回车),并忽略所有其他字符。这与传统语言不区分不同的空白字符、不区分空格和制表符相反。这个特性还允许Whitespace程序隐藏在其他语言程序的源代码中,例如C。
Chicken
Chicken语言只有“chicken”一个关键字[ 15] 。
相关条目
参考文献
^ McLean, A., Griffiths, D., Collins, N., and Wiggins, G. (2010). "Visualisation of Live Code". In Electronic Visualisation and the Arts , London: 2010.
^ 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)
^ Turning tarpit - Esolang (页面存档备份 ,存于互联网档案馆 ). Esolangs.org (2011-05-26). Retrieved on 2011-11-21.
^ 4.0 4.1 reMorse
^ THRAT
^ Java2K [永久失效連結 ]
^ Dada Engine
^ rmutt
^ 游戏天空 - 专属于程序猿的天书! 十大最怪异的编程语言 . [2017-01-14 ] . (原始内容存档 于2017-01-16).
^ Esolang - /// . [2017-01-14 ] . (原始内容存档 于2020-11-12).
^ DM's Esoteric Programming Languages - Chef (页面存档备份 ,存于互联网档案馆 ). Dangermouse.net. Retrieved on 2013-07-21.
^ DM's Esoteric Programming Languages - Chef - Hello World (页面存档备份 ,存于互联网档案馆 ). Dangermouse.net. Retrieved on 2013-07-21.
^ Jane Bailey. Bidding on Security . The Daily WTF. 2016-02-29 [2018-07-13 ] . (原始内容 存档于2016-03-02).
^ Morgan-Mar, David. Piet programming language . 25 January 2008 [18 May 2013] . (原始内容存档 于2021-04-15).
^ " Hello world" in Esoteric Programming Languages? (Esolangs) . DEV Community. 25 July 2020 [2022-12-04 ] (英语) .
外部链接
列表