ИМЯ И ЗНАЧЕНИЕ СИМВОЛА Функциональное программирование Григорьева И.В.
2 Значением константы является сама константа Значением константы является сама константа Символ может обозначать произвольное выражение Символ может обозначать произвольное выражение SET вычисляет имя и связывает его SET вычисляет имя и связывает его SETQ связывает имя, не вычисляя его SETQ связывает имя, не вычисляя его SETF - обобщенная функция присваивания SETF - обобщенная функция присваивания Побочный эффект псевдофункции Побочный эффект псевдофункции Вызов интерпретатора EVAL вычисляет значение значения Вызов интерпретатора EVAL вычисляет значение значения Основной цикл: READ-EVAL-PRINT Основной цикл: READ-EVAL-PRINT
3 Значением константы является сама константа Константы обозначают самих себя. Если мы введем константу, то интерпретатор в качестве результата выдаст саму эту константу: t -> T t -> T nil -> NIL nil -> NIL >
4 Символ может обозначать произвольное выражение Символы можно использовать как переменные. В этом случае они могут обозначать некоторые выражения. У символов изначально нет какого- нибудь значения, как у констант. Если, например, введем символ ФУНКЦИИ, то мы получим сообщение об ошибке: функции -> Error: Unbound atom ФУНКЦИИ Интерпретатор здесь не может вычислить у значение символа, поскольку его у него нет.
5 SET вычисляет имя и связывает его При помощи функции SET символу можно присвоить или связать с ним некоторое значение. (set 'функции '(car cdr cons atom eq)) -> (CAR CDR CONS ATOM EQ) Эта связь, которая действительна до окончания работы, если, конечно, этому имени функцией SET не будет присвоено новое значение. После присваивания интерпретатор уже может вычислить значение символа ФУНКЦИИ: Функции -> (CAR CDR CONS ATOM EQ)
6 SET вычисляет оба аргумента. (set (car Функции) '(взбрести в голову)) -> (ВЗБРЕСТИ В ГОЛОВУ) (саr функции) ;первый аргумент -> CAR ; предыдущего вызова CAR ;присвоенное -> (ВЗБРЕСТИ В ГОЛОВУ) ; функцией SET функции ; значение -> (CAR CDR CONS ATOM EQ)
7 Значения символов определяются с помощью специальной функции SYMBOL- VALUE, которая возвращает в качестве своего значения значение символа, являющегося ее аргументом. (symbol-value (car функции)) -> (ВЗБРЕСТИ В ГОЛОВУ)
8 SETQ связывает имя, не вычисляя его (setq функции '(саг cdr cons atom eq)) -> (CAR CDR CONS ATOM EQ) При использовании функции SETQ отпадает надобность в знаке апострофа перед первым аргументом. Проверить, связан ли атом, можно с помощью предиката BOUNDP, который истинен, когда атом имеет какое-нибудь значение: (boundp 'беззначения) ->NIL
9 SETF - обобщенная функция присваивания Для присваивания существует обобщенная функция обновления данных SETF, которая записывает в ячейку памяти новое значение: (SETF ячейка-памяти значение) Через функцию SETF можно представить описанные нами ранее функции SET и SETQ: (setq х у) (setf x у) (set х у) (setf (symbol-value x) у) (setf список '(a Ь с)) -> (А В С) список ->(А В С)
10 Побочный эффект псевдофункции Функции SET, SETQ и SETF отличаются от других рассмотренных функций тем, что помимо того, что они имеют значение, они обладают и побочным эффектом. Эффект функции состоит в образовании связи между символом и его значением, а значением функции является связываемое значение. Символ остается связанным с определенным значением до тех пор, пока это значение не изменят.
11 Вызов интерпретатора EVAL вычисляет значение значения Интерпретатор Лиспа называется EVAL, и его можно так же, как и другие функции вызывать из программы. QUOTE и EVAL действуют во взаимно противоположных направлениях и аннулируют эффект друг друга. EVAL- это универсальная функция Лиспа, которая может вычислить любое правильно составленное лисповское выражение. EVAL определяет семантику (semantics) лисповских форм, т.е. определяет, какие символы и формы совместно с чем и что означают и какие выражения имеют значение.
12 (quote (+ 2 3)) -> (+ 2 3) (eval (quote (+ 2 3))) -> 5 (setq x (a b c)) -> (A B C) x->X (eval x)-> (A B C) (eval x)-> ошибка (eval (quote (quote (a b c)))) -> (A B C) (quote (eval x)) -> (eval x)
13 Основной цикл: READ-EVAL- PRINT Диалог с интерпретатором Лиспа на самом верхнем, командном уровне, можно описать простым циклом: (print _); вывод приглашения (setq e (read)); ввод выражения (setq v (eval e)); вычисление его значения (print v); вывод результата
14Упражнения 1.Каковы будут значения следующих вызовов при условии, что значением X является Y, а значением Y-X: 1.Каковы будут значения следующих вызовов при условии, что значением X является Y, а значением Y-X: (set х у) (setq х у) (setf х у) 2.Каково будет значение атома А после следующих вызовов: 2.Каково будет значение атома А после следующих вызовов: a)(set (setq а 'а) 'Ь) Ь)(set (setq b 'a) (setq а 'с)) c) (set b a) Вычислите значения следующих выражений Вычислите значения следующих выражений а) '(саг '(а Ь с)) b) (eval '(car '(а Ь с))) c) (eval (car '(а Ь с))) d) (eval (quote (quote quote))) e) (quote (eval (quote (quote quote))))