Часть полного текста документа:Функциональное программирование Н.Н.Непейвода, Интернет Университет Информационных Технологий, INTUIT.ru Функциональное программирование объясняется на примере диалекта Common Lisp языка LISP. Этот диалект наиболее распространен и имеет официальный стандарт. Common Lisp может работать не только в пакетном режиме (когда он запускается как обычная программа), но и в режиме диалога. LISP - вероятно, первый из практически реализованных языков1, который основывался на серьезном теоретическом фундаменте и пытался поднять практику программирования до уровня концепций, а не наоборот - опустить концепции до уровня существовавшей на момент создания языка практики. В настоящий момент функциональное программирование представлено целым семейством языков, но LISP свои позиции не сдает. ?-абстракции В некоторых случаях осознанное усвоение концепций даже на самом низком уровне нереально без базовых теоретических сведений. А знакомство с таким базисом, в свою очередь, стимулирует значительно более глубокий интерес к теории и способствует пониманию того, что на высшие уровни знаний и умений не подняться без овладения теорией. Теоретической основой языка LISP является логика функциональности: комбинаторная логика или (по наименованию одного из основных понятий в наиболее популярной из нынешних ее формализаций) ?-исчисление. В ?-исчислении выразительные средства, на первый взгляд, крайне скупы. Имеются две базисные операции: применение функции к аргументу (?x) и квантор образования функции по выражению ?x t[x]. В терминах ?-исчисления функция возведения числа в квадрат записывается как ?x (sqrx) или, если быть ближе к обычным математическим обозначениям, ?x x2. Основная операция - символьное вычисление применения функции к аргументу: (?x t[x] u) преобразуется в t[u]. Но эта операция может применяться в любом месте выражения, так что никакая конкретная дисциплина вычислений не фиксируется. Более того, функции могут вычисляться точно так же, как аргументы. Уже эта маленькая тонкость приводит к принципиальному расширению возможностей ?-исчисления по сравнению с обычными вызовами процедур. Если мы желаем ограничиться лишь ею, рассматривается типизированное ?-исчисление, в котором, как принято в большинстве современных систем программирования, значения строго разделены по типам. В типизированном ?-исчислении есть только типы функций, но этого хватает, поскольку функции могут принимать в качестве параметров и выдавать функции. Но в исходной своей форме ?-исчисление является нетипизированным, любой объект может быть и функцией, и аргументом, и, более того, функция может применяться к самой себе. Конечно же, при этом появляется возможность зацикливания, но без нее не обойдется ни одна алгоритмическая система. Например, выражение (?x (xx) ?x (xx)) вычисляется бесконечно, а чуть более сложное выражение ((?x ?y x a) (?x (xx) ?x (xx))) может либо дать a, либо зациклиться, в зависимости от выбора порядка его вычисления. Но все равно, если мы приходим к результату, то он определяется однозначно. Так что совместность вычислений не портит однозначности, если язык хорошо сконструирован. Дж. Маккарти перенес идеи ?-исчисления в программирование, не потеряв практически ничего из исходных концепций. ............ |