Сегодня мы откажемся от традиционных средств коммуникации и научимся программировать при помощи зверей, плодов и десертов. Мы испытаем просветление, поймем, как пиво помогает избежать ошибок, и, постепенно утрачивая рассудок, составим интерпретатор языка Brainfuck из девяти лимонов, двадцати двух арбузов и шести шоколадок.

 

Язык будущего

Однажды я прочитал, что за всю человеческую историю письменность изобрели всего два или три раза. Все остальное — это производные того, что тысячи лет назад придумали в Шумере, Китае и, возможно, в долине Инда. Если это в самом деле так, то шумерам пора подвинуться. Не так давно появилась четвертая письменность, превосходящая предшественников по всем статьям. Речь, конечно, об эмодзи.

Нелепость и ограниченность этой смартфонной азбуки не должна смущать. Пиктограммы, которыми пять тысяч лет назад пользовались жители долины Инда, были куда нелепее и при этом не позволяли записать даже простое слово «баклажан». А эмодзи не только позволяют, но еще и наполняют эту почтенную сельскохозяйственную культуру новыми удивительными смыслами.

У людей, связанных с компьютерами, эмодзи должны вызывать особенно живой интерес. Эксперты давно предрекают, что обыкновенные ПК будут вытеснены смартфонами и планшетами. И что тогда станут делать программисты? Мучительно вводить при помощи экранной клавиатуры зарытые на третьем уровне фигурные скобки? Готовиться можно начинать прямо сейчас, и один из способов — полностью избавиться от печатных команд и использовать вместо них эмодзи.

Гуглу известны по меньшей мере три языка программирования, создатели которых заменили устаревшие буквы и цифры на эмодзи: Emojicode, Emojilisp и 🍀. Emojilisp скучноват. У клевера нет документации. Выбор очевиден — учим эмодзикод!

 

Твой первый фрукт

Первая программа, которую пишут на любом языке программирования, — это Hello World. Не будем изобретать велосипед и последуем традиции. Вот как Hello World выглядит на эмодзикоде.

Попробуем разобраться, что мы видим.

Клетчатый флажок 🏁 (:checkered_flag:) — это обозначение метода, с которого интерпретатор начнет исполнение программы. Его можно сравнить с методом main в Java. В эмодзикоде, как и в Java, не бывает неприкаянных функций, и к клетчатому флажку это относится в полной мере. В ранних версиях языка программисту полагалось явно декларировать класс, к которому относится этот метод, но потом синтаксис упростили. Этот класс по-прежнему есть, но теперь его автоматически добавляет сам компилятор.

Ухмылка 😀 (:grinning:) — это метод объекта строка, который распечатывает ее содержимое. Для вызова метода сначала указывают его эмодзи, а затем объект, к которому происходит обращение. Им в данном случае служит литерал строки «Hello World!». Он окружен квадратиками с буквами abc: в эмодзикоде они заменяют кавычки.

И наконец, виноград и арбуз — две главные ягоды эмодзикода. В этом языке они играют ту же роль, что и фигурные скобки в си или JavaScript или ключевые слова begin и end в Pascal. Любой блок кода должен быть заключен между ними. В начале — виноград 🍇 (:grapes:). В конце — арбуз 🍉 (:watermelon:).

При первом столкновении с эмодзикодом хочется понять принцип, по которому создатель языка отбирал эмодзи. Не стоит — это не пойдет на пользу психике. Примерно с той же проблемой сталкиваются люди, которые изучают иероглифическую письменность. Они узнают, что, например, японский иероглиф 鮮, означающий свежесть, состоит из рыбы и овцы, а стыд (恥) — из уха и сердца. Какая связь между стыдом и ухом? При чем тут рыба и овца? Это невозможно понять — только запомнить.

Так и с эмодзикодом. Запоминай: виноград и арбуз. Смысла нет.

Компиляция и исполнение

Для начала нужно скачать сам эмодзикод с его страницы на GitHub. Выбирай самую свежую версию: в новых бетах меньше ошибок, чем в старых релизах.

Исходные файлы на эмодзикоде имеют расширение .emojic. Перед запуском их нужно скомпилировать.

emojicodec hello.emojic

Компилятор сохраняет полученный байт-код в файл с расширением .emojib. Его нужно запустить при помощи интерпретатора.

emojicode hello.emojib

И hello.emojic, и все прочие программы из этой статьи можно взять отсюда.

 

Медведь с пирогом и двумя пистолетами

Написав Hello World, понимаешь: будущее пока не настало. Мы всё еще программируем при помощи компьютеров, которые совершенно не приспособлены для ввода эмодзи. Это серьезная проблема. Если мы хотим чего-то достичь, нам потребуется программа, которая позволит писать программы на эмодзикоде без самих эмодзи.

