пятница, 18 января 2013 г.

Использование Common Lisp в Fedora 17 (KDE). Первое знакомство.


Для начала нам необходимо ознакомится с историей возникновения и развития языка Common Lisp. Далее будут размещены несколько ссылок на русскоязычные ресурсы посвященных данному языку и ссылка на 
Википедию. 
На странице в Wiki можно увидеть множество реализаций данного языка. Далее нам необходимо посмотреть какая реализация и версия языка размещена в репозитории Fedora 17. Для этого запустите приложение Apper и в поле поиска введите lisp (Смотрите рисунок 1).

Рисунок 1. Поиск реализации Common Lisp в приложение Apper
 
Видим, что Apper нам нашел одну реализацию языка с названием clisp версии 2.49. Выделите пакет clisp. Ниже можно почитать описание данного пакета. Из описания можно вычитать, что ANSI Common Lisp (стандартизированный Американским национальным институтом стандартов (ANSI)) высокоуровневый язык программирования. GNU Clisp это реализация Common Lisp, авторами которого являются Bruno Haible и Michael Stoll, оба из Германии. GNU Clisp запускается на большинстве Unix подобных и других системах (семейства Windows) и требует только 4 мегабайта памяти. GNU Clisp относится к Свободному Программному Обеспечению и распространяется в рамках лицензии GNU GPL (GNU General Public License). Так же возможно распространять коммерческие патентованные приложения скомпилированные GNU CLISP
 
Пользовательский интерфейс поставляется на английском, германском, французском, испанском, голландском, датском и русском, что может не радовать, и может быть изменен во время работы.
GNU CLISP включает в себя интерпретатор, компилятор, отладчик, CLOS (Common Lisp Object System) — система объектно — ориентированного программирования (обязательно почитайте на Wikipedia об CLOS, по ссылке выше), MOP (внимание на английском) — (Meta — Object Protocol, пока не понятно что это и с чем его едят), a foreign language interface ((не понятно как перевести на русский), сокращенно FLI (опять английский), возможность вызывать Си (язык программирования) функции прямо из CLISP), сокеты (на английском), i18n (ссылка 2)— Интернационализация, быстрые bignum (на английском) и многое другое. Графический интерфейс X11 доступен через CLX(на английском) (ссылка 2), Garnet (ссылка 2), CLUE/CLIO. На GNU CLISP запускается приложение Maxima — система компьютерной алгебры, ACL2 (на английском) и другие пакеты.
 
Так, если выше указанное описание вас не напугало, как меня, то пробуем установить GNU CLISP на компьютер. В Apper, напротив пакета с именем clisp нажимаем кнопку установить (Install), а потом кнопку применить (Apply). Ждем пока установится. Установилось? Хорошо. Идем дальше. А что, собственно, дальше спросите вы? Идем искать на Google.ru.

Открываем терминал Konsole и вводим команду clisp. Вы должны увидеть следующий результат выполнения команды приведенный ниже на рисунке 2.
Рисунок 2. Результат выполнения команды clisp в терминале
 
Мы запустили интерпретатор языка lisp, увидели все авторские права и подсказку ввести команду :h и потом клавишу Enter, чтобы выполнить команду. Вводим. Ниже показан результат (Рисунок 3). 

Рисунок 3. Результат команды :h выполненной интерпретатором clisp

Справка нам говорит что, мы находимся на верхнем уровне цикла «Read — Eval (Evaluate) — Print», т.е. это значит что, мы вводим значение или выражение, интерпретатор обрабатывает введенные данные и выводит результат. Такая вот интерактивная среда. Прежде чем начать мучить интерпретатор clisp, давайте рассмотрим небольшое, на пару строчек, введение в Common Lisp, т.e. синтаксис. 
  1. Все выражения заключаются в круглые скобки ( )
  2. Функция: (FUNCTION parameter1 parameter2 ...), название функции и ее параметры разделяются пробелом.
  3. Функции сравнения в результате выдают значение T если условие выполняется, в противном случае NIL. (К ним относятся <, >, =)
  • Пример функции сложения: (+ 1 2 3 4), интерпретатор вернет результат 10
  • Пример функции умножения: (* 1 2 3 4), интерпретатор вернет результат 24
  • Пример функции деления целых чисел: (/ 1 2), интерпретатор вернет результат 1/2
  • Пример функции деления вещественных чисел: (/ 1.0 2.0), интерпретатор вернет результат 0.5
  • Пример функции деления на ноль: (/ 1 0), интерпретатор вернет в результате ошибку деления на ноль.
    *** - /: division by zero
    The following restarts are available:
    ABORT :R1 Abort main loop
