45719 (762110), страница 2

Файл №762110 45719 (Функциональное программирование) 2 страница45719 (762110) страница 22016-08-02СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 2)

Программа на языке lisp задается как список применений функций, часть из которых может вычисляться во время исполнения самой программы. Как правило, заданные в программе списки интерпретируются как применения функций и вычисляются, если другое не определяют ранее активированные функции (вы видели, что функция quote запрещает вычисление своего аргумента, функция setq запрещает вычисление лишь первого из двух аргументов, а функция setf заставляет вычислить первый аргумент лишь до стадии, когда получена ссылка на его значение). Любое выражение выдает значение, что используется, в частности, при диалоговой работе с lisp (на примере которой иллюстрируются понятия).

Основные управляющие функции концептуально едины и позволяют динамически строить блочную структуру программы. В частности, функция

(block name e1 . . . en) (8.1)

вычисляет свои аргументы, начиная со второго, один за другим, тем самым задавая последовательность команд. Первый ее аргумент, name, служит именем блока. В любой момент из любого объемлющего блока можно выйти и выдать значение с помощью функции

(return-from name value) (8.2)

Этим lisp выгодно отличается от большинства языков, где такие структурные переходы либо неполны, либо некорректно реализованы.

Далее, блоком считается любое описание функции. Описание функции производится при помощи функции defun, которая, в свою очередь, определяется через примитивы function и lambda. Первый из них задает, что имя, являющееся его аргументом, рассматривается как функция (он часто сокращается в конкретном синтаксисе до #'), второй образует значение функционального типа. Имя функции является и именем функционального блока.

Пример 8.4.1. В данном примере иллюстрируются определение факториала, вызов анонимной функции и возможность вычисления произвольного функционального выражения, созданного в программе.

[1]> (defun fact (n) (if (= n 0) 1

(* (fact (- n 1)) n)))

FACT

[2]> (fact 40)

815915283247897734345611269596115894272000000000

[3]> ((lambda (x) (fact (* x x))) 5)

15511210043330985984000000

[4]> (setq g '(lambda (x) (fact (* x x))))

(LAMBDA (X) (FACT (* X X)))

[5]> (eval (list g 3))

362880

Нужно заметить, что определение функции с данным именем и значение имени могут задаваться независимо. Например, мы можем в этом же контексте задать (setq fact 7), хотя, конечно же, это отвратительный способ программирования.

Все формальные параметры функций являются локальными переменными. Никакие изменения их значений не выходят наружу. Но все другие свойства остаются глобальными! Приведем пример.

[23]> (defun f (x) (progn (setf

(get 'x 'weight) '(25 kg)) (+ x 3)))

F

[24]> (setf (get 'x 'weight) '(30 kg))

(30 KG)

[25]> (get 'x 'weight)

(30 KG)

[26]> (setq x 5)

5

[27]> (f 3)

6

[28]> x

5

[29]> (get 'x 'weight)

(25 KG)

В lisp имеется возможность создать анонимный блок со своими локальными переменными, не объявляя его функцией. Создание такого блока называется связыванием переменных и производится функцией let.

Значение имени, унаследованного извне, все равно будет внешним! Смотрите пример ниже.

[32]>(setq a '(b c d))

(B C D)

[33]>(setq b 5)

5

[34]> (list (let ((b 6)) (eval (car a)))

(eval (car a)))

(5 5)

[35]> (list (let ((b 6)) b) (eval (car a)))

(6 5)

[36]> (list (let ((b 6)) (list b a))

(eval (car a)))

((6 (B C D)) 5)

[37]> (list (let ((b 6)) (eval (car

(list 'b a)))) (eval (car a)))

(5 5)

Важнейшей особенностью функционального программирования как стиля, впервые использованной в языке lisp, являются функционалы с аргументами-функциями. Рассмотрим пример возведения всех членов кортежа в квадрат.

[57]> (setq a (list 1 5 7 9 11 13 15 19 22 28))

(1 5 7 9 11 13 15 19 22 28)

[58]> (mapcar (function (lambda (x) (* x x))) a)

(1 25 49 81 121 169 225 361 484 784)

Функционал mapcar применяет свой первый аргумент ко всем членам второго.

Такие функционалы, в частности, делают циклы практически ненужными. Тем не менее в языке lisp есть конструкции циклов как дань программистской традиции. Чужеродность циклов подчеркивается тем, что они всегда выдают значение nil.

И, наконец, приведем пример3.

Пример 8.4.2. Данная программа строит автомат для нахождения всех вхождений некоторой системы слов во входной поток. Позже она анализируется с точки зрения автоматного программирования.

Листинг 8.4.1. Автомат для нахождения всех вхождений некоторой системы слов во входной поток (html, txt)

Прагматические добавления и динамическое порождение программ

Разберем возможности языка lisp в комплексе.

Выразительные средства конкретно-синтаксического представления общей структуры данных и программ языка lisp крайне скупы. Но это представление позволяет практически однозначно связать синтаксис и реализационную структуру.

Реализационное представление как нельзя лучше соответствует соглашению об общности функциональной структуры и структуры данных: в каждом списке голова рассматривается как указание (имя, ссылка или что-то подобное) на функцию, а хвост - как последовательность указаний на аргументы. Задание свойства списка не быть функцией, т. е. отмена выделенного статуса головы, обозначающей функцию, достигается с помощью блокировок. Это удачное решение в условиях принятого соглашения, позволяющее трактовать нефункциональный список как константную функцию, свое изображение (представление). Еще более важно то, что оно обеспечивает гибкость представления: функцию eval, заставляющую список принудительно вычисляться, естественно трактовать просто как снятие блокировок. Заметим, что на уровне абстрактного синтаксиса функция eval обязана быть универсально применимой к любому списку.

К сожалению, такой универсализм провоцирует крайне ненадежное и неэффективное программирование, поэтому это решение нельзя считать удачным. Справедливости ради заметим, что в те времена, когда разрабатывался язык, задача надежности еще не была поставлена, но плохо то, что сформировался стихийный стандарт, не способствующий качеству программирования.

Для обеспечения практической пользы функции eval следовало бы предусмотреть компенсирующие регламенты ее корректного применения на уровне конкретного синтаксиса, режимов вычислений и системных механизмов.

Внимание!

На уровне абстрактного и конкретного синтаксиса разные семантические возможности имеют разный статус, поэтому в конкретном представлении необходимо предусматривать механизм скрытия и даже полного запрета тех возможностей, которые концептуально разумны лишь на уровне абстрактного синтаксиса4.

Структура списков lisp идеальна для представления абстрактного синтаксиса языка. И хотя злые языки называют этот синтаксис , он в точности соответствует абстрактному синтаксису. Если даже не учитывать преимущества указанного соответствия, то остается простота представления программ и данных в виде линейной текстовой последовательности символов.

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

Сегодня можно было бы говорить о других форматах конкретного синтаксиса lisp, в том числе и не связанных с линейным представлением. Использование развитых средств графики при экранном наборе программ позволяет на полную мощь подключить двумерную работу. Однако традиции и стихийно сформировавшиеся стандарты не оставляют возможности для внедрения таких форматов. Здесь в очередной раз и в полной мере проявились вредные эффекты ранней стандартизации, мешающие развитию направления, остающегося одним из самых концептуально богатых и перспективных.

Диктат линейности укоренился настолько глубоко, что даже в тех случаях, когда он мог бы быть преодолен безболезненно, языковая система чаще всего все равно строится как линейная. Это касается не только функционального стиля5.

Объекты и LISP

Стандартная надстройка над Common Lisp, имитирующая объектно-ориентированный стиль, это модуль CLOS - Common Lisp Object System. Сама по себе объектность не дает никакого выигрыша по сравнению с языком lisp, поскольку возможности динамического вычисления функций в lisp даже шире. Видимо, именно поэтому в CLOS имеются две интересных модификации, делающие его не совсем похожим на стандартное ООП.

Начнем с понятия структуры данных в языке Common Lisp. Структура определяется функцией defstruct вида

(defstruct pet name (species 'cat) age weight sex)

Задание структуры автоматически задает функцию-конструктор структуры make-pet, которая может принимать ключевые аргументы для каждого из полей:

(make-pet :nick 'viola :age '(3 years) :sex 'femina))

и функцию доступа для каждого из полей, например pet-nick, использующуюся для получения значения поля или ссылки на него. Если поле не инициализировано (ни по умолчанию, ни конструктором), оно получает начальное значение nil. Никакой дальнейшей спецификации полей структур нет6.

В объекте для каждого поля могут явно указываться функции доступа и имена ключевых параметров для инициализации аргументов. Приведем пример класса, определенного на базе другого класса.

(defclass pet (animal possession) (

(species :initform 'cat)

(nick :accessor nickof

:inintform 'Pussy

:initarg namepet)

)

Этот класс наследует поля, функции доступа и прочее от классов animal и possession. Например, поле cost имеется в значении класса, если оно имеется в одном из этих классов. Поскольку статических типов у полей нет, нет и конфликтов.

Основная функция наследования в CLOS - определение упорядочения на классах. С каждым классом связано свое упорядочение. Наследник меньше своих предков, из предков меньшим считается тот, который раньше перечислен в списке наследования при определении класса. CLOS достраивает этот частичный порядок до линейного. Способ пополнения порядка может быть в любой момент и без оповещения изменен, и хакерское использование особенностей конкретного пополнения считается грубой стилистической ошибкой. Если система находит несовместимость в определении порядка, то она выдает ошибку, как в следующем примере:

[6]> (defclass init () ())

#

[7]> (defclass a (init) ())

#

[8]> (defclass b (init) ())

#

[9]> (defclass c1 (a b) ())

#

[10]> (defclass c2 (b a) ())

#

[11]> (defclass contr (c1 c2) ())

*** - DEFCLASS CONTR:

inconsistent precedence graph,

cycle (# #)

В CLOS могут задаваться методы, отличающиеся от функций тем, что их аргументы специфицированы, например

(defmethod inspectpet ((x pet) (y float))

(setf weightofanimal 3.5))

Как видно из этого примера, методы не обязательно связаны с классами. Они могут быть связаны с любыми типами. Методы в CLOS могут иметь дополнительные спецификации. Для того, чтобы разобраться, как эти спецификации взаимодействуют с упорядочением типов классов, рассмотрим следующую программу и генерируемый при ее исполнении результат.

Листинг 8.6.1. Взаимодействие дополнительных спецификаций методов в CLOS с упорядочением типов классов (html, txt)

При загрузке этого файла происходит следующее:

Пример 8.6.2. Результат загрузки программы 8.6.1 (html, txt)

Видно, что упорядоченность классов по отношению наследования позволяет выстраивать целые последовательности действий при вызове одного метода.

Поскольку в CLOS нет ни механизмов скрытия конкретных представлений, ни механизмов замены прямого доступа к данным на функции, ни других характерных особенностей ООП, мы видим еще один пример того, как модным словом (в данном случае ООП) прикрывается другая, не менее интересная сущность: начатки планирования действий по структуре типов данных. В связи с этим стоит напомнить блестящий эксперимент планирования вычислений по структуре данных, в настоящий момент (судя по всему, временно) забытый: эстонскую систему PRIZ [Тыугу Э.Х. Концептуальное программирование. М. Наука. 1984. - 256 с.].

Неадекватное теоретизирование мешает увидеть и развить реальные достоинства системы и закрепляет слабые места.

Список литературы

Для подготовки данной работы были использованы материалы с сайта http://www.citforum.ru/

Характеристики

Тип файла
Документ
Размер
393,47 Kb
Тип материала
Учебное заведение
Неизвестно

Список файлов статьи

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6989
Авторов
на СтудИзбе
262
Средний доход
с одного платного файла
Обучение Подробнее
{user_main_secret_data}