Введение в программирование на Лиспе

         

Диалог с Лисп-системой


Рассмотрим особенности функционирования Лисп-интерпретатора на примере системы GNU Clisp.

> clisp

Работа системы начинается с заставки вида:

> clisp

i i i i i i i ooooo o ooooooo ooooo ooooo I I I I I I I 8 8 8 8 8 o 8 8 I \ `+' / I 8 8 8 8 8 8 \ `-+-' / 8 8 8 ooooo 8oooo `-__|__-' 8 8 8 8 8 | 8 o 8 8 o 8 8 ------+------ ooooo 8oooooo ooo8ooo ooooo 8 Copyright (c) Bruno Haible, Michael Stoll 1992, 1993 Copyright (c) Bruno Haible, Marcus Daniels 1994-1997 Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998 Copyright (c) Bruno Haible, Sam Steingold 1999-2002

[1]>

Символ ">" - приглашение к вводу выражений для интерпретации. Выход из Лисп-системы осуществляется как вызов функции "BYE"

[1]> (BYE)1)

Происходит возврат к операционной системе.

[1]> (BYE) Bye.

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

[1]> (CONS 1 2)

Интерпретатор вычисляет это выражение, затем печатается полученный результат и появляется очередное приглашение:

[1]> (CONS 1 2) (1 . 2) [2]>

При недостатке правых скобок ничего не происходит:

[1]> (CONS 1 2

Система ждет, пока не получит недостающие скобки, прежде чем предложить прочитанную форму интерпретатору:

[1]> (CONS 1 2 ) (1 . 2) [2]>

Баланс скобок проще всего поддерживать, набирая пары "()" и вставляя потом между ними нужный текст. При наборе закрывающей скобки система на полсекунды перемещает курсор на соответствующую левую скобку, что также помогает замечать нарушения в балансе скобок.

При невозможности интерпретировать полученное данное как символьное выражение система печатает диагностическое сообщение:

[2]> (CONS A B) *** - EVAL: variable A has no value2) 1. Break [3]>



В этом примере перед атомами "A" и "B" следует поставить апострофы, показывающие системе, что здесь эти атомы не рассматриваются как переменные. Система перешла в режим обработки прерывания, выйти из которого можно с помощью Ctrl-D (одновременное нажатие).

[5]> (cons a 'b)

*** - EVAL: variable A has no value 1. Break [6]>3) [7]> (cons 'a 'b) (A . B) [8]>

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

[1]> (CONS 1 2) (1 . 2) [2]>4) (CONS 1 2)

Теперь эту строку можно подкорректировать:

[1]> (CONS 1 2) (1 . 2) [2]> (CONS 4 5)5) (4 . 5)

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

[1]> (cons 'ГОЛОВА 'хвост) (ГОЛОВА . ХВОСТ) [2]>



Пошаговое вычисление


В системе имеется функция "STEP", обеспечивающая пошаговую интерпретацию сложных выражений.

Унарная функция "STEP" выполняет пошаговую интерпретацию своего аргумента. Ее работа начинается с приглашения выбрать действие по управлению интерпретацией (см. таблицу):