Что бы выйти из режима созерцания ошибки введите следующую команду :q или команду :r1, о которой нам любезно сообщил интерпретатор.
  • Пример операции сравнения двух чисел (> 1 0), интерпретатор вернет результат T
  • Пример операции сравнения двух чисел (< 1 0), интерпретатор вернет результат NIL
  • Пример операции сравнения двух чисел (= 0 0), интерпретатор вернет результат T

Создадим функцию которая бы считала факториал натурального числа:

(defun factorial (N) (if (zerop N) 1 (* N (factorial (- N 1)))))

В данном описание функции используется условный оператор if в условии которого проверяется является ли переданный нами аргумент нулем (zerop — возвращает истину (T) если 0, иначе ложь (NIL)), если да то возвращаем число 1, т.к. факториал числа 0 является 1, иначе вычисляем факториал дальше, т.е. умножается значение аргумента N на значение факториала с преданным аргументом N-1 (Рекурсивный вызов).
 
Откройте Konsole и запустите CLISP. Предайте эту функцию интерпретатору Common Lisp. После успешной обработки интерпретатор должен вывести названия вашей функции, например так:

[1]> (defun factorial (N) (if (zerop N) 1 (* N (factorial (- N 1)))))

FACTORIAL

Чтобы протестировать нашу функцию необходимо в круглых скобках написать название нашей только что созданной функции и передать ей один аргумент, например число 5:

[2]> (factorial 5)

120

т.е. факториал числа 5 будет вычислен и будет выведен результат число 120.

Так идем дальше. Для удобства работы с Common Lisp нам необходимо среда разработки (IDE). Для Common Lisp существуют различные IDE как платные, условно-бесплатные и бесплатные. Ниже будут перечислены названия некоторых сред и указаны ссылки на их сайты.
  • Corman Common Lisp (Только Windows)
  • Allegro Common Lisp (Linux и Windows), есть бесплатная версия с некоторыми ограничениями (Allegro CL Express Edition)
  • LispWorks (Linux и Windows), есть бесплатная версия с некоторыми ограничениями (LispWorks Personal Edition)
  • Ufasoft Lisp Studio (Только Windows), использует форк gnu clisp в качестве интерпретатора Common Lisp
  • LispIDE (Только Windows), может работать с различными реализациями Common Lisp
  • Cusp, плагин для платформы Eclipse
  • Emacs (ссылка 2) + SLIME (ссылка 2), связка текстового редактора и режима Emacs для разработки на Common Lisp.
  • и другие. 
Скажу вам честно, что в Emacs уже есть один встроенный диалект Lisp и имя его, как нетрудно догадаться Emacs Lisp (книга о программирование на Emacs Lisp на русском, английский GNU Emacs Lisp Reference Manual, книга на английском An Introduction to Programming in Emacs Lisp (Third Edition), и еще что-то на ergoemacs.org на английском). Свой диалект в Emacs позволяет настраивать и расширять его возможности, другими словами, очень удобно иметь в составе редактора скриптовый язык, может быть в другом посте мы попробуем узнать больше о возможностях Emacs Lisp, но дальше мы будем разбираться в Emacs и Slime.

Хотелось бы вкратце рассказать о Slime. Slime, как пишут на официальном сайте проекта, это режим Emacs для разработки на Common Lisp. Вдохновленный такими существующими системами как Emacs Lisp (о том, что это смотрите ссылки выше) и ILISP (ILISP User Manual на английском).
Slime (Superior Lisp Interaction Mode for Emacs) режим наилучшего взаимодействия с Lisp для Emacs. Slime расширяет возможности Emacs поддерживая интерактивное программирование на Common Lisp. Его особенности сосредоточены вокруг режима slime-mode, т.е. режим Emacs который дополняет стандартный режим lisp-mode. В то время как режим lisp-mode поддерживает редактирование исходных файлов Lisp, режим slime-mode добавляет поддержку для взаимодействия с запущенными процессами Common Lisp для компиляции, отладки, поиска документации и многое другое. Среда программирования или попросту окружение предоставляемое режимом slime-mode следует примеру естественному для Emacs окружению Emacs Lisp. Также Slime включает в себя хорошие идеи из похожей системы такой как ILISP и некоторые идеи собственного производства.

