Рефал-5λ

Введение в язык

Что такое РЕФАЛ? Что такое Рефал-5λ?

РЕФАЛ — язык функционального программирования, ориентированный на обработку символьных данных: анализ компьютерных программ, трансляция, обработка текста на естественных и искусственных языках.

Исходно, язык был предложен Валентином Фёдоровичем Турчиным в 1968 году как метаалгоритмический язык [1] — язык для описания семантики других языков программирования. Иначе говоря — некий псевдокод, что-то вроде математической нотации. Но потом появились и эффективные реализации РЕФАЛа для ЭВМ — он уже стал полноценным языком программирования.

От других функциональных языков (далее, ФЯ) РЕФАЛ отличает, прежде всего, использование особой структуры данных — объектного выражения. Большинство ФЯ используют однонаправленные списки — последовательности элементов, у которых доступен для непосредственной обработки только левый край. Т.е. допустимы только такие операции как посмотреть на первый элемент, отсечь первый элемент, построить новый список путём добавления элемента в начало исходного списка.

Извлечь последний элемент списка можно только путём последовательного отбрасывания первого элемента до тех пор, пока последовательность не станет пустой — последний отброшенный элемент и есть последний элемент списка. Чтобы конкатенировать (склеить) два списка, необходимо к началу второго списка приписывать элементы первого в обратном порядке.

РЕФАЛ же манипулирует двунаправленными последовательностями (которые называются объектными выражениями): для них допустимы не только одинаковые операции с обоими краями (отсечение элемента, приписывание элемента), но и конкатенации и даже разбиения в произвольных местах (см. далее про открытые e-переменные). И всё это примитивные операции! За счёт этого существенно повышается выразительность программ.

Другой важной особенностью РЕФАЛа является сопоставление с образцом (pattern matching). РЕФАЛ был одним из первых языков программирования (если не самым первым), использующим этот механизм для анализа структур данных. Функции на РЕФАЛе осуществляют анализ своего аргумента путём выбора одного из нескольких образцов, описывающих аргумент. Других способов анализа данных в языке не предусмотренно.

Диалект Рефал-5λ является, во-первых, точным надмножеством диалекта РЕФАЛ-5 [2], а это значит, что любая программа, которая работала на «классической» реализации [3] (в дальнейшем на реализацию [3] мы будем ссылаться как на классическую без кавычек), останется корректной и в Рефале-5λ.

Примечание. В актуальной версии не поддерживаются метафункции Ev-met, Up и Dn. Они будут реализованы в следующих версиях. Других ограничений нет.

Во-вторых, он является расширением РЕФАЛа-5, которое включает в себя функции высшего порядка, в том числе и вложенные функции, а также много хорошего, вкусного и полезного синтаксического сахара. Классический РЕФАЛ-5 не поддерживал вложенные функции по идеологическим соображениям, поскольку по Турчину должен был быть не только субъектом, но и объектом преобразований программ, причём допустимыми преобразованиями считались лишь те, которые можно описать при помощи «ручки и бумаги» [4].

Впервые вложенные функции появились в диалекте Refal-7, предложенном Сергеем Юрьевичем Скоробогатовым в 2006 году[5]. Язык Рефал-5λ имеет ограниченную поддержку вложенных функций Refal’а-7 — только вложенные безымянные функции. Но, как показывает практика, этого вполне достаточно.

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

Синтаксическим сахаром Рефала-5λ являются присваивания и блоки, и, как в дальнейшем будет показано, они выражаются через вложенные функции. Об этом и других видах «сахара» мы расскажем позже.

В-третьих, актуальная реализация Рефала-5λ не замкнута, в отличие от многих других реализаций РЕФАЛа. Это означает, что программист не ограничен набором «встроенных» функций языка, встроенный интерфейс с языком C++ позволяет программисту реализовывать и использовать в своих программах на Рефале функциональность, отсутствующую в стандартной библиотеке — работа с сетью, с базами данных, оконный интерфейс и т.д. Точно так же, как языки C/C++ допускают вставки кода на ассемблере, Рефал-5λ допускает вставки кода на C++ в исходных текстах на Рефале (т.н. «нативные вставки»). Разумеется, чтобы компилировать такие программы, необходим компилятор C++, но если вы нативными вставками не пользуетесь, компилятор C++ можно не устанавливать.

