Опубликован: 21.08.2007 | Доступ: свободный | Студентов: 1787 / 192 | Оценка: 4.23 / 3.74 | Длительность: 15:37:00
Лекция 7:

Функциональное программирование

< Лекция 6 || Лекция 7: 1234 || Лекция 8 >

Данные и программы

Рассмотрим на примере языка Лисп подход к представлению данных и программ в языках функционального программирования.

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

Функция CONS строит структуры данных из бинарных узлов, заполняя их парами объектов, являющихся значениями пары ее аргументов. Первый аргумент произвольного вида размещается в левой части бинарного узла, а второй, являющийся списком, - в правой.

Функция CAR обеспечивает доступ к первому элементу списка - его "голове", а функция CDR - к укороченному на один элемент списку - его "хвосту", т.е. к тому, что остается после удаления головы.

Функция ATOM позволяет различать составные и атомарные объекты: на атомах ее значение "истина", а на структурированных объектах - "ложь".

Функция EQ выполняет проверку атомарных объектов на равенство.

Различие истинностных значений в Лиспе принято отождествлять с разницей между пустым списком и остальными объектами, которым программист может придать в программе некоторый другой смысл. Таким образом, значение "ложь" - это всегда Nil.

Любая структура данных может быть построено из атомов с помощью CONS, и любая его часть может быть выделена с помощью CAR-CDR.

Атом Nil, рассматриваемый как представление пустого списка (), играет роль ограничителя в любом списке.

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

  1. Самая простая форма выражения - это переменная. Она может быть представлена как атом.
  2. Все более сложные формы понимаются как применение функции к ее аргументам ( вызов функции ). Аргументом функции может быть любая форма. Вызов функции можно строить как список, первый элемент которого - представление функции, остальные элементы - аргументы функции.
    (функция аргумент1 аргумент2 ... )
  3. Имена функций, как и переменные, изображаются с помощью атомов.

    Соответствие между именем функции и ее определением можно задать с помощью специального конструктора функций. Вместо конструктора LABEL, описанного в "Многоликое программирование" , в реальные системы программирования включают ряд средств с разными особенностями подготовки, реализации и применения определений функций. Common Lisp включает в себя конструктор функций DEFUN, первый аргумент которого - имя функции, второй - список аргументов функции, а третий - тело определения функции. Формальным результатом DEFUN является ее первый аргумент, который меняет свой статус - теперь это имя новой функции. Определение функции строится с помощью неявного LAMBDA-конструктора, объединяющего список аргументов функции и тело ее определения.

    Пример 7.1. Новая функция "третий".

    Определение функции Комментарии
    (DEFUN третий 
                (x) 
           (CAR (CDR (CDR x))) 
       )   
    ; Атом "третий" связан 
    ;с выражением " ( LAMBDA (x ) (CAR (CDR (CDR x ))) ) "
    имя новой функции 
    параметры функции
    тело функции

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

  4. Композиции функций можно строить с помощью вложенных скобок.
    (функция1 (функция2 аргумент21 аргумент22 ... )
                       аргумент2 ... )

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

  5. Если объект играет роль константы, то для объявления константы достаточно заблокировать его вычисление, как бы взять его в кавычки (quotation), отмечающие буквально используемые фразы, не требующие обработки. Для такой блокировки вводится специальная функция QUOTE, предохраняющая свой единственный аргумент от вычисления.

    (QUOTE (A B C) )    - константа  (A B C) объявлена

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

  6. Ветвление ( условное выражение ) обеспечивает специальная функция COND (condition), аргументами которой являются двухэлементные списки, содержащие предикаты и соответствующие им выражения. Аргументов может быть сколько угодно, а обрабатываются они по особой схеме: сначала вычисляются первые элементы аргументов по порядку, пока не найдется предикат со значением "истина". Затем выбирается второй элемент этого аргумента, и вычисляется его значение, которое и считается значением всего условного выражения.

    (COND (p1 e1) (p2 e2) ... (pk ek) )
              |   |_______|__________|_______ ветви условного выражения    
              |_______|___________|__________ предикаты для выбора ветви

    Каждый предикат pi или ветвь ei может быть любой формы: переменная, константа, вызов функции, композиция функций, условное выражение.

    Специальные функции QUOTE, COND, LAMBDA и DEFUN существенно отличаются от обычных функций CAR, CDR, CONS, ATOM, EQ правилом обработки аргументов. Обычно функции получают значения аргументов, предварительно вычисленные системой программирования по формулам фактических параметров функции. Специальные функции не требуют такой предварительной обработки параметров. Они сами могут выполнять все необходимое, используя представление фактических параметров в виде списков.

< Лекция 6 || Лекция 7: 1234 || Лекция 8 >
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Илья Ардов
Илья Ардов

Добрый день!

Я записан на программу. Куда высылать договор и диплом?