Это хорошая идея для следующего примера. Давай напишем утилиту, которая открывает файлы с исходниками, где вместо эмодзи указаны их короткие названия. С исходниками в таком виде проще работать в текстовом редакторе. Наша утилита заменит короткие названия на соответствующие символы, после чего передаст полученный эмодзикод компилятору. Пока мы ее делаем, заодно познакомимся с основными конструкциями языка.

Для начала определим класс эмодзи. Список названий, который потребуется для переработки исходных файлов, будет состоять из объектов именно этого типа.

Желтый старичок 👴 (:older_man:) отмечает комментарии. Встретив его, компилятор сразу же переходит к следующей строчке. Многострочные комментарии удобнее делать при помощи старушек 👵 (:older_woman:). Все, что попадает между двух старушек, будет проигнорировано.

Дальше идет главное: декларация класса.

Она всегда начинается с едва различимого на белом фоне белого кролика 🐇 (:rabbit2:). За ним следует эмодзи класса. В нашем случае это подсолнух 🌻 (:sunflower:), но можно было бы выбрать и другой значок. И наконец, виноград, значение которого мы уже разбирали. Весь код от него и до ближайшего арбуза относится к подсолнуху.

Пирог 🍰 (:cake:) служит для объявления переменных.

После пирога необходимо указать название и класс переменной. Название может состоять из любых символов, кроме пробелов и эмодзи; русские буквы тоже разрешены. Что касается класса, то наши переменные относятся к классу abcd 🔡 (:abcd:), то есть строки. Этот класс определен в стандартной библиотеке эмодзикода.

В эмодзикоде к переменным объекта может обращаться только его собственный код. Чтобы их значения можно было узнавать или менять из других мест, требуются модифицирующие методы: геттеры) и сеттеры. У подсолнуха таких метода два: цветок 🌼 (:blossom:) сообщает значение переменной эмодзи, а этикетка 🏷 (:label:) — значение названия.

Свинья 🐖 (:pig2:) в начале строки — это признак декларации метода. В примере рядом с ней находится цветок 🌼 (:blossom:). Этот эмодзи будет использоваться в качестве названия метода. Его, как и эмодзи класса, выбирает программист.

После названия метода могут быть объявлены его аргументы и их типы. Цветок из примера не требует аргументов, поэтому их тут нет, но он возвращает значение. Тип возвращаемого значения необходимо сообщить после стрелки вправо ➡ (:arrow_right:). В нашем случае это строка 🔡 (:abcd:).

Между виноградом и арбузом заключен весь код метода. Код цветка из примера — это единственная строчка, которая при помощи яблока возвращает значение переменной объекта с названием эмодзи (мы определили ее выше). Яблоко 🍎 (:apple:) в эмодзикоде соответствует ключевому слову return в других языках.

При создании экземпляра класса все переменные объекта должны быть инициализированы, иначе компилятор сообщит об ошибке. Для этого служит особая разновидность метода — инициализатор. Декларация инициализатора начинается с кота 🐈 (:cat2:), а не со свиньи, как у обычного метода.

Инициализатор с именем капля 💧 (:droplet:) принимает два аргумента: @эмодзи и @название. Типы аргументов указаны сразу после их имен (в примере оба аргумента — строки). Обычные инициализаторы не возвращают значений, поэтому стрелки вправо в декларации капли нет.

У класса может быть несколько инциализаторов, принимающих различные аргументы, но у каждого из них, как и других методов, должно быть свое собственное имя, не совпадающее с другими.

Заварной крем 🍮 (:custard:) нужен для того, чтобы присваивать переменным новые значения — примерно как ключевое слово let в бейсике. За кремом идет название изменяемой переменной. Она приравнивается к выражению, которое занимает остаток строчки. В примере переменной эмодзи присваивается значение аргумента @эмодзи, а переменной название — аргумента @название.

Последний метод подсолнуха, который осталось разобрать, — это ухмылка. Подобно ухмылке строк, ухмылка подсолнуха будет распечатывать значение объекта. У этого метода нет аргументов, и он не возвращает значений, поэтому в его декларации не указаны ни аргументы, ни тип возвращаемого значения.

В коде присутствует пара незнакомых эмодзи: печенье 🍪 (:cookie:) и красный крестик ❌ (:x:). Красный крестик в литералах строк — это аналог обратной дроби в других языках. Вместо \n (перевод строки) или \t (табуляция) в эмодзикоде пишут :x:n или :x:t. Печенье же можно сравнить с оператором . в PHP. Оно тоже служит для объединения строк. Принцип действия, впрочем, иной: два печенья ставят по краям списка складываемых строк, а не между его элементами, как точки в PHP.

Пока все просто. Теперь добавим класс, который будет заниматься кое-чем посложнее: загружать библиотеку эмодзи из текстового файла, где эмодзи и их названия сохранены в виде списка значений, разделенных табуляцией (tab separated values).

Вот код этого класса.