Актуальная реализация может компилировать программы как в промежуточный интерпретируемый код, так и в код на C++.

Установка и запуск

Автоматическая установка для Windows («setup.exe»)

Самый простой способ — скачать со страницы

https://github.com/bmstu-iu9/refal-5-lambda/releases/latest

файл setup-refal-5-lambda-***.exe и просто запустить его. В этом случае в профиль пользователя (в папку %APPDATA%) будет распакован архив с исполнимыми и библиотечными модулями Рефала, путь к каталогу с исполнимыми файлами будет прописан в переменную PATH для текущего пользователя. Для удаления Рефала с Вашей машины можно либо воспользоваться ярлыком «Refal-5-lambda» → «Uninstall Refal-5-lambda» в меню Пуск, либо обычным образом через «Панель управления» → «Программы и компоненты» или «Параметры» → «Приложения» → «Приложения и возможности» в зависимости от версии ОС Windows.

Сразу после установки можно запустить командную строку и использовать в ней команды rlc, rlc-core, rlmake, rlmake-core в любой папке.

Раскрутка «полускомпилированного» архива (Windows, Linux, macOS)

С той же страницы https://github.com/bmstu-iu9/refal-5-lambda/releases/latest можно скачать файл bootstrap-refal-5-lambda-***.zip и распаковать его в любой каталог. В архиве находится Рефал-5λ, скомпилированный в код на C++ и связующий интерпретируемый код. Для получение из него готовых исполнимых модулей потребуется установленный на машине компилятор C++98. Достаточно будет запустить файл bootstrap.bat на Windows или bootstrap.sh на Linux или macOS — после сборки в подпапке bin появятся готовые исполнимые файлы.

Примечание. После распаковки архива у исполнимых файлов может быть сброшен атрибут +x. Для его восстановления необходимо выполнить следующую команду:

chmod +x *.sh scripts/load-config.sh bin/sr{efc,make}

На платформе Windows первый запуск bootstrap.bat неизбежно приведёт к ошибке. Это так и должно быть: скрипт bootstrap.bat создаст конфигурационный файл c-plus-plus.conf.bat и предложит в нём прописать командную строку используемого Вами компилятора C++ (в нём уже есть несколько готовых закомментированных строк, используйте одну из них, если Ваш компилятор там перечислен). Повторный запуск должен всё собрать.

Примечание. На unix-like платформах (Linux, macOS) bootstrap.sh тоже создаёт конфигурационный файл c-plus-plus.conf.sh, но в нём уже по умолчанию прописан вызов GCC C++. При желании можете заменить его, например, на Clang.

Содержимое этого «полускомпилированного» архива также доступно в виде хранилища на GitHub по адресу https://github.com/bmstu-iu9/simple-refal-distrib. Его можно склонировать при помощи команды

git clone https://github.com/bmstu-iu9/simple-refal-distrib

и далее развернуть при помощи описанной выше процедуры.

Сборка из исходников

Исходники клонируются командой

git clone https://github.com/bmstu-iu9/refal-5-lambda

и собираются аналогично «полускомпилированному» дистрибутиву выше (запускается bootstrap.***, правится c-plus-plus.conf.***, если необходимо, и т.д.).

Для развёртывания достаточно иметь любой компилятор C++98. Сборка тестировалась на BCC 5.5, Microsoft Visual C++ различных версий, GCC C++, Clang, Open Watcom. Поддерживаемые операционные системы: Windows XP и новее, GNU+Linux (дистрибутивы не старше пяти лет), macOS (не знаю, каких версий, не я тестировал). Поддерживаемые архитектуры процессоров — x386 и amd64 (работа на big-endian-машинах в текущей версии не поддерживается).

