Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Программа состоит из форм и функцийСодержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
Под формой (form) понимается такое символьное выражение, значение которого может быть найдено интерпретатором. Ранее мы уже использовали наиболее простые формы языка: константы, переменные, лямбда-вызовы, вызовы функций и их сочетание. Кроме них были рассмотрены некоторые специальные формы, такие как QUOTE и SETQ, трактующие свои аргументы иначе, чем обычные функции. Лямбда-выражение без фактических параметров не является формой. Вычислимые выражения можно разделить на три группы: 1) Самоопределенные (self-evaluating) формы. Эти формы, подобно константам, являются лисповскими объектами, представляющими лишь самих себя. Это такие формы, как числа и специальные константы Т и NIL, а также знаки, строки и битовые векторы, которые мы рассмотрим далее. Ключи, начинающиеся с двоеточия и определяемые через ключевое слово &KEY в лямбда-списке, также являются самоооределенными формами. 2) Символы, которые используются в качестве переменных. 3) Формы в виде списочной структуры, которыми являются: a) Вызовы функций и лямбда-вызовы. b) Специальные формы (special form), в число которых входят SETQ, QUOTE и другие, предназначенные для управления вычислением и контекстом. c) Макровызовы (рассмотрим немного позднее). У каждой формы свой синтаксис и семантика, основанные, однако, на едином способе записи и интерпретации.
Управляющие структуры Лиспа являются формами В распространенных процедурных языках наряду с основными действиями есть специальные управляющие механизмы разветвления вычислений и организации циклов. В Паскале, например, используются структуры IF THEN ELSE, WHILE DO, CASE и другие. Управляющие структуры Лиспа (мы будем для них использовать термин предложение (clause)) выглядят внешне как вызовы функций. Предложения будут записываться в виде скобочных выражений, первый элемент которых действует как имя управляющей структуры, а остальные элементы – как «аргументы». Результатом вычисления, так же как у функции, является значение, т.е. управляющие структуры представляют собой формы. Однако предложения не являются вызовами функций, и разные предложения используют аргументы по-разному. Наиболее важные с точки зрения программирования синтаксические формы можно на основе их использования разделить на следующие группы:
1. Работа с контекстом: - QUOTE или блокировка вычислений; - Вызов функции и лямбда-вызов; - Предложения LET и LET*
2. Последовательное исполнение: - предложения PROG1, PROG2 и PROGN. 3. Разветвление вычислений: - условные предложения COND, IF, WHEN, UNLESS; - выбирающее предложение CASE. 4. Итерации: - циклические предложения DO, DO*, LOOP, DOTIMES, DOUNTIL.
5. Передачи управления: - предложения PROG, GO и RETURN.
6. Динамическое управление вычислением: - THROW и CATCH, а также BLOCK.
Ранее мы уже рассмотрели форму QUOTE, а также лямбда-вызов и вызов функции. Эти формы тесно связаны с механизмом определения функций и их вызова. Остальные формы в основном используются в теле лямбда-выражений, определяющих функции.
LET создает локальную связь Вычисление вызова функции создает на время вычисления новые связи для формальных параметров функции. Новые связи внутри формы можно создать и с помощью предложения LET. Эта структура (немного упрощенно) выглядит так:
(LET ((m1 знач1) (m2 знач2)...) форма1 форма2...) Предложение LET вычисляется так, что сначала статические переменные m1, m2,... из первого «аргумента» формы связываются (одновременно) с соответствующими значениями знач1, знач2,... Затем слева направо вычисляются значения форм форма1, форма2,... В качестве значения всей формы возвращается значение последней формы. Как и у функций, после окончания вычисления связи статических переменных m1, m2,... ликвидируются и любые изменения их значений (SETQ) не будут видны извне. Например:
_(setq x 2) _(let ((x 0)) (setq x 1)) _x Форма LET является на самом деле синтаксическим видоизменением лямбда-вызова, в которой формальные и фактические параметры помещены совместно в начале формы:
(LET ((m1 a1) (m2 a2)... (mn an)) форма1 форма2...) ó ((LAMBDA (m1 m2... mn); формальные параметры форма1 форма2...); тело функции а1 а2...an); фактические параметры Тело лямбда-выражения в Коммон Лиспе может состоять из нескольких форм, которые вычисляются последовательно, и значение последней формы возвращается в качестве значения лямбда-вызова. Значения переменным формы LET присваиваются одновременно. Это означает, что значения всех переменных mi вычисляются до того, как осуществляется связывание с формальными параметрами. Новые связи этих переменных еще не действуют в момент вычисления начальных значений переменных, которые перечислены в форме позднее. Например:
_(let ((x 2) (y (* 3 x))) (list x y)); при вычислении Y Error: Unbound atom X; у Х нет связи Побочный эффект можно наблюдать при работе с формой LET* подобной LET, но вычисляющей значения переменных последовательно:
_(let* ((x 2) (y (* 3 x))) (list x y)) (2 6) Последовательные вычисления: PROG1, PROG2 и PROGN Предложения PROG1, PROG2 и PROGN позволяют работать с несколькими вычисляемыми формами:
(PROG1 форма1 форма2... формаN) (PROG2 форма1 форма2... формаN) (PROGN форма1 форма2... формаN) У этих специальных форм переменное число аргументов, которые они последовательно вычисляют и возвращают в качестве значения значение первого (PROG1), второго (PROG2) или последнего (PROGN) аргумента. Эти формы не содержат механизма определения внутренних переменных:
_(prong (setq x 2) (setq y (* 3 x))) _x Многие формы, как, например описанная выше форма LET(*), позволяют использовать последовательность форм, вычисляемых последовательно, и в качестве результата последовательности возвращают значение последней формы. Это свойство называют неявным PROGN (implicit prong feature).
Разветвление вычислений: условное предложение COND Предложение COND является основным средством разветвления вычислений. Это синтаксическая форма, позволяющая управлять вычислениями на основе определяемых предикатами условий. Структура условного предложения такова:
(COND (p1 a1) (p2 a2) ... (pN aN)) Предикатами pi и результирующими выражениями ai могут быть произвольные формы. Значение предложения COND определяется следующим образом: 1. Выражения pi, выполняющие роль предикатов, вычисляются последовательно слева направо (сверху вниз) до тех пор, пока не встретится выражение, значением которого не является NIL, т.е. логическим значением которого является истина; 2. Вычисляется результирующее выражение, соответствующее этому предикату, и полученное значение возвращается в качестве значения всего предложения COND; 3. Если истинного предиката нет, то значением COND будет NIL.
Рекомендуется в качестве последнего предиката использовать символ Т, и соответствующее ему результирующее выражение будет вычисляться всегда в тех случаях, когда ни одно другое условие не выполняется. В следующем примере с помощью предложения COND определена функция, устанавливающая тип выражения (здесь для примера принимается, что возможны лишь три типа выражений: пустой список, атом и список):
_(defun тип (l) (cond ((null l) ’пусто) ((atom l) ’атом) (t ’список))) ТИП _(тип ’(a b c)) СПИСОК _(тип (atom ’(а т о м))) ПУСТО В условном предложении может отсутствовать результирующее выражение ai или на его месте часто может быть последовательность форм:
(COND (p1 a11) ... (pi); результирующее Выражение отсутствует (pk ak1 ak2...akN); последовательность форм В качестве результата Если условию не ставится в соответствие результирующее выражение, то в качестве результата предложения COND при истинности предиката выдается само значение предиката. Если же условию соответствует несколько форм, то при его истинности формы вычисляются последовательно слева направо и результатом предложения COND будет значение последней формы последовательности (неявный PROGN). В качестве примера использования условного предложения определим логические действия логики высказываний «и», «или», «не», => (импликация) и < = > (тождество):
_(defun и (x y) (cond (x y) (t nil))) И _(и t nil) NIL _(defun или (x y) (cond (x t) (t y))) ИЛИ _(или t nil) T _(defun не (x) (not x)) НЕ _(не t) NIL _(defun => (x y) (cond (x y) (t t))) => _(=> nil t) T Импликацию можно определить через другие операции:
_(defun => (x y) (или x (не y))) => _(defun < = > (x y) (и (=> x y) (=> y x))) < = > Предикаты «и» и «или» входят в состав встроенных функций Лиспа и называются AND и OR. Число их аргументов может быть произвольным.
_(and (atom nil) (null nil) (eq nil nil)) T Предикат AND в случае истинности возвращает в качестве значения значение своего последнего аргумента. Его иногда используют как упрощение условного предложения по следующему образцу:
(AND условие1 условие2... условиеN) ó (COND ((AND условие1 условие2... условиеN-1) условиеN) (T NIL)) _(and (atom nil) (+ 2 3)) Такое использование предиката AND не рекомендуется. Предложения COND можно комбинировать таким же образом, как и вызовы функций. Например, предикат «исключающее или», который является ложным, когда оба аргумента одновременно либо истинны, либо нет, можно определить следующим образом:
_(defun xor (x y) (cond (x (cond (y nil) (t t))) (t y))) XOR _(xor t nil) T _(xor nil nil) NIL В этой функции на месте результирующего выражения первого условия вновь стоит предложение COND. На месте, отведенном условию, также можно использовать еще одно условное предложение, и в этом случае мы получим условное условие. Такие построения очень быстро приводят к труднопонимаемым определениям.
|
||||
Последнее изменение этой страницы: 2016-09-05; просмотров: 467; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.19.251 (0.012 с.) |