Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Fp_3.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
635.39 Кб
Скачать

3.1.3 Функция append

В стандартах любой реализации LISPа встречается ещё одна важная функция, применяющаяся для построения списков, которая называется append

Формат

(append lst1 lst2)

Результатом работы этой функции является новый список, элементами которого будут значения элементов списка lst1, за которыми идут значения элементов списка lst2.

Пример

> (append '(1 2) '(3 4))

(1 2 3 4)

Графически работу этой функции можно

проиллюстрировать так:

Заметим, что для образования списков

здесь была использована …

3.1.4 Функция quote.

В связи с применением символа «'», возникшим при получении списков, снова (и окончательно) вернемся к функции quote.

Формат.

(quote expr)

возвращает в качестве значения свой аргумент expr , не вычисляя его.

Мы уже встречались с этой формой. Знак кавычки, который мы ставили перед символами - всего лишь удобство написания этой функции.

Сравним

> (quote a)

а

и тот же самый вызов

> 'а

а

И, как всегда, – «правило двойного служебного символа»

> ''a

Итак, сделаем полезный вывод - для получения списков наряду с list можно пользоваться и функцией quote.

Примеры получения списков с её помощью

> '(+ 1 2)

(+ 1 2)

> (quote (+ 1 2))

(+ 1 2)

А теперь и с другими функциями, работающими со списками

> (car '(+ 1 2))

+

> (list '(+ 1 2))

((+ 1 2))

Надо обратить внимание, что в последнем примере получился список списка !

Иногда, особенно когда списки длинные, вместо list для лучшей читаемости полезнее записывать функцию quote:

> '(1 2 3 4)

(1 2 3 4)

Сравните:

> (quote (1 2 3 4) )

(1 2 3 4)

Мы уже встречали подсписки, теперь уточним, что количество уровней вложений ничем не ограничено.

> '(1 ("Привет" 3) (5 (6 7) 'list 8))

(1 ("Привет" 3) (5 (6 7) 'list 8))

3.1.5 Функция eval

Противоположность quote, которая ничего ни делает - функция eval.

Формат

(eval expression)

вычисляет значение выражения expression и возвращает его в качестве ответа.

Примеры.

> (eval '(+ 1 2))

3

Вспомните, когда мы впервые встретили функцию list, то заметили, что «пока нечем заставить это сложение выполнится» и вот теперь – свершилось! Попробуем другие, аналогичные вырианты:

> (eval (list + 1 2))

3

> (eval (quote (+ 1 2)))

3

Это очень важная функция LISPa. С помощью нее можно вычислить любое S-выражение. Для примера, вначале создадим выражение для функции вывода не экран

>(list 'display '(+ 1 2))

(display (+ 1 2))

Мы видим список, который как бы «по совместительству» является и вызовом функции display. Но функция display не исполняется, поскольку никто не заставляет её выполняться. Тогда заставим её выполнится, разумеется, с помощью eval

>(eval (list 'display '(+ 1 2)))

3

3.2 Точечные пары

Любые два объекта можно объединить в структуру называемую точечной парой (иногда называют просто – пара. Вспомните, такое понятие не зря уже встречалось нам ранее) при помощи встроенной функции cons (сокращение от construction).

Эта функция берёт два параметра, например, a и b, а возвращает пару, т.е. объект, состоящий из значений этих двух(!!) параметров, который обычно отображается через точку так: (a . b)

Формат функции cons.

(cons x y) возвращает составной объект – точечную пару (x . y)

ВАЖНО заметить, что точка записывается в окружении пробелов!

П римеры Для сравнения:

> (cons 1 2)

(1 . 2)

Графически точечная пара представляется так:

Ещё раз обратите внимание – возвращается пара из значений.

> (define a -3)

> (cons 5 a)

(5 . -3)

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

Чтобы получить составные части пары, используются функции car и cdr:

(car x) возвращает первый элемент пары x

(cdr x) возвращает второй элемент пары x.

Заметим: здесь мы говорим о втором равноправном элементе точечной пары!

Примеры.

> (define x (cons 1 2)) > x (1 . 2)

> (car x) 1

> (cdr x) 2

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

Определим пару от пары:

> (cons (cons 'a 1) 12 ) ((a . 1) . 12)

Придумаем для пары имя

> (define y (cons (cons 2 a) 4))

> y

((2 . -3) . 4)

( Вспомним, что мы уже определяли значение -3 для a где-то раньше)

> (cdr (car y))

-3

> (cdar y)

-3

3.2.1 Функция pair?

При обработке структур необходимо иметь возможность определить, является ли выражение атомом или парой. Это делается встроенным предикатом pair?.

(pair? x)

возвращает #t, если аргумент x представляет собой пару и #f в противном случае.

Начнём примеры с ехидства.

> (pair? 1.2)

#f

И это правильно, поскольку 1.2 – действительное число. (Обратите внимание на отсутствие обрамляющих точку пробелов!!!) А вот тот же вопрос и для соответствующей пары

> (pair? (cons 1 2))

#t

Теперь для поименованной пары

> (define x (cons 1 2))

> x

(1 . 2)

> (pair? x)

#t

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]