Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник_Лисп_1.doc
Скачиваний:
12
Добавлен:
01.05.2025
Размер:
883 Кб
Скачать
☆

3.Практикум: Простая база данных

Очевидно, перед тем, как создавать настоящие программы на Lisp, вам необходимо изучить язык. Но давайте смотреть правде в глаза — вы можете подумать "Practical Common Lisp"? Не оксюморон ли это? Зачем тратить силы на изучение деталей языка, если на нем невозможно сделать что-то дельное?". Итак, для начала я приведу маленький пример того, что можно сделать с помощью Common Lisp. В этой главе вы напишете простую базу данных для организации коллекции CD. В главе 27 вы будете использовать схожую технику при создании базы данных записей в формате MP3 для вашего потокового MP3-сервера. Фактически, можете считать это частью вашего программного проекта — в конце концов, для того, чтобы иметь сколько-нибудь MP3-записей для прослушивания, совсем не помешает знать, какие записи у вас есть, а какие нужно извлечь с диска.

В этой главе я пройдусь по языку Lisp достаточно для того, чтобы вы продвинулись до понимания того, каким образом работает код на нём. Но я не буду вдаваться в детали. Вы можете не беспокоиться, если что-то здесь будет вам непонятно — в нескольких следующих главах все используемые здесь (а также многие другие) конструкции Common Lisp будут описаны гораздо более систематически.

Одно замечание по терминологии: в этой главе я расскажу о некоторых операторах Lisp. В главе 4 вы узнаете, что Common Lisp предоставляет три разных типа операторов: функции, макросы и операторы специального назначения. Для целей этой главы вам необязательно понимать разницу. Однако я буду ссылаться на различные операторы как на функции, макросы или специальные операторы, в зависимости от того, чем они на самом деле являются, вместо того, чтобы попытаться скрыть эти детали за одним словом — оператор. Сейчас вы можете рассматривать функции, макросы и специальные операторы как более или менее эквивалентные сущности1).

Также имейте ввиду, что я не буду использовать все наиболее сложные техники Common Lisp для вашей первой после "Hello, world" программы. Цель этой главы не в том, чтобы показать, как вам следует писать базу данных на Lisp; скорее, цель в том, чтобы вы получили представление, на что похоже программирование на Lisp и видение того, что даже относительно простая программа на Lisp может иметь много возможностей.

3.1.Cd и Записи

Чтобы отслеживать диски, которые нужно перекодировать в MP3, и знать, какие из них должны быть перекодированы в первую очередь, каждая запись в базе данных будет содержать название и имя исполнителя компакт диска, оценку того, насколько он нравится пользователю и флаг, указывающий, был ли диск уже перекодирован. Итак, для начала вам необходим способ представления одной записи в базе данных (другими словами, одного CD). Common Lisp предоставляет для этого много различных структур данных, от простого четырехэлементного списка до определяемого пользователем с помощью CLOS класса данных.

Для начала вы можете остановиться на простом варианте и использовать список. Вы можете создать его с помощью функции LIST, которая, соответственно, возвращает список 2) из переданных аргументов.

CL-USER> (list 1 2 3) (1 2 3)

Вы могли бы использовать четырёхэлементный список, отображающий позицию в списке на соответствующее поле записи. Однако другая существующая разновидность списков, называемая property list (список свойств) или, сокращенно, plist, в нашем случае гораздо удобнее. Plist — это такой список, в котором каждый нечетный элемент является символом, описывающим следующий (чётный) элемент списка. На этом этапе я не буду углубляться в подробности понятия символ; по своей природе это имя. Для символов, именующих поля в базе данных, мы можем использовать частный случай символов, называемый символами-ключами (keyword symbol). Ключ — это имя, начинающееся с двоеточия (:), например, :foo 3). Вот пример plist, использующего символы-ключи :a, :b и :c как имена свойств:

CL-USER> (list :a 1 :b 2 :c 3) (:A 1 :B 2 :C 3)

Заметьте, вы можете создать список свойств той же функцией LIST, которой создавали прочие списки. Характер содержимого — вот что делает его списком свойств.

Причина, по которой использование plist является предпочтительным — наличие функции GETF, в которую передают plist и желаемый символ и получают следующее за символом значение. Это делает plist чем-то вроде упрощенной хэш-таблицы. В Lisp есть и "настоящие" хэш-таблицы, но для ваших текущих нужд достаточно plist, к тому же намного проще сохранять данные в такой форме в файл, это сильно пригодится позже.

CL-USER> (getf (list :a 1 :b 2 :c 3) :a) 1 CL-USER> (getf (list :a 1 :b 2 :c 3) :c) 3

Теперь, зная это, вам будет достаточно просто написать функцию make-cd, которая получит четыре поля в качестве аргументов и вернёт plist, представляющий CD.

(defun make-cd (title artist rating ripped) (list :title title :artist artist :rating rating :ripped ripped))

Слово DEFUN говорит нам,4) что эта запись определяет новую функцию. Имя функции — make-cd. После имени следует список параметров. Функция содержит четыре параметра — title, artist, rating и ripped. Всё, что следует за списком параметров — тело функции. В данном случае тело — лишь форма, просто вызов функции LIST. При вызове make-сd параметры, переданные при вызове, будут связаны с переменными в списке параметров из объявления функции. Например, для создания записи о CD Roses от Kathy Mattea вы можете вызвать make-cd примерно так:

CL-USER> (make-cd "Roses" "Kathy Mattea" 7 t) (:TITLE "Roses" :ARTIST "Kathy Mattea" :RATING 7 :RIPPED T)