Lisp8

343 views

Published on

my first upload

Published in: Entertainment & Humor, Sports
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
343
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Lisp8

  1. 1. Внутреннее представление списков. Применяющие функционалы . Лекция 8
  2. 2. <ul><li>Внутреннее представление списков </li></ul><ul><li>Обработка списков без разрушения. Append </li></ul><ul><li>Разрушающие функции </li></ul><ul><li>Применяющие функционалы </li></ul>
  3. 3. Внутреннее представление списков
  4. 4. Структура памяти <ul><li>Списочная ячейка ( cons-ячейка ) - специальный элемент памяти, </li></ul><ul><li>состоит из двух полей: CAR и CDR . </li></ul><ul><li>Список – совокупность атомов, которые связываются списочными ячейками. </li></ul>
  5. 5. Представление списков через списочную ячейку
  6. 6. Представление списков через точечные пары <ul><li>(a) <=> (a.nil) </li></ul><ul><li>(a b c) <=> (a.(b.(c.nil))) </li></ul><ul><li>(a.(b c)) <=> (a b c) </li></ul><ul><li>Выражение точечной нотации можно привести к списочной, если cdr -поле – список. </li></ul>
  7. 7. Списочная ячейка и базовые функции <ul><li>Результат функции Сar – значение левого поля первой списочной ячейки </li></ul><ul><li>* (сar '(a (b c) d) </li></ul><ul><li>a </li></ul><ul><li>Результат функции Сdr – значение правого поля первой списочной ячейки. </li></ul><ul><li>* (сdr '(a (b c) d) </li></ul><ul><li>((b c) d) </li></ul>
  8. 8. Списочная ячейка и базовые функции <ul><li>CONS создает новую списочную ячейку, car -поле которой указывает на первый элемент, а cdr на второй (cons 'x '(a b c)) . </li></ul>
  9. 9. Списочная ячейка и базовые функции <ul><li>LIST </li></ul><ul><li>Создается списочная ячейка для каждого аргумента . </li></ul><ul><li>В car - поле ставится указатель на соответствующий элемент . </li></ul><ul><li>В cdr - поле ставится указатель на следующую списочную ячейку . </li></ul><ul><li>* (list 'a '(b c)) </li></ul><ul><li>(a (b c)) </li></ul>
  10. 10. Переменные и списки <ul><li>Использование переменной в функции обеспечивает доступ к структуре . </li></ul><ul><li>(setq y '(a b c)) </li></ul><ul><li>CONS, не изменяя структуры, увеличивает список. </li></ul><ul><li>(setq x (cons 'd y)) </li></ul>
  11. 11. Переменные и списки <ul><li>Если в функции присвоения список задается явно, под него отводятся новые списочные ячейки </li></ul><ul><li>(setq z '(a b c)) </li></ul><ul><li>Переменная z будет иметь значение '(a b c) . </li></ul>
  12. 12. Равенство списков <ul><li>EQ – физическое равенство – одинаковая структура </li></ul><ul><li>EQUAL – логическое равенство – одинаковые элементы </li></ul><ul><li>EQL – эквивалентность символов и чисел </li></ul><ul><li>Структура списка определяется списочными ячейками. </li></ul>
  13. 13. Пример <ul><li>* (setq lis1 '(a b)) </li></ul><ul><li>* (setq lis2 '(a b)) </li></ul><ul><li>* (setq lis3 lis1) </li></ul>* (equal lis1 lis2) t * (equal lis1 lis3) t * (eql lis1 lis2) nil * (eql lis1 lis3) t * (eq lis1 lis2) nil * (eq lis1 lis3) t * (setq m 'abc) * (setq n 'abc) * (eq m n) t Для отдельного атома принцип не выполняется, т.е. новые ячейки не отводятся.
  14. 14. Cборка мусора <ul><li>«Мусор» - структуры, на которые нельзя ссылаться. </li></ul><ul><li>* (setq l1 '((a) b c)) </li></ul><ul><li>* (setq l1 (cdr l1)) </li></ul><ul><li>Сборщик мусора (garbage collector) GC – собирает ставшие мусором ячейки в область свободной памяти для использования. </li></ul>
  15. 15. Обработка списков без разрушения. Append
  16. 16. Обработка списков без разрушения. Append. <ul><li>Операции над списками не вносят изменений в указатели списочных ячеек: </li></ul><ul><li>создается копия списочной ячейки с новым содержанием полей. </li></ul><ul><li>Функция APPEND </li></ul><ul><li>* (setq first '(a b)) (a b) * (setq second '(c d)) (c d) * (setq both (append first second)) (a b c d) </li></ul>
  17. 17. Структура при APPEND Append создает копии всех списочных ячеек для каждого элемента во всех аргументах, исключая последний. C ons создает только одну списочную ячейку.
  18. 18. Разрушающие функции
  19. 19. Разрушающие функции Функции, которые изменяют содержимое указателей вместо создания новых списочных ячеек, называют разрушающими . (т.к. указатель заменяется и исходная структура разрушается)
  20. 20. NCONC <ul><li>позволяет соединить два списка изменением указателя. </li></ul><ul><li>(setq new (nconc first second)) </li></ul><ul><li>Список не копируется. </li></ul><ul><li>N il в последней списочной ячейке меняется на указатель к первой списочной ячейке второго списка. </li></ul>
  21. 21. RPLACA, RPLACD <ul><li>Функции от двух аргументов (первый – список) изменяют структуру своих аргументов. </li></ul><ul><li>rplaca – &quot;replace the car&quot; – заменяет car первого аргумента на второй. </li></ul><ul><li>(Т.е. указатель car первой списочной ячейки меняется на указатель ко второму аргументу.) </li></ul><ul><li>rplacd – &quot;replace the cdr&quot; – заменяется cdr- указатель. </li></ul>
  22. 22. Механизм действия <ul><li>* (setq lis1 '(a b c)) </li></ul><ul><li>* (setq lis2 '(a b c)) </li></ul>
  23. 23. <ul><li>* (rplaca lis1 'd) </li></ul><ul><li>(d b c) </li></ul><ul><li>* (rplacd lis2 '(e f)) </li></ul><ul><li>(a e f) </li></ul>Механизм действия Через setf (rplaca x y) <=> (setf (car x) y) (rplacd x y) <=> (setf (cdr x) y)
  24. 24. Пример <ul><li>Функция replace-item имеет три аргумента: первый элемент должен быть списком, разрушающе замещает первое местоположение второго аргумента в списке на третий аргумент. </li></ul><ul><li>(defun replace-item (lis old new) (rplaca (member old lis) new)) </li></ul><ul><li>* ( replace-item ‘(d a s d a f) ‘a ‘n) </li></ul><ul><li>(n s d a f) </li></ul>
  25. 25. Использование разрушающих функций <ul><li>При работе с большими списками, чтобы не увеличивать расход памяти. (Например, использовать nconc вместо append .) </li></ul><ul><li>Использование требует осторожности: </li></ul><ul><li>побочный эффект – можно получить бесконечные списки. </li></ul><ul><li>* (setq v1 '(a b c)) </li></ul><ul><li>(a b c) </li></ul><ul><li>* (setq v2 v1) </li></ul><ul><li>(a b c) </li></ul><ul><li>* (setq v2 (nconc v1 v2)) </li></ul><ul><li>(a b c a b c....) </li></ul>
  26. 26. Применяющие функционалы
  27. 27. Применяющие функционалы применяют функциональный аргумент к своим параметрам. APPLY FUNCALL Применяющие функционалы вычисляют значение функции. (В этом смысле они аналогичны функции EVAL , вычисляющей значение выражения. )
  28. 28. APPLY <ul><li>Предположим, мы хотим объединить в один список несколько вложенных списков. APPLY применяет функцию к элементам списка, как к аргументам функции. </li></ul>
  29. 29. Пример 1 <ul><li>Часто apply используют вместе c марсаr . </li></ul><ul><li>Задача: найти общее число элементов в списках. </li></ul><ul><li>* (countall '((a b c) (d e f) (k l))) </li></ul><ul><li>8 </li></ul><ul><li>(defun countall (lis) (apply '+ (mapcar 'length lis)) </li></ul><ul><li>) </li></ul>
  30. 30. Пример 2 <ul><li>Функция countatom считает элементы в любом списке. </li></ul><ul><li>* (countatom '(a (a (b) c) (d) e (f g))) </li></ul><ul><li>8 </li></ul><ul><li>(defun countatom (lis) (cond ((null lis) 0) ((atom lis) 1) (t (apply '+ (mapcar 'countatom lis))) </li></ul><ul><li>) </li></ul><ul><li>) </li></ul>
  31. 31. Cочетание apply, nconc, mapcar – mapcan <ul><li>Задача: Построить функцию, образующую список из хвостов списков. </li></ul><ul><li>* (list-last '((a b) (b c) (c d))) </li></ul><ul><li>(b c d) </li></ul><ul><li>(defun list-last (lis) (apply 'append (mapcar 'last lis))) </li></ul><ul><li>APPEND работает медленно и оставляет много мусора. Можно это сделать через nconc : </li></ul><ul><li>(defun list-last (lis) (apply 'nconc (mapcar 'last lis))) </li></ul>
  32. 32. Cочетание apply, nconc, mapcar – mapcan <ul><li>Отображающий функционал mapcan объединяет результаты в один список, используя функцию nconc . </li></ul><ul><li>Механизм действия: </li></ul><ul><li>(mapcan fn x1 x2 ... xN)  (apply 'nconc (mapcar fn x1 x2 ... xN)) </li></ul>
  33. 33. Cочетание apply, nconc, mapcar – mapcan <ul><li>Задача: Построить функцию, образующую список из хвостов списков. </li></ul><ul><li>* (list-last '((a b) (b c) (c d))) </li></ul><ul><li>(b c d) </li></ul><ul><li>(defun list-last (lis) (mapcan 'last lis)) </li></ul>
  34. 34. Функционал FUNCALL <ul><li>Применяющий функционал FUNCALL аналогичен APPLY , но аргументы принимает не в списке, а по отдельности: </li></ul><ul><li>(funcall fn x1 x2 ... xN)  (fn x1 x2 ... xN) </li></ul><ul><li>здесь fn – функция с n аргументами. </li></ul>* (funcall '+ 1 2) <=> * (+ 1 2) 3 * (funcall (car '(+ - / *)) 1 2) 3
  35. 35. Пример <ul><li>Рассмотрим использование funcall для построения функции map2 , которая действует аналогично mapcar , но берет в качестве аргументов два элемента из списка, а не один. </li></ul><ul><li>* (map2 'list '(A Christie V Nabokov K Vonnegut)) </li></ul><ul><li>((A Christie) (V Nabokov) (K Vonnegut)) </li></ul><ul><li>(defun map2 (f2 lst) </li></ul><ul><li>(if (null lst) nil </li></ul><ul><li>(cons (funcall f2 (car lst) (cadr lst)) </li></ul><ul><li>(map2 f2 (cddr lst))) </li></ul><ul><li>) </li></ul><ul><li>) </li></ul>
  36. 36. Блокировка функции <ul><li>‘ х  (QUOTE х) </li></ul><ul><li># ‘f  (FUNCTION f ) </li></ul><ul><li>(+ 2 3) </li></ul><ul><li>(funcall ‘+ 2 3) </li></ul><ul><li>(funcall #‘+ 2 3) </li></ul>
  37. 37. Замыкание <ul><li>(defun f1 (x) </li></ul><ul><li>(cons </li></ul><ul><li>(function (lambda (y) (+ x y))) </li></ul><ul><li>(function (lambda (y) (setq x y))))) </li></ul><ul><li>* (setq para (f1 10)) </li></ul><ul><li>* (funcall (car para) 2) ;; 1-е замыкание (для MCL не работает) </li></ul><ul><li>12 </li></ul><ul><li>* (funcall (cdr para) 100) ;; 2-е замыкание </li></ul><ul><li>100 </li></ul><ul><li>* (funcall (car para) 102) ;; 2-е </li></ul><ul><li>202 </li></ul>
  38. 38. Блокировки вычисления <ul><li>FUNCTION или #‘ используется тогда, когда в замыкаемой функции есть свободные переменные </li></ul><ul><li>Если в замыкаемой функции нет свободных (глобальных функции) переменных, то форма FUNCTION ни чем не отличается от формы QUOTE </li></ul>
  39. 39. Спасибо за внимание! <ul><li> Вопросы? </li></ul>

×