Slime построен из двух частей: пользовательского интерфейса написанного на Emacs Lisp и вспомогательной серверной программы написанной на Common Lisp. Две эти части соединяются друг с другом посредством сокета и общаются между собой используя протокол похожий на RPC протокол.
Lisp сервер в первую очередь написан на переносимом Common Lisp. Требования к осуществлению конкретной функциональности указан по четко определенному интерфейсу и отдельно реализован для каждой реализации Lisp. Это делает SLIME легко переносимым.

Статья на английском языке которая рассказывает об архитектуре SLIME с картинкой. Название статьи Understanding SLIME (Using Emacs and Lisp Cooperatively)
Еще скажу что SLIME поддерживает большое количество реализаций Common Lisp. Одна из многих реализаций является GNU CLISP, которая и используется нами.

Перед тем как продолжить вам необходимо установить текстовый редактор Emacs. Делается это легко, запустите приложение Apper. В строке поиска введите emacs, по вашему запросу будет найдено большое количество совпадений, из всех пакетов перечисленных там, вам нужен с именем emacs. Установите его. Выберите его нажмите кнопку Install и Apply. Ниже на рисунке 4 показан внешний вид программы GNU Emacs.

Рисунок 4. Внешний вид программы Emacs

Шаг первый. Установка SLIME.

Запускаем менеджер пакетов Apper и в строку поиска вводим слово slime. Ниже на рисунке 5 отображен результат поиска.

Рисунок 5. Результат поиска по запросу slime в приложение Apper

Выбираем пакет с именем emacs-slime (как можно видеть из рисунка 5, версия slime 3.0-0.6.20120525cvs.fc17) и нажимаем Install, а потом Apply. Ждем окончания установки. Помимо основного пакета emacs-slime с ним устанавливаются два зависимых пакета (cl-asdf и common-lisp-controller). Пакет cl-asdf, или просто ASDF (Another System Definition Facility — Другая Система Определения Объекта), не что иное как инструмент для описания того как организованы исходные файлы Lisp: какой зависит от которого и когда. Это приблизительно то, что Common Lisp программисты используют для сборки программного обеспечения, это тоже самое что и для C(Си) программистов GNU Make (ссылка 2)(система для сборки проекта). ASDF является преемником былого инструмента DEFSYSTEM (ссылка 2) для Lisp. Надеюсь у вас все установилось, значит переходим к шагу два.

Шаг второй. Начинаем работу.

Дальше нам необходимо показать Emacs, где находится интерпретатор Common Lisp (GNU CLISP) и режим SLIME.

Создайте в вашем домашнем каталоге конфигурационный файл Emacs, имя этого файла .emacs и добавьте в файл следующие строчки, эти строчки взяты из документации по SLIME в разделе по установке на сайте common-lisp.net:

(setq inferior-lisp-program "/usr/bin/clisp") ; your Lisp system

