Функция CONS включает новый элемент в начало списка 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Функция CONS включает новый элемент в начало списка



Функция CONS (construct) строит новый список из переданных ей в качестве аргументов головы и хвоста:

 

(CONS голова хвост)

 

Функция добавляет новое выражение в список в качестве первого элемента:

 

_(cons ’ a ’ (b c))

(A B C)

_(cons ’ (a b) (c d))

((A B) C D)

_(cons (+ 1 2) ’ (+ 4)); первый аргумент без апострофа, поэтому

(3 + 4); берется его значение

_(cons ’ (+ 1 2) ’ (+ 4)); первый аргумент не вычисляется

((+ 1 2) + 4)

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

 

_(cons ’ (a b c) nil)

((A B C)); одноэлементный список

_(cons nil ’ (a b c))

(NIL A B C); NIL – элемент списка

_(cons nil nil)

(NIL); не то же самое, что NIL

Для того, чтобы можно было включить первый аргумент функции CONS в качестве первого элемента значения второго аргумента этой функции, второй аргумент должен быть списком. Значением функции CONS всегда будет список:

 

CONS: s-выражение × список → список

 

 

Связь между функциями CAR, CDR и CONS

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

 

 

 
 
CAR


 

это

 

(это просто список)

 
 
CDR


 

(просто список)

 

 

это

 
 
CONS

 


(это просто список)

(просто список)

Эту связь между функциями CAR, CDR и CONS можно выразить следующим образом:

 

_(cons (car ’ (это просто список)

(cdr ’ (это просто список)))

(ЭТО ПРОСТО СПИСОК)

Предикат проверяет наличие некоторого свойства

Чтобы осуществлять допустимые действия со списками и избежать ошибочных ситуаций, нам необходимы, кроме селектирующих и конструирующих функций, средства опознавания выражений. Функции, решающие эту задачу, в Лиспе называются предикатами (predicate).

Предикат – это функция, которая определяет, обладает ли аргумент определенным свойством и возвращает в качестве значения логическое значение «ложь», т.е. NIL, или «истина», которое может быть представлено символом Т или любым выражением, отличным от NIL.

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

 

 

Предикат АТОМ проверяет, является ли аргумент атомом

При работе с выражениями необходимо иметь возможность проверить, является ли выражение атомом или списком. Это может потребоваться, например, перед применением функций CAR и CDR, так как эти функции определены лишь для аргументов, являющихся списками. Базовый предикат АТОМ используется для идентифицирования лисповских объектов, являющихся атомами:

 

(АТОМ s-выражение)

Значением вызова АТОМ будет Т, если аргументом является атом, и NIL – в противном случае.

 

_(atom ’ ж)

Т

_(atom ’ (Я программирую – следовательно существую))

NIL

_(atom (cdr ’ (a b c)))

NIL; АТОМ от списка (В С) – это NIL

С помощью предиката АТОМ можно убедиться, что пустой список NIL, или (), является атомом:

 

_(atom nil)

T

_(atom ()); () – то же самое, что и NIL

T

_(atom ’ ()); Пустой список с апострофом все равно

Т; есть NIL

_(atom ’ (nil)); Аргумент – одноэлементный список

NIL

_(atom (atom (+ 2 3))); Логическое значение Т

Т; является атомом

В последнем примере результатом сложения является число, а результатом внутреннего вызова предиката АТОМ – значение Т, которое, в свою очередь, тоже является атомом.

В Лиспе существует целый набор предикатов, проверяющих тип являющегося аргументом выражения или любого другого лисповского объекта и таким образом идентифицирующих используемый тип данных. Например, LISTP идентифицирует списки, ARRAYP – массивы и т.д.

EQ проверяет тождественность двух символов

Предикат EQ сравнивает два символа и возвращает значение Т, если они идентичны, в противном случае – NIL.

 

_(eq ’ x ’ кот)

NIL

_(eq ’ кот ’ (car (кот пес)))

Т

_(eq () nil)

T

_(eq t ’t)

T

_(eq t (atom ’ мышь))

Т

Предикат EQ накладывает на свои аргументы строго определенные требования. С его помощью можно сравнивать только символы или константы Т и NIL, и результатом будет значение Т лишь в том случае, когда аргументы совпадают. В некоторых версиях Лиспа предикат EQ не используется.

Предикат EQ в Лисп-системах обычно таков, что его можно применять к списочным и числовым аргументам, не получая сообщения об ошибке; он не проверяет логического равенства чисел, строк или других объектов, а лишь смотрит, представлены ли лисповские объекты в памяти вычислительной машины физически одной и той же структурой. Одноименные символы представлены в одном и том же месте памяти (не считая нескольких исключений), так что той же проверкой предикатом EQ символы можно сравнить логически. До сих пор, например, списки могли быть логически (внешне) одинаковы, но они могут состоять из физически различных списочных ячеек. К вопросам физического и логического равенства списков мы вернемся позже. Приведем все-таки для предостережения два примера.

 

_(eq ’ (a b c) ’ (a b c))

NIL

_(eq 3.14 3.14)

NIL

Так как EQ определен лишь для символов, то, сравнивая два выражения, прежде всего надо определить, являются ли они атомами (АТОМ). Если хотя бы один из аргументов является списком, то предикат EQ нельзя использовать для логического сравнения. При сравнении чисел проблемы возникают с числами различных типов. Например, числа 3.000000, 3 и 0.3Е1 записываются внешне одинаково. Равенство выражений можно понимать по-разному. Для различных видов и степеней равенства в Лиспе наряду с EQ используются и другие предикаты, которые мы рассмотрим далее.

 



Поделиться:


Последнее изменение этой страницы: 2016-09-05; просмотров: 414; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.133.131.168 (0.009 с.)