Создание меню в ЛИСПе

Слайд 2

Конструкции, которые понадобятся

loop - бесконечный цикл без связанных с ним переменных.
let -

Конструкции, которые понадобятся loop - бесконечный цикл без связанных с ним переменных.
объявление локальной переменной
dolist - DOLIST проходит по всем элементам списка, выполняя тело цикла с переменной, содержащей последовательно элементы списка
print - функции вывода с переходом на новую строку
princ - не переходят на новую строку и не выводит пробел
setq  - форма применяется для присваивания переменной и блокирует вычисление первого аргумента
Read - Функция ввода
cond - ветвление, специальная функция COND (condition). Ее аргументами являются двухэлементные списки, содержащие предикаты и соответствующие им выражения
return 'ok - RETURN - нормальное завершение программы. Аргумент return вычисляется, что и является значением программы. Никакие последующие операторы не вычисляются. Если программа прошла все свои операторы, не встретив Return, она завершается со значением NIL.
nth - функция NTH, выделяющая n-й элемент списка
Funcall – функционвл, функция, которая позволяет вызывать другие функции,

Слайд 3

Универсальное меню

;; Универсальное меню:
(defun uni-menu (lst-name lst-act)
 (loop
   (let ((p 0) (c

Универсальное меню ;; Универсальное меню: (defun uni-menu (lst-name lst-act) (loop (let ((p
0))  
  (dolist (m lst-name nil)
  (print p)(princ ".")(princ m)
  (setq p (1+ p)))
  (print p)(princ ". END")
  (print "Ваш выбор: ")
  (setq c (read))
  (cond ((= c p) (return 'ok))
  ((or (< c 0) (> c p)) (princ "Ошибка! Повторите."))
  (t (let ((f (nth c lst-act)))
  (funcall f)))))) )

Слайд 4

Составим две функции-исполнителя:

;; сложить два числа
(defun f+ ()
  (let ((x (progn (print

Составим две функции-исполнителя: ;; сложить два числа (defun f+ () (let ((x
'x=) (read)))
  (y (progn (print 'y=) (read))))
   (print (+ x y))))
;; Умножить два числа
(defun f* ()
  (let ((x (progn (print 'x=) (read)))
  (y (progn (print 'y=) (read))))
   (princ (* x y))))

Форма Prog имеет структуру, подобную определениям функций и процедур в Паскале:
(PROG, список рабочих переменных, последовательность операторов и атомов ... ) Первый список после символа PROG называется списком рабочих переменных. При
отсутствии таковых должно быть написано NIL или (). Форма Prog имеет структуру, подобную определениям функций и процедур в Паскале:

Слайд 5

Испытаем все вместе:

(uni-menu '("ADD 2 numbers" "MULTIPLY 2 numbers") '(f+ f*))

Испытаем все вместе: (uni-menu '("ADD 2 numbers" "MULTIPLY 2 numbers") '(f+ f*))

Слайд 6

Функциональный подход Определим функцию SUM1 суммирования элементов списка:

(defun sum1 (l)
(cond ((null l)

Функциональный подход Определим функцию SUM1 суммирования элементов списка: (defun sum1 (l) (cond
0)
(t (+ (car l)
(sum1 (cdr l))))))
SUM1
* (sum1 '(10 20 30 40 50))
150
* (sum1 '(1))
1
* (sum1 '())
0

Слайд 7

Императивный подход

Приведенные выше примеры можно переписать, используя цикл вместо рекурсии:
(defun sum3 (l)

Императивный подход Приведенные выше примеры можно переписать, используя цикл вместо рекурсии: (defun
(let ((sum 0))
(dolist (x l)
(setq sum (+ sum x))
)
sum))

Слайд 8

Трассировка — это отслеживание информации о ходе выполнения программы (например, о вызовах

Трассировка — это отслеживание информации о ходе выполнения программы (например, о вызовах
и аргументах функций) в целях ее отладки. В Lisp для этого можно воспользоваться макросом trace. Пример: (defun fact (n)  
(if (zerop n) 1
  (* n (fact (1- n)))))  
CL-USER>
(trace fact)
(FACT)
CL-USER> (fact 5)