Содержание


Guile — универсальный инструмент программирования. Часть 1. Как с ним обращаться

Comments

Серия контента:

Этот контент является частью # из серии # статей:

Следите за выходом новых статей этой серии.

Этот контент является частью серии:

Следите за выходом новых статей этой серии.

GNU Guile представляет собой интерпретатор и "по совместительству" виртуальную машину языка программирования Scheme, то есть, его можно использовать и как командную оболочку в интерактивном режиме, и как встраиваемый в программы на компилируемых языках инструмент создания расширений. Lisp-синтаксис не всем нравится и не всем подходит (вплоть до полного неприятия), тем не менее — по моему мнению, Guile заслуживает внимания.

1. Общая характеристика и история создания Guile

В Википедии название языка программирования Guile определяется, как аббревиатура, раскрываемая следующим образом: GNU's Ubiquitous Interactive Language for Extension — повсеместно применяемый (или широко используемый; "вездесущий") интерактивный язык для расширений от GNU. В то же время английское слово "guile" имеет значения: "обман; вероломство, коварство; хитрость, уловка". Такие вот неоднозначные толкования...

GNU Guile предлагает реализацию Scheme в соответствии со стандартом R5RS (Revised^5 Report on the Algorithmic Language Scheme). Первая версия интерпретатора Guile появилась в 1993 году.

Истоки Guile следует искать в так называемой "the Tcl Wars", дискуссии, развёрнутой Ричардом Столлманом (Richard M.Stallman), который утверждал, что Tcl в качестве языка скриптов для приложений и расширений не обладает требуемой мощностью, и предложил заменить его интерпретатором Scheme (которого в то время пока ещё не было). Идею поддержал Том Лорд (Tom Lord), и вскоре появились первые версии на базе SIOD (Scheme In One Day) и ядра интерпретатора SCM, написанного Обри Джаффером (Aubrey Jaffer). А название Guile придумал Ли Томас (Lee Thomas) в ходе обсуждения в соответствующей Usenet-группе.

1.1. Общая функциональная характеристика Guile

Как уже было сказано выше, Guile может выступить в роли командной оболочки, принимая вводимые пользователем выражения, вычисляя их и выводя результаты, или как средство выполнения скриптов, когда код Scheme считывается из файла и выполняется. Кроме того, в распоряжение разработчиков предоставляется библиотека libguile, позволяющая включать в приложения полноценный интерпретатор языка Scheme. Таким образом, Guile применяется как универсальный, многоцелевой язык расширений.

2. Где взять и как установить

Самую последнюю версию Guile можно взять непосредственно на основном ftp-сервере GNU, то есть по адресу ftp://ftp.gnu.org/pub/gnu/guile-1.8.7.tar.gz.

Альтернативный вариант — установка пакетов Guile из репозиториев используемого дистрибутива, например, для Fedora предлагается следующий набор: guile, guile-devel, а также дополнительные пакеты: guile-lib (guile-модули, своего рода "аналог CPAN"), guile-cairo (графика) и guile-gnome-platform (для создания Gnome-приложений). Правда, при этом вы получаете более старую версию — 1.8.6, которая и будет рассматриваться в данной статье.

3. Практическое применение Guile. Простые примеры

3.1. Проверка работоспособности интерпретатора

После того, как пакеты Guile установлены, имеет смысл проверить корректность работы интерактивного интерпретатора, запустив его и выполнив несколько различных команд. Для наглядности весь тестовый сеанс показан на рисунке ниже.

Рис.1. Проверка работы интерпретатора Guile
Рис.1. Проверка работы интерпретатора Guile
Рис.1. Проверка работы интерпретатора Guile

Для "тестирования" были использованы арифметические операции (умножение, сложение и извлечение квадратного корня) и определение функции для вычисления факториала. Обратите внимание на то, как отреагировал интерпретатор, когда имя функции было введено с опечаткой. Литерал factorail был классифицирован, как "несвязанная переменная", то есть, неопределённая переменная, не содержащая никакого значения. Для выхода из интерпретатора я воспользовался стандартной функцией (quit), хотя можно просто нажать комбинацию клавиш Ctrl+D.

3.2. Теперь скрипты

Guile-скрипт принципиально не отличается от скриптов, написанных на языках командных оболочек shell или на интерпретируемых языках Perl, Python, AWK и т.п. Точно так же в самом начале указывается ссылка на требуемый интерпретатор, затем следуют выполняемые команды (инструкции). Вот простейший пример скрипта, вычисляющего тот же факториал:

#!/usr/bin/guile -s
!#
(display "Проверка работы Guile-скрипта")
(newline)
(define (factorial n)
  (if (zero? n) 1
    (* n (factorial (- n 1)))))
(display (factorial (string->number (cadr (command-line)))))
(newline)

Сохраните этот исходный код в файле с именем test-guile01, сделайте этот файл выполняемым, после чего можете проверить, как он работает:

$ ./test-guile01 7
Проверка работы Guile-скрипта
5040