В классе книги 📚 (:books:) объявлена только одна переменная — список. Она относится к классу десерт 🍨 (:ice_cream:), который служит для хранения списков — стандартной коллекции объектов, к элементам которой можно обращаться по их порядковому номеру. В эмодзикоде размер списка может изменяться во время работы программы.

Десерт — это обобщенный класс, или дженерик (generic). Его можно использовать для того, чтобы создать список объектов любого типа. Однако тип элементов должен быть указан при декларации переменной. Для этого после эмодзи десерта ставят ракушку 🐚 (:shell:), а затем эмодзи класса элементов.

Переменная список — это список подсолнухов, поэтому после десерта и ракушки идет подсолнух. А если бы нам понадобился, например, список строк, то описание его типа состояло бы из десерта, ракушки и abcd.

В инициализаторе книг мы первым делом создаем новый список подсолнухов и сохраняем его в словаре. Новые объекты создаются при помощи синего ромба 🔷 (:large_blue_diamond:), после которого указан сначала класс нового объекта, а затем эмодзи инициализатора. Нас интересует лягушка 🐸 (:frog:) — это инициализатор десерта, который создает пустой список.

Затем мы открываем файл с полученным в качестве аргумента именем, читаем его содержимое и сохраняем загруженный текст в переменной исходник. Это всего одна строчка, но в ней происходит очень много нового и непонятного.

Начнем с мороженого. Как и крем, мороженое служит для присваивания. Переменные, которые инициализированы мороженым, «замерзают» и не могут быть изменены. Инструкция к языку рекомендует по возможности отдавать предпочтение мороженому, а не крему. В этом случае некоторые ошибки всплывут еще на стадии компиляции (по крайней мере, в теории). Компилятор следит за соблюдением этого правила и выдает предупреждения, когда замечает необновляемые переменные без мороженого.

Исходник — это переменная, созданная в области видимости инициализатора, а не класса. Обрати внимание, что у нее не было пирога. Это нормально. В таких случаях переменная создается автоматически, а ее тип определяется типом присваиваемого значения. Несмотря на такие вольности, эмодзикод сильно типизирован. Это, среди прочего, значит, что тип переменной задается раз и навсегда. Компилятор не позволит изменить значение переменной, которая хранила, например, строку, на, скажем, число.

Выражения удобно разбирать справа налево. Например, выражение, которое будет присвоено исходнику, делится на две основные части. Сначала страница 📄 (:page_facing_up: — стандартный класс для работы с файлами) загружает двоичные данные. Затем двоичные данные при помощи метода abcd преобразуются в строку.

Файл загружается при помощи классового метода картотека 📇 (:card_index:), который относится к классу страница. Классовые методы отличаются от обычных тем, что их можно вызывать прямо из класса, даже не создавая объекта. Чтобы это сделать, нужен пончик 🍩 (:doughnut:). Картотека принимает на входе один аргумент (строку @имя-файла) и возвращает двоичные данные. Но не просто так, а в конфетной обертке.

Конфеты — это, пожалуй, самая любопытная и в то же время самая раздражающая часть эмодзикода. Во многих языках принято сообщать об ошибках, возвращая невозможные значения — например, NULL в си или None в Python. Программист, вызвавший функцию, должен проверить ее результат и убедиться в том, что ошибки не было. В эмодзикоде эта практика формализована, и компилятор внимательно следит, чтобы ни один сомнительный результат не остался непроверенным. Для этого и нужны конфеты.

В эмодзикоде в случае ошибки методы возвращают так называемое ничто — уникальный объект, генерируемый при помощи молнии ⚡ (:zap:). Чтобы компилятор не жаловался на несовпадение типов, при декларации метода к типу результата прилагают конфету 🍬 (:candy:). Про такие значения говорят, что они в конфетной обертке. Внутри обертки может оказаться либо обещанный результат, либо ничто. Пока не развернешь, не узнаешь.

С точки зрения языка объект в обертке и сам объект относятся не к разным типам. Пока обертка на месте, компилятор не позволит его использовать, поэтому от нее нужно избавиться. Лучше всего это сделать при помощи мандарина с мороженым. Они исполняют условное присваивание, которое разворачивает значение, сохраняет его в переменной и вызывает один блок кода, если в обертке были данные, и другой, если внутри пусто (этот блок идеально подходит для описания реакции программы на ошибку).

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


Check Also

Как стартовал Nginx. Игорь Сысоев о разработке знаменитого веб-сервера

12 декабря 2019 года в московском офисе разработчиков Nginx прошел неожиданный обыск, о ко…

2 комментария

  1. Аватар

    IdFox

    25.08.2016 at 14:45

    За работу конечно плюс, но Боже мой… Что за бред!!! 🙂

  2. Аватар

    IdFox

    25.08.2016 at 14:47

    Я тут подумал…
    В сравнении с этим я даже готов признать, что есть программирование на 1С 🙂

Оставить мнение