Тотальное функциональное программирование (также известное как сильное функциональное программирование , [1] в отличие от обычного или слабого функционального программирования ) — это парадигма программирования , которая ограничивает диапазон программ теми, которые доказуемо завершаются . [2]
Прекращение действия гарантируется следующими ограничениями:
Эти ограничения означают, что полное функциональное программирование не является полным по Тьюрингу . Однако набор алгоритмов, которые можно использовать, по-прежнему огромен. Например, любой алгоритм, для которого можно вычислить асимптотическую верхнюю границу (с помощью программы, которая сама использует только рекурсию Вальтера), можно тривиально преобразовать в доказуемо завершающую функцию, используя верхнюю границу в качестве дополнительного аргумента, уменьшаемого на каждую итерацию или рекурсию. .
Например, быстрая сортировка не является тривиально субструктурно-рекурсивной, но она рекурсивна только до максимальной глубины длины вектора (временная сложность в худшем случае O ( n 2 )). Реализация быстрой сортировки списков (которая будет отклонена субструктурной рекурсивной проверкой) с использованием Haskell :
импортировать Data.List ( раздел ) qsort [] = [] qsort [ a ] = [ a ] qsort ( a : as ) = let ( меньше , больше ) = раздел ( < a ) как в qsort lesser ++ [ a ] ++ qsort больше
Чтобы сделать его субструктурно-рекурсивным, используя длину вектора в качестве ограничения, мы могли бы сделать:
импортировать Data.List ( раздел ) qsort x = qsortSub x x — минимальный регистр qsortSub [] as = as — показывает завершение — стандартные случаи qsort qsortSub ( l : ls ) [] = [] — нерекурсивный, поэтому принимается qsortSub ( l : ls ) [ a ] = [ a ] — нерекурсивно, поэтому принято qsortSub ( l : ls ) ( a : as ) = let ( lesser , Greater ) = раздел ( < a ) as — рекурсивно, но рекурсивно по ls, которая является подструктурой -- его первый ввод. в qsortSub ls lesser ++ [ a ] ++ qsortSub ls больше
Некоторые классы алгоритмов не имеют теоретической верхней границы, но имеют практическую верхнюю границу (например, некоторые эвристические алгоритмы могут быть запрограммированы так, чтобы «сдаваться» после такого большого количества рекурсий, что также обеспечивает завершение).
Другим результатом тотального функционального программирования является то, что и строгая оценка , и ленивая оценка , в принципе, приводят к одному и тому же поведению; однако тот или иной вариант все же может быть предпочтительнее (или даже необходим) по соображениям производительности. [4]
В тотальном функциональном программировании различают данные и кодаты : первые являются финитными , а вторые потенциально бесконечны. Такие потенциально бесконечные структуры данных используются для таких приложений, как ввод-вывод . Использование кодатов влечет за собой использование таких операций, как corecursion . Однако можно выполнять ввод-вывод на функциональном языке программирования (с зависимыми типами ) и без кодовых данных. [5]
И Epigram , и Charity можно считать полностью функциональными языками программирования, хотя они и не работают так, как указывает Тернер в своей статье. То же самое можно сделать и с программированием непосредственно в простой системе F , в теории типов Мартина-Лёфа или в исчислении конструкций .