[2]> (step (cons (car '(a . b)) 'd )) step 1 --> (CONS (CAR '(A . B)) 'D ) Step 1 [3]>

Таблица 2.1. Первоочередные средства управления пошаговой интерпретацией символьных выражений. (Можно пользоваться сокращенными обозначениями из 2-ой колонки.)

COMMANDABBRDESCRIPTIONКОМАНДАСОКР.ОПИСАНИЕ
Help:h (or ?)this command list
Полный список команд
Error:ePrint the recent Error Message
Вывод последнего сообщения об ошибке
Continue:ccontinue evaluation
Продолжение вычислений
Step:sstep into form: evaluate this form in single step mode
Продвижение к внутреннему подвыражению
Next:nstep over form: evaluate this form at once
Вычисление данной формы сразу, полностью

По действию "step" выбирается вычисление первого аргумента функции "CONS":

Step 1 [2]> (step (cons (car '(a . b)) 'd )) Step 1 --> (CONS (CAR '(A . B)) 'D ) Step 1 [3]> step Step 2 --> (CAR '(A . B)) Step 2 [4]>

Это же действие "step" теперь можно выбирать с помощью стрелки вверх:

Step 1 [2]> (step (cons (car '(a . b)) 'd)) Step 1 --> (CONS (CAR '(A . B)) 'D) Step 1 [3]> step Step 2 --> (CAR '(A . B)) Step 2 [4]> step1) Step 3 --> '(A . B) Step 3 [5]>

Теперь шаг за шагом смотрим как интерпретатор перебирает подвыражения и получает их значения:

(step (cons (car '(a . b)) 'd )) step 1 --> (CONS (CAR '(A . B)) 'D) Step 1 [15]> step step 2 --> (CAR '(A . B)) Step 2 [16]> step step 3 --> '(A . B) Step 3 [17]> step

step 3 ==> value: (A . B) step 2 ==> value: A step 2 --> 'D Step 2 [18]> step

step 2 ==> value: D step 1 ==> value: (A . D) (A . D) Step 1 [14]>



Сайты с Лисп-системами


Интернет-браузер на запрос "Lisp" даст многочисленные ссылки на сайты, среди которых можно найти следующее:

Таблица 2.1. Адреса, выданные IE через Yandex в начале июля 2006 года

URLКомментарий
http://lisp.narod.ru/Русскоязычный сайт для новичков с форумами и дискуссионными статьями.
http://www.dvo.ru/tech/lisp/index.htmlОтсканированный текст известного двухтомника "Мир Лиспа"
http://langos.lrn.ru/langs/funclng.phpМатериалы по языкам функционального программирования
http://www.intuit.ru/Сайт Интернет-Университета Информационных Технологий с большим числом дистанционных курсов по программированию
http://lists.unixcenter.ru/archives/mlug/2000-August/000232.htmlМатериалы сравнения Си с Лиспом
http://www.shareware-ownload.org/lisp.phpБесплатные Lisp-системы.
http://ru.wikipedia.org/wiki/LISP/Статья про Лисп в электронной энциклопедии.
ftp://ftp.gnu.org/gnu/clisp/release/2.29/Сайт со свободно распространяемыми реализациями Clisp (clisp-2.29-win32.zip)
http://www.cs.cmu.edu/~dst/Lisp/Сайт CMU
http://penguin.kurgan.ru/doc/lisp.htmlПро AutoLisp
http://www.ystok.ru/index.htmlСайт фирмы, использующей Лисп в качестве базовой технологии
http://www.marstu.mari.ru/mmlab/home/lisp/title.htmСайт Морозова с введением в программирование на Лиспе
http://vspu.ac.ru/~lmiker/5im/rezn.htmСайт Микеровой с учебником по Лиспу
Сайт Заочной школы программирования и Информационных технологий, включающий материалы по Лиспу

Можно воспользоваться комплектом GNU Clisp, на базе которого подготовлены примеры в данного курса, выставленным на сайте http://green.iis.nsk.su/lisp



Установка Лисп-системы


Система программирования на языке Лисп представляет собой комплекс функций для обработки различных структур данных, включая многоуровневые списки, числа, строки, файлы и их имена. Программа на Лиспе может дополнять их комплекс. Функции встраиваются в систему как атомы, имеющие определения на уровне исполнимого кода или языка программирования. В систему входит компилятор, обеспечивающий перевод функций с уровня языка программирования на уровень исполнимого кода, поэтому нет формальной разницы между определениями разного уровня. В целом работа Лисп-системы обеспечивается интерпретатором, вычисляющим отдельные выражения, последовательность которых и есть программа.



Запуск Лисп-программ из файлов


Программа на Лиспе – это последовательность интерпретируемых выражений.

Представим, что подготовлен файл с именем "start.lsp":

; пример программы (defun первый (x) (car x)) ;; определение новой функции (print (первый '(one two))) ;; вывод результата применения новой функции

Расширение "lsp" символизирует тексты на Лиспе. В этом файле содержится программа с построчными комментариями. Комментарии отделяются от программы символом ";".

Defun – функция трех аргументов: первый – имя объявляемой новой функции, второй – список ее аргументов, третий – тело определения. Функция "Defun" встраивает в систему новую, определяемую в программе функцию.

Print – унарная псевдо-функция, печатающая свой аргумент.

Заранее подготовленный файл с программой можно ввести и сразу исполнить с помощью функции LOAD.

[1]> (LOAD 'start.lsp) T ONE [2]>

Перед именем файла ставится апостроф. Результат "T" означает, что чтение файла прошло успешно. При чтении файла произошла интерпретация содержащихся в нем выражений. Чтобы увидеть результаты работы программы здесь применение функции оформлено как аргумент псевдо-функции "PRINT".

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