Все на дно. Смоляная яма Тьюринга

image
Машина Тьюринга во всей своей красе.

Какой язык программирования лучше всего выбрать? Само собой, очень часто выбор языка зависит от того, для чего пишется та или иная программа, да и просто от личных пристрастий программиста. Выбор, как правило, идёт среди более-менее известных языков, начиная от различных вариаций C и заканчиваться может где угодно. Хотя, безусловно, ту или иную вещь на том или ином языке будет гораздо сложнее написать, чем на другом. Но как насчёт таких языков, где трудно написать в принципе любую вещь, поскольку, например, синтаксис состоит из восьми команд? Такие языки называются «Эзотерическими языками программирования», или, по-простому, «Смоляной ямой Тьюринга». Предлагаю тут же и посмотреть, какие черти водятся в этом тихом омуте.
Для начала — при чём тут Тьюринг? Существует такая абстрактная вычислительная машина, как «Машина Тьюринга», являющаяся визуализацией алгоритма. Состоит она из бесконечной ленты с ячейками и головки записи, которая может двигаться по ленте и изменять значения ячеек согласно неким заранее прописанным правилам. Очень напоминает то, как работает программирование, не так ли? Из этого растут ноги критерия «Полнота по Тьюрингу», т.е., возможность при помощи того или иного языка программирования (т.е., алгоритма движения головки по ленте) реализовать на нём любую вычислимую функцию. Тогда что за «смоляная яма»?

Как уже упоминалось выше, «Смоляной ямой Тьюринга» (а.к.а. «Трясина Тьюринга», «Turing tarpit») называют языки программирования которые обладают очень бедным или весьма… нестандартным синтаксисом. При этом каждый из них является полностью функциональным и Тьюринг-полным языком. Зачем они тогда вообще существуют, если ими пользоваться сложно, неудобно, и вообще есть куча других языков? Ну, вопрос открытый. Некоторые из них (как Brainfuck) используются для весьма конкретных целей, но большинство всё-таки были написаны на спор или «по приколу». Как минимум, один (Malbolge) был специально написан для издевательств над программистами.

Нет, ну посудите сами. Во-первых, Malbolge, будучи двоичным, все операции проводит с цифрами троичными. Во-вторых, после выполнения каждой инструкции, она шифруется целых два раза. В-третьих, из восьми команд одна не делает ничего, одна — завершает программу, одна нужна для перехода к другой ячейке, а все оставшиеся служат для выполнения всякой чертовщины в духе «Сдвинуть регистр d на одну троичную цифру вправо и сохранить в регистры d и a». Просто для примера — первая программа на Malbolge появилась спустя два года после того, как язык был написан. На данный момент программ на Malbolge всего пять — две версии «Hello, world!», программа, выводящая свой собственный код на экран (был сгенерирован другим компьютером за 14 лет), «Кошка» (программа, немедленно выводящая всё, что печатает пользователь), а так же текст песни-цикла »99 бутылок пива». Язык, на секундочку, был написан в 1998 году.

Если что, «Hello World» выглядит вот так:

('&%:9]!~}|z2Vxwv-,POqponl$Hjig%eB@@>}=

`CB]V?
Tx

Полной противоположностью ему является Brainfuck. Это максимально простой язык для освоения, с максимально простыми командами, которых, кстати, тоже всего 8. Это буквально виртуальная машина Тьюринга — синтаксис Brainfuck состоит из команд сдвига головки записи влево-вправо, уменьшения-увеличения текущего значения на единицу, чтения-записи и организации while-цикла. При этом, опять же, Тьюринг-полный (Написать эмулятор Brainfuck на некотором языке — автоматически доказать его полноту). В основном его используют для объяснения самых-самых основ программирования (теми, кто про него знает), написания компиляторов, интерпретаторов, изучения оптимизаций. Ну, и по-хорошему, именно с рассказа о Brainfuck надо было начинать статью — ведь именно он в 93-ем создал компьютерную эзотерику, нечто вроде гимнастики на ниве научного креатива — «как бы так извернуться, чтобы все вокруг обалдели».

image
Hello World на Brainfuck

Апофеозом всего этого будет Whitespace, так же известный, как «Brainfuck для шпионов». Особенностью этого языка является то, что весь его синтаксис состоит из пробелов, табуляций и переносов строки. Код на Whitespace буквально выглядит, как чистый лист. При этом, набор команд достаточно широк — целых 24 штуки. Чисто теоретически, если это не какой-нибудь Python или Forth, программу на Whitespace можно спрятать внутри другой программы и наслаждаться зрелищем. Стоит также отметить, что большинство программ на этом языке были получены при помощи ассемблера, а не написаны вручную (хотя такие тоже есть).

image
Hello World на Whitespace. Синее — табуляция, красное — пробел,

Казалось бы, что может быть бредовее языка, код которого является леденящей душу пустотой? Вот оно, дно смоляной ямы достигнуто.

И тут снизу постучали. Дамы и господа, встречайте Shakespeare! Язык, который — я сейчас не шучу — имитирует собой пьесы Шекспира. Переменные в нём задаются в разделе персонажей, им обязательно присваиваются имена. Для вывода используются команды в духе «Open your heart» (Открой сердце своё) или «Speak your mind» (Что у тебя на уме?). Но больше всего мне нравится то, как устроены операции с числами. В Shakespeare каждое существительное имеет значение либо 1, либо 0 (зависит от того, красив ли предмет\понятие, или нет. Например, «Цветы» имеют значение 1, а некрасивая «Свинья» — 0. У нейтральных существительных значение 1). Каждое прилагательное удваивает значение (а следующее удваивает уже новое значение). Значения же присваиваются обращением к персонажу-переменной (т.е., буквально «ты»), сопровождаемой, например, потоком оскорблений. Арифметические операции, к счастью, работают нормально (»Ты — разность меж квадрата поганой твари и осла» и т.д.). Поскольку на сцене могут находится только два персонажа, периодически одного из них надо убрать командой [Exit персонаж] и ввести другого командой [Enter персонаж]. Все персонажи прогоняются командой [Exeunt]. Упрощая — перед нами всё тот же Brainfuck с его минимальным синтаксисом, только гораздо более заморочный.

Конечно, существует ещё множество языков, написанных «по приколу», как я уже говорил раньше. Например, многочисленные подражатели Brainfuck’а, такие, как многозадачный Brainfork, F*ckF*ck (каждая инструкция — неподцензурное словцо со звездочкой) или DoubleFuck. В жанре чистого фарса возникает язык Whenever, инструкции которого выполняются в случайном порядке, а не в том, в котором записаны. Схожие идеи заложены в остросатирической Java2k– подобно тому, как оригинальная Java от Sun «освобождает память в случайные интервалы времени», программы Java2k имеют несколько альтернатив каждой функции, а какую из альтернатив выполнить — решается случайным образом во время выполнения программы. В той же парадигме «случайного» или «побочного» программирования построен Fish Programming Language (Язык Программирования Рыбки) вся работа происходит на изображении рыбки, разделенном на множество частей, случайным образом меняющих свой цвет.

И вообще, не погружайтесь в смоляную яму Тьюринга — там можно сделать всё, но ничего из этого вам не дастся просто.

P.S. Как оказалось, Turing Tarpit — это ещё и музыкальная группа. Вот обложка их альбома (а так же состояние разработчика на Brainfuck)

image

p-u9l27ynelxi92bcmdxhu76ma8.png

© Habrahabr.ru