В статье рассматриваются основные понятия языка Лисп.
Автор:
Написал: artish   Дата: 2008-09-08 21:33
Комментарии: (1)   Рейтинг:
Пользовательская оценка (от 1 до 10): 5.50   
Проголосовавших: 2 с 2008-12-07 18:18
Аббревиатура LISP рассшифровывается как LIST PROCCESSOR или по-русски: обработчик списков.
Список, пожалуй, базовое понятие в лиспе. Возьму на себя смелость утверждать, что в лиспе всё есть список.
Например, программа на лиспе - это несколько записанных подряд списков.
Список обозначается как набор разделенных пробелами (одним или несколькими) элементов списка, заключенные в круглые скопки:
(<элемент1>   <элемент2> <элемент3> ... <элементN>)
Элементами списка могут быть другие списки или АТОМЫ (второе базовое понятие в списке).
Атом - как и в физике (до недавнего времени :) ) обозначает нечто неделимое, например числа или символы.
(Более точные определения терминов мы дадим позже)

Например:

( (12 36 78) йцукен qwerty t () another-symbol)

Здесь приведен список состоящий соответственно из другого списка: (12 36 78) из символов йцукен и qwerty, специальных  символов  t (обозначающего "истинность") и () - (пустой список, то есть не содержащий ни одного элемента, он еще обозначает "ложь") и еще одного символа по имени enother-symbol.

Данные для лисп программы тоже представляют такой же список или атом. (вообще это не совсем верно, данные могут быть в любом виде, разумеется, но об этом ниже) Этот факт позволяет лисп программе теоретически обрабатывать другие лисп программы или саму себя. (хотя подобные программы мне неизвестны)
Например, привычные всем массивы могут быть представлены (и представляются) как список списков:

( 1 2 3 4 5 6 ) одномерный массив

    ((1 2 3)
    (4 5 6)
    (7 8 9)) - квадратный массив 3x3
Как вы понимаете, теоретических ограничений на размерность нет (есть физические - у каждого интерпретатора лиспа, свой)

Другой пример: ассоциативный список:

((кеу1 value1)
(key2 value2)
....................
(keyN valueN))
другими словами, ассоциативный список - это список, состоящий из двухэлементных списков, у которых  первый элемент -ключ, второй - значение. Причем, ключом и(или) значением , в свою очередь, могут быть другие списки....

Другой пример:

(DEFUN MY-SUBST (CLEARLIST SYMBOLLIST MY-LENGTH)
  (IF (NULL SYMBOLLIST)
 (PROGN (PRINT CLEARLIST)(PRINC (SETQ COUNTER (1+ COUNTER))))
      (DO ((I 0 (1+ I)))((> I (- MY-LENGTH 1))())
 (IF (null (ELT CLEARLIST I))
            (progn (setf (ELT CLEARLIST I) (CAR SYMBOLLIST))
   (MY-SUBST CLEARLIST (CDR SYMBOLLIST) MY-LENGTH)
(setf (ELT CLEARLIST I) NIL)
                 )))))

(DEFUN MAIN (SPISOK)(declare (special counter))
(setq counter 0)
 (MY-SUBST
   (make-list (LENGTH SPISOK) :initial-element NIL)
   SPISOK
   (LENGTH SPISOK)))

(MAIN '(Q W E R T Y U I O P A S D F G H J K L Z X C V B N M))

Сташно? :) Не бойтесь. Это пример реальной программы на LISP, которая принимает в качестве исходных данных список и перчатает в standard output все возможные перестановки . Давайте его разберем:
Эта программа состоит всего из трех списков (в лиспе перенос строки является пробельным символом и не несет никакого особого знчачения):

(defun my-subst (clearlist symbollist my-length) (if .......))
(defun main (spisok) (declare ........)
(main '(........))

Здесь три списка. Интерпретатор лиспа считывает их последовательно и по первому элементу списка определяет, как его обрабатывать.
Первые два - определение функций  по имени my-subst и main соответственно. Третий - вызов функции main с одним аргументом - списком.
(Функция my-subst вызывается из main)
Как интерпретировать остальную часть списка - зависит от первого элемента списка (он не обязательно должен быть атомом).
Например Если превый элемент атом defun - то второй элемент должен определять имя функции, второй элемент - список аргументов фунции, третий - тело функции:
(defun <имя> (<арг-лист>) <тело функции>)
Если первый элемент имя функции, то хвост списка - аргументы вызова, причем их количество должно соответствовать количеству элементов списка <арг-лист> в форме defun.
Например:
Определим функцию func1: (defun func1 (arg1 arg2 arg3) .....)
Соответственно вызов этой функции будет выглядеть так: (func1 '(a b c d) 2 'qwerty)
Здесь '(a b c d) первый аргумент, 2 - второй, 'qwerty - третий.



Онлайн :

0 пользователь(ей), 13 гость(ей) :




Реклама на сайте: