INTERCAL
Последнее изменение этой страницы: 20:14, 1 июня 2016.
Парадигма | эзотерический |
---|---|
Спроектировано | Дон Вудс, Джеймс М. Лайон |
Первый появившийся | 1972 |
Лицензия | GNU General Public licence |
Портал: | http://www.catb.org/~esr/intercal/ |
Влияние | |
Befunge, Brainfuck, Malbolge, Unlambda, LOLCODE |
INTERCAL (абр. The Compiler Language With No Pronounceable Acronym - Компилируемый Язык С Непроизносимым Акронимом) - эзотерический язык программирования, созданный в 1972 году Дон Вудсом и Джеймсом Лионом в качестве шутки-пародии на языки программирования того времени. Несмотря на всю экзотичность, INTERCAL является полным по Тьюрингу, то есть, на нём можно вычислить всё, что и на «нормальном» языке программирования.
Содержание
История
Язык стандартизован в основном его первой реализацией, INTERCAL-72, на совместимость с которой ориентируются последующие реализации. Большинство реализаций привносят в язык что-то свое, будь это альтернативный формат ввода-вывода или элементы квантовых вычислений. Особенности оригинальной реализации (например, случайные ошибки или стилистику сообщений об ошибках) тщательно сохраняются и переносятся в новые реализации.
Особенности
INTERCAL предполагалось сделать сильно непохожим на все другие языки программирования. Операции, являющиеся базовыми в других языках, в INTERCAL имеют непонятный и излишний синтаксис. Согласно мануалу, самый простой способ записать число 65536 в 32-битную переменную -
DO :1 <- #0¢#256
Любой разумный программист сказал бы, что это абсурд. INTERCAL имеет много других особенностей, сделанных специально, чтобы сделать написание программ еще более неудобным для программиста: он использует такие выражения, как "READ OUT", "IGNORE", "FORGET", выражение "PLEASE". Последнее должно встречаться в программе достаточно часто, чтобы компилятор не посчитал автора излишне грубым, но не слишком часто, чтобы не быть излишне вежливым.
Несмотря на преднамеренную тупость и нелепость синтаксиса, INTERCAL полон по Тьюрингу: он может решить любую задачу, которую может решить универсальная машина Тьюринга. Хотя делает он это ужасно медленно. Так, программа вычисляющая все простые числа от 1 до 65536 работала 17 часов, в то время как программа, написанная на С, выполнила задачу за 0.5 секунды.
Справочное руководство
Современные эзотерические языки концентрируют свою необычность в самой сути языка, а их руководства ограничиваются сухими фактологическими описаниями команд и особенностей. В случае INTERCAL авторы пошли другим путем: в описании языка программирования "The INTERCAL Programming Language Reference Manual" наполнен эпиграфами из «Алисы в Стране Чудес» и ехидными комментариями, сказанными совершенно серьезным тоном. Кроме того, специально для этого языка авторы разработали систему эвфемизмов для использующихся служебных символов: ' — искра, " — кроличьи ушки, . — пятно, : — двойное пятно, , — хвост, ; — гибрид, $ — большие деньги, ~ — загогулина и т.д. (полный список прилагается к руководству)1.
От авторов
- INTERCAL — очень простой для изучения язык, и можно было бы предположить, что он будет хорош для инициации программистов-новичков. На самом деле он скорее подтолкнет программиста к поиску другой работы.
- В INTERCAL есть 5 операторов — 2 бинарных и 3 унарных. Впрочем, в некотором смысле все операторы бинарны, поскольку все они оперируют с двоичным представлением аргументов, но эта игра слов уводит нас в сторону от изложения.
- Приоритет операторов определяется следующим образом: (остаток страницы целенаправленно оставлен пустым — не забывайте, что создатели INTERCAL ставили своей целью отсутствие приоритетов).
- Каждой команде программы можно задать вероятность, с которой она будет выполняться при запуске программы. Кроме того, существуют команды, которые блокируют выполнение последующих команд определенного типа или изменения переменных.
- Числа выводятся в римской записи, а вводятся словами по одной цифре на любом языке, который поддерживает компилятор. Ввод-вывод символов реализован по-разному в разных компиляторах, и в любом случае слишком ужасен, чтобы описывать его здесь.
Сообщения об ошибках
В обычных языках сообщения об ошибках информативны и точно указывают на причины произошедшего. В INTERCAL — напротив, сообщения либо универсальны, либо подбрасывают неправильные причины ошибки. Ошибки INTERCAL так же ехидны, как и руководство, и без справочника не расшифровываются принципиально. Например:
- E252 «Я забыл, что я собирался сказать» — ошибка переполнения памяти при операциях ввода-вывода
- E182 «Кажется, тебе очень нравится эта метка» — ошибка использования одной и той же метки несколько раз.
- E405 «Программа отвергнута из соображений психического здоровья» сигнализирует об использовании команд многопоточности или вычислений с откатами без соответствующей опции компилятора
- E017 «Что, я правда должен с этим разобраться?» — об использовании констант неправильного диапазона,
- E127 «Говорить „абракадабра“ без волшебной палочки совершенно бесполезно» — о том, что стандартная библиотека не подключена.
Некоторые ошибки вообще не имеют аналогов в других языках:
- E079 «Программист недостаточно вежлив» и E099 «Программист слишком вежлив» относятся к количеству идентификаторов команды PLEASE в программе (никакой другой смысловой нагрузки идентификатор PLEASE не несет)
- E774 «Случайный баг компилятора» полностью соответствует своему названию — возникает случайно и при повторной компиляции обычно пропадает
- E995 «Что, я правда должен был это реализовать?» возникает при попытке выполнить код, который еще не написан (только не спрашивайте, как это можно сделать!)
Синтаксис
Ввод (WRITE IN
) и вывод (READ OUT
) не используют обычные форматы. В INTERCAL-72 инструкция WRITE IN принимает числа, записанные в виде английских слов-названий цифр (например SIX FIVE FIVE THREE FIVE), а READ OUT печатает в формате римских цифр. Более современные версии имеют собственные форматы.
Комментарии получаются, если в строке встречается идентификатор NOT или N'T. Такие строки будут игнорированы компилятором.
Структуры данных
INTERCAL-72 имел всего 4 типа данных: 16-битное целое (записывается с использованием .
так же "пятно"), 32-битное целое (:
"двойное пятно"), массив 16-битных целых (,
"хвост"), и массив 32-битных целых (;
он же "гибрид").
Программисту доступно 65535 переменных любого типа, от 1 до 65535. Причем каждая из этих переменных имеет собственный стек, над которым доступны операции push и pop (STASHed и RETRIEVEd, в терминологии INTERCAL), что сильно увеличивает возможную сложность структур данных. Массивы могут быть многомерными. Так же можно использовать целые константы от 0 до 65535 (записываются с помощью #
)
Операторы
В INTERCAL-72 всего 5 операторов.
Operator | INTERCAL-72 characters |
---|---|
INTERLEAVE / MINGLE | c backspace /
|
SELECT | ~
|
AND | &
|
OR | V
|
XOR | V backspace -
|
В противоположность большинству других языков, операторы AND, OR, и XOR - унарные, которые работают с последовательностью битов собственных аргументов; самый значительный бит (имеющий наибольший вес) результата получается путем применения оператора к самому значительному и самому незначительному биту входного аргумента, второй по значимости бит результата - оператор, примененный к 1 и 2 по значимости битам, третий по значимости бит - результат применения оператора к 2 и 3 по значимости битам аргумента и так далее. Оператор помещается между типом переменной или константы и ее номером, или просто внутри группирующих знаков.
SELECT и INTERLEAVE - инфиксные бинарные операторы; SELECT берет биты первого оператора, которые соответствуют "1" битам второго операнда и удаляет биты, которые соответствуют "0". Например, 51 (110011 в двоичном) SELECT 21 (10101) = 5 (101 в двоичном);
MINGLE чередует биты своего первого и второго операнда (в таком порядке, что самый младший бит второго операнда - самый младший бит результата)
В INTERCAL нет приоритета операторов. Для изменения порядка вычислений используются "группирующие знаки": '
("искра"), и "
("кроличьи ушки"). Знаки должны быть парными и не создавать двусмысленных ситуаций.
Управляющие структуры
В INTERCAL инструкции всегда начинаются с специального идентификатора: в INTERCAL-72 это может быть DO, PLEASE и PLEASE DO, каждая из которых делает одно и то же (но использование одной и той же конструкции много раз подряд может вызвать ошибку компиляции), или в инвертированной форме, если добавить в конец идентификатора NOT или N'T
В начале строки может быть записана необязательная строка в виде целого числа в круглых скобках - метка. В конце выражения можно записать строку в виде %50
, которая означает вероятность выполнения команды. (изначально 100%)
В INTERCAL-72, основные инструкции управления - это NEXT, RESUME, и FORGET.
DO (N) NEXT
переход на строку N и занесение следующей строки, которая не была выполнена, в стек.
DO FORGET expression
удаляет вхождения expression из головы стека.
DO RESUME expression
удаляет вхождения expression из стека вызовов и переходит на самую недавно помещенную в стек строку.
CLC-INTERCAL и новейшие версии C-INTERCAL так же поддерживают COME FROM (DO COME FROM expression)
и NEXT FROM, который делает то же самое, но еще и сохраняет адрес возврата.
Так же, повлиять на ход выполнения программы можно с помощью инструкций IGNORE и REMEMBER примененные к переменным (которые заставляют компилятор игнорировать команды присвоения значений переменной), а так же ABSTAIN и REINSTATE, заставляющие пропускать строки кода.
Примеры
Традиционная программа "Hello, world!" демонстрирует, как сильно INTERCAL отличается от обычных языков программирования. В Си это бы выглядело так:
#include <stdio.h>
int main(void) {
printf("Hello, world!\n");
return 0; // _exit(0);
}
Аналогичная программа на INTERCAL более длинная и запутанная:
DO ,1 <- #13
PLEASE DO ,1 SUB #1 <- #238
DO ,1 SUB #2 <- #108
DO ,1 SUB #3 <- #112
DO ,1 SUB #4 <- #0
DO ,1 SUB #5 <- #64
DO ,1 SUB #6 <- #194
DO ,1 SUB #7 <- #48
PLEASE DO ,1 SUB #8 <- #22
DO ,1 SUB #9 <- #248
DO ,1 SUB #10 <- #168
DO ,1 SUB #11 <- #24
DO ,1 SUB #12 <- #16
DO ,1 SUB #13 <- #162
PLEASE READ OUT ,1
PLEASE GIVE UP
Программа, инкрементирующая переменную .1:
(2000) PLEASE DO STASH .1 + .2 + .3
DO .2 <- #1
DO (2001) NEXT
(2001) PLEASE FORGET #1
DO .3 <- "?!1~#1'$#1"~#3
DO (2002) NEXT
PLEASE DO .2 <- !2$#1'~'#65535$#1'
DO .1 <- .1~#65534
DO (2001) NEXT
(2002) PLEASE DO (2003) NEXT
DO RETRIEVE .1
DO .3 <- .1
PLEASE DO .1 <- '?.2$.3'~'#0$#65535'
DO RETRIEVE .2 + .3
DO RESUME #2
(2003) DO RESUME .3
ISSN 2542-0356
Следуй за Полисом
Оставайся в курсе последних событий
Лицензия
Если не указано иное, содержание этой страницы доступно по лицензии Creative Commons «Attribution-NonCommercial-NoDerivatives» 4.0, а примеры кода – по лицензии Apache 2.0. Подробнее см. Условия использования.