Эзотерические языки программирования
#define H (*h)
w(int*q){if(q){w(q[2]);printf("%c%9d\n",*q,q[1]+1);w(q[3]);}}
main(){int t,*r=0,*H;while((t=getch())>31){h=&r;while H
if(*H-t)h=&(H[2+(*H<t)]);else{H[1]++;break;}}if(!H)*(H=calloc(4,4))=t;}w(r);}
Как и люди других профессий, программисты не лишены чувства юмора и самоиронии. Наличие целого семейства так называемых эзотерических языков тому доказательство. Эти языки не имеют какого-либо практического значения, а разрабатывались в качестве либо шутки, либо эксперимента, в котором какие-либо идеи доводятся до абсурда. Но иногда от этих языков есть польза. Они порождают упражнения и задачи для программистов: как разработать ту или иную программу, как построить интерпретатор или какой-либо другой инструмент. Многие из них развивают логическое мышление, которое вам пригодится при решении практических задач
Этих языков насчитывается не менее 300.
Самый старый эзотерический язык программирования, INTERCAL (http://progopedia.ru/language/intercal/) , был создан в 1972 году как пародия на существующие в то время языки. Язык пережил несколько версий, каждая из которых целенаправленно усложняла все, что возможно. Например, числа выводились в римской записи. К некоторым инструкциям надо было добавлять модификаторы PLEASE, не несущие никакой смысловой нагрузки. Оператор PLEASE FORGET прерывал безусловный переход, в котором уже не было необходимости. В языке была команда DO ABSTAIN FROM STASHING, которая отключала во всей программе странную команду STASH («припрятать»).
Один из старейших эзотерических языков программирования FALSE (год разработки – 1993 http://progopedia.ru/language/false/ ) положил начало целому поколению языков с односимвольными командами. Язык имеет 20 команд (6+14 в/в), предоставляющих достаточно большой набор возможностей, в том числе именованные переменные, строки и лямбда-функции (функции без имени, используемые в функциональных языках). Синтаксис подобен широко известному в то время языку APL, а некоторые команды заимствованы из языка Forth. Синтаксис языка FALSE очень запутанный, что и было целью создателя языка. Второй целью автора было создания минимального компилятора: авторский вариант, написанные на Ассемблере, занимал ровно 1024 байта!
Вот программа вычисления чисел Фибоначчи на FALSE:
0i: 1a: 1b:
[i;16=~]
[a; $. ",
" $ b; $ a: + b: i;1+i:]
#
"..."
Для сравнения программа на Haskell, который поначалу тоже кажется эзотерическим:
fibs
= 0 : 1 : zipWith (+) fibs (tail fibs)
Программа отражает следующее свойство ряда Фибоначчи. Если «сдвинем» ряд влево на одну позицию (tail fibs) и сложим (zipWith (+)) с исходным рядом, опять получим исходный ряд без первого нуля:
Самый минималистичный язык программирования Brainf*ck (литературный перевод: «Великая Загадка Для Ума, Об Кою Многие Из Мудрейших Сломают Копья») http://progopedia.ru/language/brainfuck, породил целое семейство похожих языков. Минимализм состоит в том, что он имеет всего 8 односимвольных команд (пример программы приведён в эпиграфе), а компилятор занимает менее 200 байт! (это и было целью создания). Тем не менее, на языке можно реализовать любой алгоритм. Вот программа «Hello,world!»:
++++++++++[>+++++++>++++++++++>+++>+<
<<<-]>++.>+.+++++++..+++.>++.<<++++++
+++++++++.>.+++.———.————.>+.>.
В языке программирования AAAAAAAAAAAAAA!!!! символов вдвое меньше, всего четыре: символ A, пробел, восклицательный знак и запятая.
Вот пример программы, которая выводит на экран вводимые с клавиатуры символы: AAAAA A! AAA AAAA AA A! AA AAA AAAAA, A! AAA AA A! AA AAAA AA!
Самый сложный эзотерический язык программирования Malbolge («Злые щели» – название восьмого круга ада «Божественной комедии» Данте, предназначенного для обманщиков) http://progopedia.ru/language/malbolge/. По замыслу автора язык должен быть максимально адским, т.е. сделать процесс программирования как можно сложнее. После публикации спецификации в 2000 году лишь через два года была написана программа «Hello, world!»:
('&%:9]!~}|z2Vxwv-,POqponl$Hjig%eB@@>}=<M:9wv6WsU2T|nm-,jcL(I&%$#"`CB]V?Tx<uVtT`Rpo3NlF.Jh++FdbCBA@?]!~|4XzyTT43Qsqq(Lnmkj"Fhg${z@>
Вручную такое вряд ли кто мог написать. Для этого специально пришлось написать эвристическую программу на языке Лисп. Виртуальная машина Malbolge имеет всего 10 команд и работает в троичной системе счисления.
Самый популярный эзотерический язык программирования – Whitespace. http://progopedia.ru/language/whitespace/ Большинство языков программирования игнорируют непечатные символы: пробел, табуляцию и перенос строки. Автор языка решил исправить эту несправедливость. В языке всё наоборот: три пробельных символа (Space, Tab и LF) – единственные символы языка, все остальные игнорируются и могут использоваться как комментарий.
Язык имеет развитую систему из 22 команд, сгруппированных по типу. Тип команды определяется префиксом: Space – операции со стеком, Tab-Space – арифметические операции, Tab-Tab – операции доступа к куче, Tab-LF – операции ввода-вывода, LF – управление потоком выполнения программы. Используется только один тип данных – целые числа в двоичной записи. Например, число 10 представляется последовательностью Space-Tab-Space-Tab-Space-LF.
Писать программу не очень удобно, поэтому был создан язык Ассемблера, который после трансляции получает программу на Whitespace (хорошее упражнение). Популярный редактор Notepad++ позволяет отображать все символы, и программы делаются видимыми.
Рекорд по минимальному алфавиту принадлежит языку программирования Unary. В его алфавите всего один символ 0!
Что же делает интерпретатор с такой программой? Он подсчитывает число нулей, переводит его в двоичную систему и разбивает двоичное представления на группы по 4 знака. Каждая такая группа становится командой в языке Brainfuck (>– 1000; < – 1001; + – 1010; - – 1011; . – 1100; , – 1101; [– 1110; ] – 1111). Дальше работает интерпретатор Brainfuck.
Так, программа +++[++>+++>+>+++<<<<] из эпиграфа представляется 84-значным числом 101010101010111010101010100010101010101010001010100010101010101010011001100110011111. Таким образом, исходная программа на Unary должна состоять из 12896389190059366252386719 нулей. Если предположить, что за секунду компьютер будет вводить миллион нулей, то для ввода этой программы потребуется более 400 миллиардов лет!
Некоторые языки подражают каким-либо текстам на естественных языках. Например, язык программирования Shakespear был создан авторами в процессе учебных занятий по синтаксическому анализу. Программы похожи на пьесы Шекспира: список действующих лиц – это объявление переменных, реплики персонажей – это команды. Программа делится на сцены и акты, номера которых служат метками для условных и безусловных переходов. Ремарки к сценам описывают переменные-персонажи, участвующие в сцене, при этом они могут входить или выходить.
Язык включает арифметические действия, ввод-вывод символов и чисел, условные и безусловные переходы и элементарные действия со стеком.
Константы в
Shakespeare http://progopedia.ru/language/shakespeare/
задаются как существительные с набором прилагательных при них. Существительное
соответствует значениям 1, 0 или -1 в зависимости от того, хорошее оно, нейтральное
или плохое. Каждое прилагательное при нём умножает константу на 2. Некоторые
реплики, как в приведенном ниже фрагменте с Дездемоной и Периклом, означают
определенные действия. Например, «Speak
your mind!» – это
вывод
символа:
use Lingua::Shakespeare;
Shakespeare-style Encoded
Message.
Desdemona, the
talker.
Pericles, a shut-pan with notable
patience.
Act I: Message output.
Scene I: Letter
by letter.
[Enter Desdemona
and Pericles]
Desdemona:
You
honest reddest gentle loving sweet brave rose!
You are
as bottomless as the sum of yourself and a rural red purple hamster!
Speak your mind!
. . .
Оригинален язык программирования Chef http://progopedia.ru/language/chef/ , который можно было назвать языком шеф-повара. Программы на этом языке — это рецепты, в которых ингредиенты представляют переменные, а миски и формы для выпечки — стеки, в которых хранятся их значения. Задача программиста получить вкусное блюдо.
Самый маленький язык программирования — HQ9+, программы на нём почти ничего не могут делать. Авторы исходили из минимальных требований к языку. Первое —программа должна уметь выводить «Hello, world!»: без этого не обходится ни один учебник по программированию. Второй требование – на языке можно написать куайн: любой приличный язык должен уметь это делать. Третье – возможность реализации как можно более короткой программы, печатающей текст песни «99 Bottles of Beer on the Wall» (шуточная популярная песня середины прошлого века в США: «99 бутылок стояло на стене. Одна упала. 98 бутылок стояло на стене …»). В итоге получился язык HQ9+, в названии которого перечислены и все его операторы: H выводит «Hello, world!», Q выводит Q (вот и куайн), 9 выводит песню, а + увеличивает сумматор на 1 (должны же быть какие-либо арифметические действия!). На страничке автора приводится и интерпретатор этого языка, написанный на языке программирования Ocaml.
Современная объектно-ориентированная версия HQ9++ включает операцию ++, создающую объект. Но согласно принципу инкапсуляции, объект недоступен.
Язык COW подражает языку животных, в данном случае коровам. В языке двенадцать слов: moo, mOo, moO, mOO, Moo, MOo, MoO, MOO, OOO, MMM, OOM, oom. Слова очень понятны и мнемоничны, например OOO – обнулить ячейку, MOo – операция уменьшения ячейки на 1, MoO – операция увеличения ячейки на 1 и т.д.
Вот программа, вычисляющая последовательность чисел Фибоначчи:
MoO moO MoO mOo
MOO OOM MMM moO moO MMM mOo mOo moO
MMM mOo MMM moO moO MOO MOo mOo
MoO moO moo mOo mOo moo
Программы на подобном языке для орангутангов состоят только из возгласов «Ook?», «Ook!» и «Ook.».
Из отечественных эзотерических языков отмечают «AvtoKod Ingenera for Minsk family of computers» (AKI), smilescript (язык, состоящий из одних смайликов). С современной точки зрения некоторые старые языки типа AKI могут некоторым показаться эзотерическими, хотя тот же AKI в свое время использовался на практике.