Предполагается, что читатели данной статьи знакомы с основами синтаксиса языка Scheme (Lisp), поэтому я не буду подробно объяснять, что делает каждая строка приведённого выше скрипта. Учебников и руководств по основам Lisp в Сети вполне достаточно, а при желании можно найти и печатные издания.

Единственное замечание — ключ -s в первой строке определяет, что команды для интерпретатора Guile должны быть считаны из файла и выполнены как скрипт.

3.3. Особенности работы в интерактивном режиме

3.3.1. Readline — история команд

Так же как в командной оболочке shell, в Guile существует возможность ведения истории команд. Но этот режим по умолчанию не активизирован, поэтому необходимо подключить библиотеку GNU Readline с помощью следующих команд:

(use-modules (ice-9 readline))
(activate-readline)

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

3.3.2. История результатов

Историю команд в интерпретаторе Guile дополняет история результатов (значений, полученных при вычислении вводимых команд). Этот режим активизируется командой

(use-modules (ice-9 history))

которую также необходимо либо ввести в интерактивном режиме, либо вписать в файл конфигурации .guile. После этого все вычисляемые результаты будут автоматически сохраняться во внутренних переменных, пронумерованных в соответствии с порядком их вычисления $1, $2, $3 и т.д. Вы можете использовать эти переменные в своих последующих командах. Работа с применением режима сохранения истории результатов показана на следующей иллюстрации.

Рис.2. Использование истории результатов в интерпретаторе Guile
Рис.2. Использование истории результатов в интерпретаторе Guile
Рис.2. Использование истории результатов в интерпретаторе Guile

История результатов по умолчанию отключена по соображениям эффективности, поскольку требуется дополнительная память для хранения значений в нумерованных переменных, и эта память не освобождается при "сборка мусора". Это может отрицательно повлиять на производительность интерпретатора.

3.3.3. Обработка ошибок

Если при выполнении команды в интерактивном режиме возникает ошибка, то Guile запоминает соответствующий контекст выполнения и может предоставить пользователю три уровня информации о самой ошибке, а также дать точные координаты её возникновения.

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

Рис.3. Обработка ошибок в интерпретаторе Guile
Рис.3. Обработка ошибок в интерпретаторе Guile
Рис.3. Обработка ошибок в интерпретаторе Guile

В последнем сообщении нам подсказывают, что можно получить более подробную информацию о контексте ошибки, если ввести команды (backtrace) или (debug).

Первая команда (backtrace) показывает стек вызовов Scheme в той позиции, где возникла данная ошибка. См. рисунок 4.

Рис.4. Получение подробной информации об ошибке с помощью команды (backtrace)
Рис.4. Получение подробной информации об ошибке с помощью команды (backtrace)
Рис.4. Получение подробной информации об ошибке с помощью команды (backtrace)

Часто режим трассировки стека вызовов активизируется по умолчанию в процессе установки пакетов Guile. В любом случае вы можете управлять этим режимом с помощью команд (debug-enable 'backtrace) и (debug-disable 'backtrace) в интерактивном режиме или записать нужную команду в файл .guile.

Команда (debug) вызывает внутренний отладчик Guile, который позволяет просматривать стек вызовов, перемещаться по отдельным командам, выражениям и процедурам, а также проверять значения переменных в текущем контексте выполнения. Более подробно об использовании отладчика вы можете прочитать в документации.

3.3.4. Ещё один небольшой пример

Несмотря на то, что в Scheme имеется "штатная" функция изменения порядка следования элементов списка на противоположный (reverse), рассмотрим собственный вариант такой функции, реализованный "в учебных целях".

(define usr-reverse usr-lst)
  (if (null? usr-lst) usr-lst
    (append (usr-reverse (cdr usr-lst)) (list (car usr-lst)))))

А теперь проверим, как работает наша версия обращения списка (рисунок 5).

Рис.5. Создание и использование функции реверсирования списка
Рис.5. Создание и использование функции реверсирования списка
Рис.5. Создание и использование функции реверсирования списка

Здесь null — функция, проверяющая, не является ли список пустым, append — функция объединения двух списков в один новый список, cdr — функция, возвращающая хвостовую часть списка (без первого элемента), list — функция создания списка из заданных элементов, car — функция, возвращающая головную часть списка (то есть, самый первый его элемент). Понимание того, как всё это работает вместе, не должно вызвать особых затруднений (даже с учётом рекурсивного вызова определяемой функции).

4. Заключение

Итак, знакомство с Guile состоялось. Я умышленно ограничился самыми простыми примерами, не углубляясь в тонкости применения языка программирования Scheme, поскольку это всего лишь обобщённый предварительный взгляд на интерпретируемую программную среду Guile.

В данной статье, открывающей цикл, был представлен общий обзор Guile. Во второй статье будет рассматриваться практическое применение интерпретатора. Третья и четвёртая статьи посвящены взаимодействию Guile с языком программирования C. В пятой, заключительной статье цикла будут описаны дополнительные средства Guile.


Ресурсы для скачивания


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux
ArticleID=507096
ArticleTitle=Guile — универсальный инструмент программирования. Часть 1. Как с ним обращаться
publish-date=08112010