(add-to-list 'load-path "/usr/share/common-lisp/source/slime") ; your SLIME directory

(require 'slime)

(slime-setup)


Сохраните файл .emacs.

Запустите GNU Emacs и нажмите комбинацию клавиш Alt + x и наберите slime, нажмите Enter. Так, начались проблемы, запуск SLIME прерывается со следующим сообщением:

;; Error while compiling /usr/share/common-lisp/source/slime/xref.lisp:

;; OPEN: File #P"/usr/share/common-lisp/source/slime/xref.lisp" does not exist

Пара в Google.ru. По-моему, что это ошибка Slime, и тянется она, как я понял, с 2006 года. Немного, об этой ошибке можно почитать на английском по ссылке 1, ссылке 2.

Перед тем как продолжить, удалите установленный ранее из репозитория Fedora SLIME с помощью приложения Apper. Далее идем на сайт SLIME или CLiki и пытаемся установить его прямо из CVS репозитория. Ставить будем в каталог opt домашнего каталога, т.е. ~/opt/, где ~ - /home/[имя пользователя]/opt. Если данного каталога у вас нет, то создайте его. Откройте терминал Konsole (рисунок 6) и перейдите в только что созданный каталог:

cd ~/opt/

# Авторизация в CVS репозиторий SLIME (пароль: anonymous)
cvs -d :pserver:anonymous@common-lisp.net:/project/slime/cvsroot login

# Создание локальной копии SLIME у вас в каталоге
cvs -d :pserver:anonymous@common-lisp.net:/project/slime/cvsroot checkout slime
Рисунок 6. Установка Slime из CVS репозитория
 
Нам осталось только чуть-чуть поправить конфигурационный файл .emacs, где мы должны изменить путь к файлам SLIME на наш ~/opt/slime

(setq inferior-lisp-program "/usr/bin/clisp") ; your Lisp system

(add-to-list 'load-path "~/opt/slime") ; your SLIME directory

(require 'slime)

(slime-setup)

Сохраните изменения в файле .emacs. Запустите GNU Emacs и нажмите Alt — x, потом наберите slime подтвердив команду клавишей Enter. На этот раз CLISP загрузился без проблем. Теперь на Common Lisp можно программировать и в GNU Emacs (Рисунок 7).

Рисунок 7. CLISP работающий через SLIME в Emacs
 
Шаг третий. Красивая жизнь с Quicklisp.
Quicklisp, как пишут на официальном сайте, это менеджер библиотеки для Common Lisp. Он работает с вашим интерпретатором Common Lisp и позволяет скачивать, устанавливать и использовать более 700 библиотек за несколько простых команд.



Quicklisp прост для установки и работает с ABCL, Allegro CL, Clozure CL, CLISP, CMUCL, ECL, LispWorks, SBCL, и Scieneer CL, на Linux, Mac OS X, и Windows.



Что-бы установить Quicklisp, необходимо скачать quicklisp.lisp и выполнить его. Сохраните файл quicklisp.lisp в каталок /home/[имя вашего пользователя]/opt/quicklisp/, например. Если каталог не создан, то создайте его.

# Перейдите в каталог quicklisp

cd ~/opt/quicklisp/


# Скачайте quicklisp.lisp в данный каталог с помощью приложения wget



Запустите ранее сконфигурированный Emacs для работы с CLISP посредством SLIME. Нажмите заветное сочетание клавиш Alt — x и напишите slime, потом нажмите клавишу Enter. Когда интерпретатор будет загружен вы увидите подсказку в виде надписи CL-USER>. Это означает, что интерпретатор ждет ввода пользовательских команд.



Теперь мы можем скормить только что скаченный файл quicklisp.lisp нашему интерпретатору CLISP в виде команды:



(load "~/opt/quicklisp/quicklisp.lisp")



Более подробный вывод результата выполнения команды представлен рисунком 8.

 
Рисунок 8. Загрузка файла quicklisp.lisp
 
Так файл quicklisp.lisp успешно загружен. Ниже можно видеть дальнейшие указания что нам нужно сделать следующим шагом. Выполнить команду (quicklisp-quickstart:install). Пробуем выполнить (Рисунок 9).

 
Рисунок 9. Результат установки quicklisp
 
Эта команда, по умолчанию, создаст у вас в домашнем каталоге папку quicklisp. Если вы хотите указать другой путь, например ~/.quicklisp/, то в команду установки необходимо добавить аргумент задания нового пути (Пример команды показан на рисунке 10).

 
Рисунок 10. Указание другого каталога установки quicklisp
 
Убедитесь в том, что альтернативный каталог установки создан, если нет, то создайте его. Если вы этого не сделаете, то установка не выполнится, а интерпретатор запущенный через Emacs будет просто навсего висеть и ничего не делать, в результате вам придется перезапустить Emacs. Интерпретатор CLISP запущенный в терминале выполнит установку в другой каталог даже если он не создан, в результате он будет им создан. На рисунке 11 показан пример установки quicklisp в другой каталог. 

Рисунок 11. Установка quicklisp в другой каталог
 
После того как нам сообщили, что quicklisp установлен, мы можем увидеть пример команды для загрузки конкретной системы (ql:quickload "system-name") или команды поиска системы по заданному термину (ql:system-apropos "term"). Но, самое главное, если мы хотим загружать quicklisp на ряду с нашим интерпретатором CLISP, мы должны выполнить следующую команду (ql:add-to-init-file) (Рисунок 12), но перед тем как выполнить данную команду, создайте в вашем домашнем каталоге конфигурационный файл CLISP. Назовите его .clisprc.lisp. Если вы этого не сделаете, то интерпретатор CLISP запущенный в Emacs опять будет висеть и чего-то ждать. Интерпретатор CLISP запущенный в терминале сам создаст, если он не создан, конфигурационный файл .clisprc.lisp в домашнем каталоге пользователя и добавит необходимые команды для успешного запуска quicklisp вместе с интерпретатором CLISP

Рисунок 12. Привязываем quicklisp к CLISP
 
Последнее что нам необходимо сделать это научить SLIME правильно работать с quicklisp. Для этого с помощью quicklisp нам нужно загрузить систему quicklisp-slime-helper. Quicklisp-slime-helper создаст файл, этот файл мы можем загрузить в Emacs и тем самым настроить правильные пути загрузки для установок из менеджера quicklisp. На рисунке 13 показан результат выполнения команды (ql:quickload "quicklisp-slime-helper").

 
Рисунок 13. Результат загрузки системы quicklisp-slime-helper

Как можно видеть из рисунка 13 нас просят изменить конфигурационный файл GNU Emacs, который расположен в домашнем каталоге пользователя под именем .emacs. Добавьте в этот файл строчку (load (expand-file-name "~/.quicklisp/slime-helper.el")). В результате ваш конфигурационный файл .emacs будет выглядеть следующим образом:

(load (expand-file-name "~/.quicklisp/slime-helper.el"))

(setq inferior-lisp-program "/usr/bin/clisp") ; your Lisp system

(add-to-list 'load-path "~/opt/slime") ; your SLIME directory

(require 'slime)

(slime-setup)
  
После всех внесенных изменений в файл .emacs, сохраните его и перезапустите редактор GNU Emacs. Окончательный результат всех настроек к которому мы стремились представлен рисунком 14. 

 
Рисунок 14. Настроенный Emacs + Slime + CLISP + Quicklisp
 
Первое знакомство со средой программирования для Common Lisp, настроенная нами с самого начала (Emacs + Slime + CLISP + Quicklisp), не очень приятное. На настройку данного окружения затрачено много времени, которое я, не знаю как вы, потратил бы на изучения языка Common Lisp. Если вы не хотите терять время на всю эту настройку, то обратите внимание на проект Lispbox в котором вся связка Emacs + Slime + Clozure Common Lisp + Quicklisp уже реализована, с дополнительными возможностями. 
 
Дальше, возможно, мы попробуем создать простое OpenGL приложения на Common Lisp, но это уже другая история.

воскресенье, 13 января 2013 г.

Развлечения в терминале. Звездные войны у вас в терминале на Linux. Играем в Emacs.

Тут как-то наткнулся на статью в блоге, называется она «TOP 25 секретов терминала». Она написана для MacOS пользователей, но что-то работает и в Linux, под что-то я имею введу два секрета терминала, под номерами 4 и 24. Вот о них и пойдет речь.
1) Если вы запустите терминал, например Konsole в KDE, и выполните следующую команду:
telnet towel.blinkenlights.nl
вы увидите полную версию «Звездные войны» реализованную в ASCII символах, смотрите рисунок 1.

 

Рисунок 1. «Звездные войны» в терминале.

2)  Если у вас есть желание поиграть в текстовом редакторе Emacs, то вам необходимо открыть терминал, например Konsole и ввести команду:
  • узнаем версию Emacs (ls /usr/share/emacs/), данная команда отобразит список каталогов, один из которых будет называться как номер версии Emacs (например 24.1)
  • ls /usr/share/emacs/24.1/lisp/play, отобразит список файлов, имена которых и являются нашими играми (рисунок 2):
Рисунок 2. Игры Emacs
 
Для запуска игры, откройте Emacs нажмите сочетание клавиш (Alt + x) и наберите название игры, например gomoku (рисунок 3) по названию файлов в каталоге play.

  Рисунок 3. Игра Gomoku в Emacs
 
Эти примеры напомнили мне еще два забавных приложения для терминала, которые мы и рассмотрим.
 
3) Есть такое приложение, называется оно sl, это зеркальное отражение названия команды ls, команды для отображения содержимого каталога в краткой форме. Например, если кто-то хотел отобразить содержимое каталога и вместо команды ls в терминале он случайна набрал sl и выполнил ее, то в терминале проиграется анимация движущегося поезда (рисунок 4).

 
Рисунок 4. Результат команды sl в терминале

4) Следующие приложение называется cowsay, если вы наберете в терминале cowsay и передадите ей один аргумент, например слово Hello!, то вы увидите корову говорящую Hello! (рисунок 5).

Рисунок 5. Результат команды cowsay 

На этом все.