Важно! Скачивать исходные тексты с GitHub нужно исключительно путём клонирования. Интерфейс сайта предоставляет возможность скачать файлы в виде zip-архива, но в распакованном архиве bootstrap.*** работать не будет. Скрипт boostrap.*** в репозитории refal-5-lambda предполагает, что к папке distrib подключён как подмодуль репозиторий simple-refal-distrib и его можно проинициализировать командами git submodule init и git submodule update. В скачанном архиве папка distrib останется пустой, а значит, раскрутить исходники не удастся. Возможно, в следующих версиях это будет исправлено.

Настройка текстовых редакторов

В дистрибутиве имеются конфигурационные файлы, обеспечивающие подсветку синтаксиса для различных текстовых редакторов. Если Вы устанавливали Рефал на Windows, используя автоматическую установку («setup.exe»), то папка с конфигурационными файлами доступна через меню Пуск: «Refal-5-lambda» → «Plugins for text editors». Во всех остальных случаях (полускомпилированный архив, склонированные репозитории) файлы настроек текстовых редакторов доступны в подпапке editors.

На данный момент полностью поддерживается подсветка синтаксиса Рефала-5λ и расширенного Простого Рефала для редакторов Vim и встроенного в Far (плагин Far Colorer). Для некоторых других текстовых редакторов (Code::Blocks, Kate, Notepad++, Sublime Text 3) поддерживается только раскраска синтаксиса расширенного Простого Рефала, причём, возможно, неактуальной версии.

Для Рефала-5λ существует плагин для IDEA, обеспечивающий подсветку синтаксических ошибок и автодополнение, он доступен по ссылке:

https://github.com/bmstu-iu9/RefalFiveLambdaPlugin

Существует поддержка классического РЕФАЛа-5 для текстового редактора SciTE, она доступна по ссылке http://www.refal.net/~belous/refscite.htm.

Компиляция простой программы

Откройте Ваш любимый текстовый редактор и введите в нём следующий текст:

$ENTRY Go {
  = <Prout 'Hello, World!'>;
}

и сохраните под именем hello.ref. Затем откройте командную строку в папке с этим файлом и введите в ней следующую команду:

rlc hello.ref

В папке должен появиться файл hello.exe (на unix-like системах он будет называться просто hello без расширения, но будет иметь флаг +x — признак исполнимости).

Его можно запустить следующим образом на Windows:

hello.exe

На unix-like:

./hello

В обоих случаях она напечатает строку Hello, World!.

О смысле написанного в файле hello.ref мы поговорим в следующем разделе.

Ссылки

  1. В. Ф. Турчин. Метаалгоритмический язык. Кибернетика №4, 1968, Cтр. 45-54. Доступно в Интернете: http://pat.keldysh.ru/~roman/doc/Turchin/1968-Turchin--Metaalgoritmicheskij_yazyk--ru.pdf
  2. V. F. Turchin, REFAL-5 programming guide and reference manual, New England Publishing Co., Holyoke, 1989 В интернете доступен перевод на русский язык (описывается устаревший синтаксис): http://refal.ru/rf5_frm.htm, также доступно переработанное и расширенное издание 1999 года: http://refal.botik.ru/book/html.
  3. V. F. Turchin, D. V. Turchin, A. P. Konyshev, A. P. Nemytykh, Refal-5: Sources, Executable Modules, ([online]: http://www.botik.ru/pub/local/scp/refal5/), 2000
  4. Аркадий Климов, письма в рассылку refal@botik.ru. Доступно в архиве рассылки: https://www.mail-archive.com/refal@botik.ru/msg00044.html, https://www.mail-archive.com/refal@botik.ru/msg00055.html
  5. Скоробогатов С.Ю. , Чеповский А.М. Язык Refal с функциями высшего порядка // Информационные технологии, 2006. № 9. Доступно в Интернете: https://waybackmachine.org/web/20070719175259/http://iu9.bmstu.ru/science/refal.pdf