Функциональные языки программирования
Теоретические основы императивного программирования. История возникновения и основные свойства функциональных языков. Использование процедур, функций и подпрограмм в функциональных языках программирования. Применение языков запросов к базам данных.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | реферат |
Язык | русский |
Дата добавления | 15.04.2016 |
Размер файла | 142,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Министерство образования и науки Российской Федерации
Федеральное государственное автономное образовательное учреждение
высшего профессионального образования
«СЕВЕРО-КАВКАЗСКИЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»
филиал в г. Пятигорске.
РЕФЕРАТ
НА ТЕМУ: «ФУНКЦИОНАЛЬНЫЕ ЯЗЫКИ ПРОГРАММИРОВАНИЯ»
Выполнил(а): Сагиров М.Н.
Проверила: Битюцкая Н.И
Пятигорск 2015
Содержание
Введение
Основная часть
История возникновения функциональных языков
Свойства функциональных языков
Краткость и простота
Строгая типизация
Модульность
Чистота (отсутствие побочных эффектов)
Отложенные вычисления (Lazy evaluation)
Языки функционального программирования
Заключение
Список используемой литературы
Internet-ресурсы по функциональному программированию
Введение
Функциональное программирование ставит своей целью придать каждой программе простую математическую интерпретацию. Эта интерпретация должна быть независима от деталей исполнения и понятна людям, которые не имеют научной степени в предметной области. Архитектура языков программирования должна была быть максимально приближена к архитектуре компьютера. Компьютер состоит из центрального процессора и памяти. Поэтому программа должна была состоять из последовательности инструкций, выполняемых процессором и модифицирующих память. Функциональная программа представляет собой определения функций. Функции определяются через другие функции или рекурсивно - через себя. В процессе выполнения программы, функции получают параметры, вычисляют и возвращают результат, в случае необходимости вычисляя значения других функций. Почти каждый из нас так или иначе использовал функциональный подход к программированию. Возьмем к примеру, всем известный MicrosoftExcel. Записывая содержимое ячейки в виде, похожем на обычную математическую формулу, мы не задумываемся о действительном порядке вычислений этой формулы, возлагая эти функции на встроенный в Excel интерпретатор. А этот интерпретатор построен так, что правильный порядок вычисления этого выражения и, следовательно, правильный результат гарантированы. Как описывать вычисления на языке более близком человеку, чем компьютеру?". На этот вопрос призваны ответить универсальные функциональные языки программирования.
Цели исследования:
1. Просмотреть общее сведения и уровни функциональных языков программирования.
2. Просмотреть историю развития функциональных языков программирования.
3. Сделать обзор современных функциональных языков программирования.
Задачи исследования:
1. Ознакомления с языками функционального программирования.
2. Рассмотрение истории развития функциональных языков программирования.
3. Обзор современных функциональных языков программирования
Предметом исследования данной работы является изучение такого актуального вопроса, как использование процедур, функции и подпрограмм в функциональных языках программирования.
Объектом исследования послужили языки функционального программирования и история развития функциональных языков программирования.
Основная часть
Функциональное программирование ставит своей целью придать каждой программе простую математическую интерпретацию. Эта интерпретация должна быть независима от деталей исполнения и понятна людям, которые не имеют научной степени в предметной области. Паулсон, Лоренс В 40-х годах нашего века были построены первые цифровые компьютеры. Самые первые модели этих компьютеров 'программировались' на машинных языках, посредством соединения плат проводками вручную или, в лучшем случае, путем установки в нужное положение сотен переключателей. Машинные языки плохо воспринимаются человеком, поэтому следующим шагом стало создание различных ассемблеров. В ассемблере машинные команды получают компактные мнемокоды типа LOAD, STORE, ADD и т.п. В конце 50-х годов сотрудник IBM Джон Бэкус решил, что записывать Формулы вида о к тому же эти формулы могут быть выполнены на любой машине, для которой есть специальная программа, которую назвали компилятором. Первый компилятор был создан для языка FORTRAN (FORmulaTRANslator - Транслятор Формул). В те дни компьютеры были очень дороги. Поэтому создатели первых языков программирования высокого уровня в погоне за эффективностью пошли по наиболее простому пути. Архитектура языков программирования должна была быть максимально приближена к архитектуре компьютера. Компьютер состоит из центрального процессора и памяти. Поэтому программа должна была состоять из последовательности инструкций, выполняемых процессором и модифицирующих память. На основе этого принципа был разработан так называемый императивный стиль программирования. Основными признаками императивных языков программирования являются ориентированность, в первую очередь, на последовательное исполнение инструкций оперирующих с памятью (присваиваний) и итеративные циклы. Но не это главное. Со времен возникновения FORTRAN-а прошло почти 50 лет. За это время были разработаны сотни намного более развитых императивных языков, таких как Pascal, C++, Ada, Java и т.д. Значительно усовершенствованы механизмы и методы императивного программирования. Однако идея, лежащая в его основе, остается прежней. Программы на этих языках описывают процесс последовательного, пошагового решения задачи. Как следствие, полученные программы слабо напоминают оригинальную спецификацию задачи, которая, как правило, не содержат никаких упоминаний о различных массивах, указателях и счетчиках. На протяжении последних 400 лет, центральным понятием математики является понятие функции. Математические функции выражают связь между параметрами (входом) и результатом (выходом) некоторого процесса. Так как вычисление -- это тоже процесс, имеющий вход и выход, функция - вполне подходящее средство задания вычислений. Именно этот простой принцип положен в основу функционального стиля программирования. Функциональная программа представляет собой определения функций. Функции определяются через другие функции или рекурсивно - через себя. В процессе выполнения программы, функции получают параметры, вычисляют и возвращают результат, в случае необходимости вычисляя значения других функций. Программируя на функциональном языке, программист не должен описывать порядок вычислений. Ему необходимо просто описать желаемый результат в виде системы функций. Почти каждый из нас так или иначе использовал функциональный подход к программированию. Возьмем к примеру, всем известный MicrosoftExcel. Записывая содержимое ячейки в виде, похожем на обычную математическую формулу, мы не задумываемся о действительном порядке вычислений этой формулы, возлагая эти функции на встроенный в Excel интерпретатор. А этот интерпретатор построен так, что правильный порядок вычисления этого выражения и, следовательно, правильный результат гарантированы. Фактически, вся таблица представляет собой набор функций и констант (которые, в общем, тоже функции), определенных друг через друга.
Другим простым примером могут послужить языки запросов к базам данных. В большинстве своем эти языки используют один из двух подходов. В языках, основанных на реляционной алгебре, результат записывается в терминах операций над таблицами, демонстрируя тем самым явно императивный подход. Языки же, основанные на реляционном исчислении (например, всем известный SQL или QBE), напротив, описывают только результат, являясь тем самым по сути функциональными. По мере развития вычислительной техники, компьютерное время удешевляется, поэтому особую важность приобретает вопрос "Как описывать вычисления на языке более близком человеку, чем компьютеру?". На этот вопрос призваны ответить универсальные функциональные языки программирования, программы на которых гораздо больше напоминают изначальную спецификацию задачи чем программы, написанные с помощью императивных языков программирования.
История возникновения функциональных языков
язык программирование функциональный запрос
Теоретические основы императивного программирования были заложены в 30-х годах Аланом Тьюрингом и Джоном фон Нейманом. Теория положенная в основу функционального подхода, также родилась в 20-х - 30-х годах. В числе разработчиков математических основ функционального программирования можно назвать Мозеса Шёнфинкеля (Германия и Россия) и Хаскелла Карри (Англия), разработавших теорию комбинаторов, а также АлонзоЧёрча (США), создателя лямбда исчисления. Теория так и оставалась теорией, пока в начале 50-х Джон МакКарти не разработал язык Lisp, который стал первым почти функциональным языком программирования и на протяжении многих лет оставался единственным таковым. Хотя Lisp все еще используется (как и FORTRAN), он уже не удовлетворяет некоторым современным запросам, которые заставляют нас взваливать как можно большую ношу на компилятор, облегчив тем самым непосильный труд программиста. Необходимость в этом, конечно же, возникла из-за все возрастающей сложности программного обеспечения. В связи с этим обстоятельством все большую роль начинает играть типизация. В конце 70-х - начале 80-х интенсивно разрабатываются модели типизации, подходящие для функциональных языков. Большинство этих моделей включали в себя поддержку таких мощных механизмов как абстракция данных и полиморфизм. Появляется множество типизированных функциональных языков: ML, Scheme, Hope, Miranda, Clean и многие другие. Вдобавок постоянно увеличивается число диалектов. В результате вышло так, что практически каждая группа, занимающаяся функциональным программированием, использовала собственный язык. Это препятствовало дальнейшему распространению этих языков и порождало многочисленные более мелкие проблемы. Чтобы исправить ситуацию, объединенная группа ведущих исследователей в области функционального программирования решила воссоздать достоинства различных языков в новом универсальном функциональном языке. Первая реализация этого языка, названного Haskell в честь Хаскелла Карри, была создана в начале 90-х годов. В настоящее время действителен стандарт Haskell 98. Большинство примеров в этой статье будут приводиться именно на этом языке. В первую очередь большинство функциональных языков программирования реализуются как интерпретаторы, следуя традициям Lisp-а. Интерпретаторы удобны для быстрой отладки программ, исключая длительную фазу компиляции, тем самым укорачивая обычный цикл разработки. Однако с другой стороны, интерпретаторы в сравнении с компиляторами обычно проигрывают по скорости выполнения в несколько раз. Поэтому помимо интерпретаторов существуют и компиляторы, генерирующие неплохой машинный код (например, ObjectiveCaml) или код на C/C++ (например, GlasgowHaskellCompiler). Что показательно, практически каждый компилятор с функционального языка реализован на этом же самом языке.
Свойства функциональных языков
Краткость и простота
Программы на функциональных языках обычно намного короче и проще, чем те же самые программы на императивных языках. Как стандартный пример, рассмотрим алгоритм быстрой сортировки Хоара. На C этот алгоритм описывается примерно так:
voidqsort (int a[], int l, int r)
{
int i = l, j = r, x = a[(l + r) / 2];
do
{
while (a[i] < x) i++;
while (x < a[j]) j--;
if (i<= j)
{
int temp = a[i];
a[i++] = a[j];
a[j--] = temp;
}
}
while (i<= j);
if (l < j) qsort (a, l, j);
if (i< r) qsort (a, i, r);
}
Сравним этот код с кодом на Haskell:
qsort:: (Ord a) => [a] -> [a]
-- если список пустой, то сортировать его не нужно...
qsort [] = []
--...иначе разобьем его на голову - x и хвост - xs
qsort (x:xs) =
-- конкатенация отсортированного списка элементов хвоста меньших или равных x...
qsort [n | n <- xs, n <= x] ++
--...и списка элементов хвоста больших x
qsort [n | n <- xs, n > x]
Что может быть проще
Кроме того, все операции с памятью выполняются автоматически. При создании объекта для него автоматически выделяется память. После того как объект выполнит свои функции, он вскоре будет также автоматически уничтожен сборщиком мусора, который является частью любого функционального языка. Еще одним полезным свойством, позволяющим сократить программу, является встроенный механизм сопоставления с образцом. Это позволяет описывать функции как индуктивные определения. Например:
-- Функция, возвращающая n-е число Фибоначчи
fib:: Int ->Int
fib 0 = 1
fib 1 = 1
fib n = fib (n - 2) + fib (n - 1)
или
-- Функция, возвращающая число n в целой степени m
pow:: Int ->Int ->Int
pow n 0 = 1
pow n m | even m = pow (n * n) (m `div` 2)
| otherwise = n * pow n (m - 1)
Строгая типизация
Практически все современные языки функционального программирования являются строго типизированными языками. Строгая типизация обеспечивает безопасность. Программа, прошедшая проверку типов просто не может выпасть в OS с сообщением подобным "segmentationviolation". Большая часть ошибок может быть исправлена на стадии компиляции, поэтому стадия отладки и общее время разработки программ сокращаются. Вдобавок к этому строгая типизация позволяет компилятору генерировать более эффективный код и тем самым ускорять выполнение программ. Вернемся к примеру, с быстрой сортировкой Хоара. Помимо уже упомянутых отличий между вариантом на языке C и вариантом на Haskell есть еще одно важное отличие: функция на C сортирует список значений типа int (целых чисел), а функция на Haskell - список значений любого типа, который принадлежит к классу упорядоченных величин Ord. Поэтому функция на Haskell может сортировать и список целых чисел, и список чисел с плавающей запятой, и список строк. Мы можем описать какой-нибудь новый тип. Определив для этого типа операции сравнения и cделав его тем самым экземпляром класса Ord, мы без перекомпиляции сможем использовать qsort и со списками этого нового типа. Это полезное свойство системы типов называется параметрическим или истинным полиморфизмом, и поддерживается большинством функциональных языков.
Еще одной разновидностью полиморфизма является перегрузка операций (overloading), позволяющая давать различным, но в чем-то схожим функциям одинаковые имена. Типичным примером перегруженной операции является обычная операция сложения. Функции сложения для целых чисел и чисел с плавающей запятой различны, однако для удобства они носят одно и то же имя. Некоторые функциональные языки, например, все тот же Haskell, помимо параметрического полиморфизма, поддерживают и перегрузку операций.
Программист, знакомый с C++, может возразить: "Да, все это хорошо, но я могу легко определить такую же полиморфную функцию qsort и на C++, воспользовавшись механизмом шаблонов". Да, это так. В стандартную библиотеку C++ STL входит такая функция и множество других полиморфных функций. Но шаблоны C++, как и родовые функции Ada, на самом деле порождают множество перегруженных функций, которые, кстати, компилятор должен каждый раз компилировать, что неблагоприятно сказывается на времени компиляции и размере кода. А в Haskell полиморфная функция qsort это одна функция.
В некоторых языках, например, в Ada, строгая типизация вынуждает программиста явно описывать тип всех значений и функций. Чтобы избежать этого, в строго типизированные функциональные языки встроен специальный механизм, позволяющий компилятору определять типы констант, выражений и функций из контекста. Этот механизм называется механизмом вывода типов (typeinference). Известно несколько таких механизмов, однако большинство из них являются разновидностями модели типизации Хиндли-Милнера, разработанной в начале 80-х. Таким образом в большинстве случаев можно не указывать типы функций. Однако в примерах, приводимых в этой статье, типы функций указаны явно. Это позволяет компилятору дополнительно контролировать корректность типов определяемых функций.
Модульность
Механизм модульности позволяет разделять программы на несколько сравнительно независимых частей (модулей) с четко определенными связями между ними. Тем самым облегчается процесс проектирования и последующей поддержки больших программных систем. Поддержка модульности не является свойством именно функциональных языков программирования. Существуют очень развитые модульные императивные языки. В качестве примеров подобных языков можно привести Modula-2 и Ada-95. В этой статье, однако, речь идет о языках функционального программирования. Поэтому для примера рассмотрим систему модулей функционального языка Standard ML. Standard ML - строго типизированный язык, это накладывает свой отпечаток и на систему модулей. Поэтому каждый модуль (в терминах языка - структура) имеет тип (сигнатуру). Сигнатура определяет часть структуры доступную извне. Именно так в Standard ML реализуется механизм абстракции данных. По аналогии с соответствиями сигнатура = тип и структура = значение, должно быть определено и какое-нибудь соответствие понятию функции. В самом деле, в Standard ML существует возможность определять функции над структурами. Такие функции называются функторами, по аналогии с термином из общей алгебры. Функторы позволяют преобразовывать структуры, соответствующие одной сигнатуре, в структуры, соответствующие другой, тем самым одновременно являя собой механизм реализующий наследование и параметрический полиморфизм на уровне целых модулей. Standard ML является одним из немногих функциональных языков с такой интересной системой модулей. В Haskell, например, реализована намного более простая система, сходная с системой модулей в языке Modula-2.Функции - это значенияв функциональных языках функции могут быть переданы другим функциям в качестве аргумента или возвращены в качестве результата. Функции, принимающие функциональные аргументы, называются функциями высших порядков или функционалами. Самый, пожалуй, известный функционал, это map. map применяет некоторуюфункцию ко всем элементам списка, формируя из результатов другой список. Например, определив функцию возведения целого числа в квадрат как:
square::Int ->Int
square n = n * n
мы можем воспользоваться этой функцией для возведения в квадрат всех элементов списка
l2 = mapsquare [1, 2, 3, 4] -- результат - список [1, 4, 9, 16]
Каждый тип имеет литералы, например, тип Boolean имеет литералы True и False, а тип Char имеет 256 литералов, представляющих ASCII символы. Функциональный тип также имеет свои литералы, которые являются ничем иным, как безымянными функциями. Функциональные литералы называются лямбда-абстракциями (это название появилось из лямбда-исчисления Чёрча) или просто лямбдами. Например, для получения списка кубов можно воспользоваться записью
l3 = map (\x -> x * x * x) [1, 2, 3, 4] -- результат - список [1, 8, 27, 64]
Функции, возвращающие другие функции, кажутся на первый взгляд несколько более специфичными. В самом деле, куда это можно применять? В функциональных языках они применяются повсеместно. Для примера определим два варианта функции сложения:
sum1:: (Int, Int) ->Int
sum1 (n, m) = n + m
sum2:: Int ->Int ->Int
sum2 n m = n + m
Вопреки первому впечатлению функция sum1 принимает всего один аргумент - пару чисел, и возвращает результат - их сумму. Функция sum2 (эквивалентная стандартному оператору (+)) - пример частично вычисляемой функции. Эта функция принимает в качестве аргумента число (типа Int) и возвращает функцию прибавляющую это число к своему аргументу. Зачем это нужно? Функция sum2 позволяет легко определять свои частные случаи. Например - функция инкремент, увеличивающая свой аргумент на 1 определяется как частный случай sum2 следующим образом:
inc:: Int ->Int
inc = sum2 1
Функция map - тоже пример частично-вычисляемой функции. Эта функция принимает в качестве аргумента функцию и возвращает функцию принимающую список и возвращающую другой список. Это легко понять если взглянуть на пример:
-- sins принимает список действительных чисел (типа Double)
-- и возвращает список их синусов
sins:: [Double] -> [Double]
sins = mapsin
Чистота (отсутствие побочных эффектов)
В императивных языках функция в процессе своего выполнения может читать и модифицировать значения глобальных переменных и осуществлять ввод/вывод. Поэтому, если мы вызовем одну и ту же функцию дважды с одним и тем же аргументом, может случиться так, что мы получим два различных результата. Такая функция называется функцией с побочными эффектами. Описывать функции без побочных эффектов позволяет практически любой язык. Однако некоторые языки поощряют или даже требуют от функции побочных эффектов. Например, во многих объектно-ориентированных языках в функцию передается скрытый параметр (чаще он называется this или self), который функция неявно модифицирует.
В чистом функциональном программировании оператор присваивания отсутствует, объекты нельзя изменять и уничтожать, можно только создавать новые путем декомпозиции и синтеза существующих. О ненужных объектах позаботится встроенный в язык сборщик мусора. Благодаря этому в чистых функциональных языках все функции свободны от побочных эффектов. Однако это не мешает этим языкам имитировать некоторые полезные императивные свойства, такие как исключения и изменяемые массивы. Для этого существуют специальные методы. Каковы же преимущества чистых функциональных языков? Помимо упрощения анализа программ есть еще одно весомое преимущество - параллелизм. Раз все функции для вычислений используют только свои параметры, мы можем вычислять независимые функции в произвольном порядке или, скажем, параллельно, на результат вычислений это не повлияет. Причем параллелизм этот может быть организован не только на уровне компилятора с языка, но и на уровне архитектуры. В нескольких университетах уже разработаны и используются экспериментальные компьютеры, основанные на подобных архитектурах.Далеко не все функциональные языки являются чистыми. В некоторых случаях побочные эффекты намного упрощают программирование. Однако преимущества чистых языков постепенно перевешивают, и наиболее современные функциональные языки являются, как правило, чистыми.
Отложенные вычисления (Lazyevaluation)
В традиционных языках программирования (например, C++) вызов функции приводит к вычислению всех аргументов. Этот метод вызова функции называется вызов-по-значению (call-by-value). Если какой-либо аргумент не использовался в функции, то результат вычислений пропадает, следовательно, вычисления были произведены впустую. В каком-то смысле противоположностью вызова-по-значению является вызов-по-необходимости (call-by-need). В этом случае аргумент вычисляется, только если он нужен для вычисления результата. Предположим, что мы хотим определить оператор конъюнкции (логическое и). На C мы можем прибегнуть к следующему определению (намеренно не используя оператор&&):
int and (int x, int y) { if (x) return y; else return 0; }
Мы не сможем пользоваться этим оператором также как предопределенным оператором, потому что даже если x == FALSE, y все равно будет вычислен перед вызовом функции, так что простой оператор
if (and (y != 0.0, 1.0 / y > 2.0)) printf ("y = %g\n", y);
в случае если y окажется равным 0.0 произойдет деление на 0, а это совсем не то, что нам нужно.Если же мы определим подобную функцию на Haskell (который поддерживает отложенные вычисления), то все будет работать как должно:
-- возвращает True, если оба аргумента истинны
and:: Bool -> Bool -> Bool
and x y = cond (x, y, False)
cond:: Bool -> a -> a
cond True result _ = result
condFalse _ result = result
обратите внимание на функцию cond, которая представляет собой не что иное как аналог конструкции if-then-else в традиционных языках программирования. В языках, использующих вызов-по-значению определить такую функцию невозможно, т.к. вне зависимости от логического условия будут вычислены оба других аргумента, хотя в каждом случае вычислять нужно только один.Одним из самых полезных свойств отложенного вычисления является, пожалуй, возможность определения потенциально бесконечных структур данных, чаще всего - списков (lazylists). Например, Haskell позволяет очень просто определить список всех простых чисел.
-- возвращает список делителей аргумента
divisors:: Int -> [Int]
divisors n = [m | m <- [1.. n], n `mod` m == 0]
-- предикат, возвращает True, если аргумент - простое число
-- число является простым, если оно делится только на 1 и на себя
isPrime:: Int -> Bool
isPrime n = (divisors n) == [1, n]
-- возвращает список всех простых чисел, получая его фильтрацией
-- множества натуральных чисел предикатом isPrime
primes:: [Int]
primes = filter isPrime [1..]
Разумеется, это далеко не самый быстрый способ вычисления простых чисел, однако один из самых простых. Если функциональный язык не поддерживает отложенные вычисления, то он называется строгим (strict). В самом деле, в таких языках порядок вычисления строго определен. В качестве примера строгих языков можно привести Scheme, Standard ML и Caml. Языки использующие отложенные вычисления называются нестрогими (non-strict или lazy). Haskell - нестрогий язык, так же как, например, Gofer и Miranda. Нестрогие языки зачастую являются чистыми. Зачастую строгие языки включают в себя средства поддержки некоторых полезных элементов, присущих нестрогим языкам, например, бесконечных списков. В поставке Standard ML присутствует специальный модуль для поддержки отложенных вычислений. А ObjectiveCaml помимо этого поддерживает дополнительное зарезервированное слово lazy и конструкцию для списков значений, вычисляемых по необходимости.
Языки функционального программирования
В этом разделе приведено краткое описание некоторых языков функционального программирования (очень немногих). Дополнительную информацию можно почерпнуть, просмотрев сайты, перечисленные в следующем разделе.
ѕ Lisp (Listprocessor). Считается первым функциональным языком программирования. Нетипизирован. Содержит массу императивных свойств, однако в общем поощряет именно функциональный стиль программирования. При вычислениях использует вызов по значению. Существует объектно-ориентированный диалект языка - CLOS.
ѕ ISWIM (If you See What I Mean). Функциональный язык-прототип. Разработан Ландиным в 60-х годах для демонстрации того каким может быть язык функционального программирования. Вместе с языком Ландин разработал и специальную виртуальную машину для исполнения программ на ISWIM-е. Эта виртуальная машина, основанная на вызове-по-значению, получила название SECD-машины. На синтаксисе языка ISWIM базируется синтаксис многих функциональных языков. На синтаксис ISWIM похож синтаксис ML, особенно Caml.
ѕ Scheme. Диалект, Lisp-а, предназначенный для научных исследований в области компьютерной науки. При разработке Scheme был сделан упор на элегантность и простоту языка. Благодаря этому язык получился намного меньше, чем CommonLisp.
ѕ ML (MetaLanguage). Семейство строгих языков с развитой полиморфной системой типов и параметризуемыми модулями. ML преподается во многих западных университетах (в некоторых даже как первый язык программирования).
ѕ Standard ML. Один из первых типизированных языков функционального программирования. Содержит некоторые императивные свойства, такие как ссылки на изменяемые значения и поэтому не является чистым. При вычислениях использует вызов-по-значению. Очень интересная реализация модульности. Мощная полиморфная система типов. Последний стандарт языка - Standard ML-97, существует формальное математическое определения синтаксиса, статической и динамической семантик языка.
ѕ Caml Light и Objective Caml. Как и Standard ML принадлежит к семейству ML. ObjectiveCaml отличается от CamlLight в основном поддержкой классического объектно-ориентированного программирования. Также, как и Standard ML строгий, но имеет некоторую встроенную поддержку отложенных вычислений.
ѕ Miranda. Разработан Дэвидом Тернером, в качестве стандартного функционального языка, использовавшего отложенные вычисления. Имеет строгую полиморфную систему типов. Как и ML преподавается во многих университетах. Оказал большое влияние на разработчиков языка Haskell.
ѕ Haskell. Один из самых распространенных нестрогих языков. Имеет очень развитую систему типизации. Несколько хуже (на мой взгляд) разработана система модулей. Последний стандарт языка - Haskell 98.
ѕ Gofer (GOodFor Equational Reasoning). Упрощенный диалект Haskell. Предназначен для обучения функциональному программированию.
ѕ Clean. Специально предназначен для параллельного и распределенного программирования. По синтаксису напоминает Haskell. Чистый. Использует отложенные вычисления. С компилятором поставляется набор библиотек (I/O libraries), позволяющие программировать графический пользовательский интерфейс под Win32 или MacOS.
Заключение
В качестве заключения хотелось бы написать, что для примера чистого функционального языка можно привести Haskell. Однако большинство функциональных языков являются гибридными и содержат свойства как функциональных, так и императивных языков. Яркие примеры -- языки Scala и Nemerle. В них органично сочетаются характеристики как объектно-ориентированных языков, так и функциональных. Реализована хвостовая рекурсия и её оптимизация, функция является полноправным объектом, то есть может быть сохранена в переменной, передана в качестве аргумента в другую функцию или возвращена из функции.
Также функциональные языки делят на строгие и нестрогие. К нестрогим языкам относят те, которые поддерживают отложенные вычисления (F#), то есть аргументы функции вычисляются только тогда, когда они действительно понадобятся при вычислении функции. Ярким примером нестрогого языка является Haskell. В качестве примера строгого языка можно привести Standard ML.
Некоторые функциональные языки реализованы поверх платформообразующих виртуальных машин (JVM,.NET), то есть приложения на этих языках могут работать в среде времени исполнения (JRE, CLR) и использовать встроенные классы. К ним относятся Scala, Clojure (JVM), F#, Nemerle, SML.NET (.NET).
Список используемой литературы
1. В.Э. Фигурнов. Изд. 6, М., "Инфра-М", 2001.
2. К.С. Ахметов. История возникновения функциональных языков 2000 год.
3. А.Е. Борзенко. "Компьютер-пресс", 1999.
4. В. Денисов. Чистые функции С-Пб, "Питер", 1998.
5. Н. Николь, Р. Альбрехт.. М., "Эком", 1997.
6. В.В. Фаронов. ФП в нефункциональных языках
Кн.1, М., МВТУ, 1998.
7. А. Гончаров. Свойства функциональных языков
"Питер", С-Пб, 2002.
8. http://www.haskell.org - очень насыщенный сайт, посвященный функциональному программированию в общем и языку Haskell в частности. Содержит различные туториалы, список интерпретаторов и компиляторов, Haskell-а (в настоящий момент все интерпретаторы и компиляторы - freeware). Кроме того, имеется обширный список интересных ссылок на ресурсы по теории функционального программирования и другим языкам (Standard ML, Clean). Очень рекомендую.
ѕ http://cm.bell-labs.com/cm/cs/what/smlnj - Standard ML of New Jersey. Очень хороший компилятор. В бесплатный дистрибутив помимо компилятора входят утилиты MLYacc и MLLex и библиотека Standard ML BasisLibrary. Отдельно можно взять документацию по компилятору и библиотеке.
ѕ http://www.harlequin.com/products/ads/ml/ - HarlequinMLWorks, коммерческий компилятор Standard ML. Однако в некоммерческих целях можно бесплатно пользоваться версией с несколько ограниченными возможностями.
ѕ http://caml.inria.fr - институт INRIA. Домашний сайт команды разработчиков языков CamlLight и ObjectiveCaml. Можно бесплатно скачать дистрибутив ObjectiveCaml, содержащий интерпретатор, компиляторы байт-кода и машинного кода, Yacc и Lex для Caml, отладчик и профайлер, документацию, примеры. Качество компилированного кода у этого компилятора очень хорошее, по скорости опережает даже Standard ML ofNewJersey.
Размещено на Allbest.ru
Подобные документы
Характеристика языков программирования: краткая история, хронология. Основные виды языков программирования: ассемблер; бейсик. Создание и использование формул в Excel. Применение операторов в формулах. Использование функций в Excel. Сайт дома отдыха.
отчет по практике [139,1 K], добавлен 03.06.2011Классификация языков программирования. Использование циклических конструкций и выполнение итерационных процессов. Алгоритмические структуры циклов языков C, C++, Java, C#. Особенности современных языков программирования высокого уровня и их применение.
курсовая работа [345,6 K], добавлен 13.11.2009Сравнительный анализ наиболее распространенных языков, их классификация, описание достоинств и недостатков. Использование процедур, функции и подпрограмм в языках программирования высокого уровня. Разработка и реализация программы "Бортовой компьютер".
курсовая работа [329,8 K], добавлен 22.06.2014Основные сведения о языках программирования и их состав. Программа для компьютера. Использование компилятора и операторы. Языки программирования высокого уровня. Концепции объектно-ориентированного программирования. Языки искусственного интеллекта.
презентация [6,3 M], добавлен 14.08.2013Сущность и функции языков программирования, их эволюция и оценка популярности различных видов. Особенности компьютерных программ, разработанных на компилируемом, интерпретируемом или смешанном языке. Основные классы и иерархия языков программирования.
презентация [873,4 K], добавлен 23.01.2013Основные концепции языков программирования, механизмы типизации данных. Описание языков программирования и методов трансляции. Конечные автоматы и преобразователи. Общие методы синтаксического анализа. Формальные методы описания языкового перевода.
курс лекций [5,5 M], добавлен 04.12.2013История развития и классификация высокоуровневых языков логического программирования. Определение понятий графического интерфейса, сетевых протоколов и моделей баз данных. Современные системы программирования компании Borland/Inprise и фирмы Microsoft.
курсовая работа [72,3 K], добавлен 11.07.2011Эволюция языков программирования от низкого уровня до современности. Языки программирования второго поколения - ассемблер. Императивные, функциональные, логические и объектно-ориентированные языки. Машинная независимость. Парадигмы программирования.
презентация [353,5 K], добавлен 14.10.2013Использование языков программирования, работающих на стороне клиента. Теговые языки логической разметки документов. Скриптовые языки программирования. Работоспособность клиентских технологий. Функциональные интерактивные сайты и сроки их разработки.
лабораторная работа [2,1 M], добавлен 27.04.2009Характеристика базовых конструкций языков программирования. Изучение истории их развития и классификации. Определение основных понятий языков программирования. Описание основных операторов, которые используются в языках программирования высокого уровня.
курсовая работа [400,6 K], добавлен 10.11.2016