FP
- Дата создания:
- 1977
- Повлиял на:
- Парадигма:
- Типизация:
- Принятые расширения файлов:
- .fp
- Реализации и версии (свернуть все | развернуть все):
FP (“Functional Programming”) — алгебраический язык программирования.
FP был изобретен Джоном Бэкусом (John Backus) и опубликован в 1977 году в статье под названием “Can Programming Be Liberated from the von Neumann style? A Functional Style and its Algebra of Programs” (“Возможно ли освободить программирование от стиля фон Неймана? Алгебра программ в функциональном стиле”) . Описание языка, данное в статье, является фактическим стандартом, и дальнейшей стандартизации FP не подвергался.
FP был придуман как модель языка, поддерживающего стиль программирования на уровне функций. Он был задуман скорее как математическая модель, чем как действующий язык, и таким и остался. FP является каноническим примеров языка, использующего парадигму программирования на уровне функций в качестве основной парадигмы, но имеет всего несколько любительских реализаций (достаточно сильно различающихся между собой), и не используется при разработке реальных программных комплексов. Тем не менее, концепции, воплощенные в FP, сильно повлияли на создание других функциональных языков.
(Следующее описание использует синтаксис языка приведенной по ссылке реализации.)
Как и любой язык программирования, реализующий парадигму программирования на уровне функций, FP состоит из трех групп сущностей:
1. атомы
. FP использует следующие типы атомов:
- скалярные значения. FP работает с числовыми (целыми и с плавающей точкой) и логическими (константами, обозначенными T и F) данными. Некоторые реализации, например, Furry Paws, расширяют язык, включая в него возможности обработки строк как последовательностей кодов символов.
-
последовательности. Последовательность определяется как
<x1, ..., xn>
, где xi — другие атомы. Следует отметить, что в одной последовательности могут объединяться атомы разных типов; так,<1 <2 5.0> T>
— законная последовательность. - значение “неопределенность”. То же значение, которое используется в определении строгой и нестрогой парадигм: атом, не имеющий определенного значения, либо еще не вычисленный, либо вычисленный с ошибкой. FP — строгий язык: если аргумент функции или элемент последовательности не определен, то результат вычисления функции или сама последовательность также не определены.
Как и любой язык, действующий на уровне функций, FP позволяет использовать атомы только в качестве входных и выходных значений программы. Если логика программы содержит константу, используется соответствующая функция-константа.
2. функции
могут быть элементарными или определенными программистом. В языке FP функции всегда принимают в качестве аргумента ровно один атом, что записывается как f:x
. Элементарные функции FP включают следующие:
-
тождество:
id:x
возвращаетx
. -
константа:
%x:y
возвращаетx
для любого значенияy
(некоторые авторы рассматривают % как функциональную форму, но эта операция не принимает функцию в качестве аргумента). -
математические +,-,*,/:
+:<x y>
возвращаетx+y
, если x и y — скалярные значения. -
выборочная функция (селектор):
i:<x1 ... xn>
возвращаетxi
, если 1 <= i <= n. -
сравнения =,>,<:
=:<x y>
возвращает T, если x=y, и F в противном случае. - ряд векторных и матричных функций: конкатенация, присоединение в начало/конец, циклическая перестановка, транспонирование и т.д.
-
определение функции программистом имеет следующий синтаксис:
{ functionName ( function code ) }
. После определения функция вызывается так же, как элементарные функции.
FP — безопасный с точки зрения типов язык: функция вычисляется только в том случае, если ее аргумент правильного типа.
3. функциональные формы
не могут определяться программистом, т.е. используются только формы, встроенные в язык. В отличие от функций, функциональные формы могут принимать несколько аргументов. Список стандартных форм FP включает в себя следующие:
-
составление:
[f1, ..., fn]:x
эквивалентно<f1:x ... fn:x>
. -
композиция:
f @ g:x
эквивалентноf:(g:x)
. -
условный выбор записывается как
( condition -> trueChoice ; falseChoice )
и применяется к атому x по следующему правилу: сначала вычисляется функцияcondition:x
; если ее результат — T, возвращаетсяtrueChoice:x
, иначе —falseChoice:x
. Все три аргумента условного выбора — функции. -
применить-ко-всем:
@f:<x1 ... xn>
эквивалентно<f:x1 ... f:xn>
. -
правая вставка:
!f:<x1 x2 ... xn>
эквивалентноf:<x1 !f:<x2 ... xn>>
(и применяется рекурсивно);!f:<x>
эквивалентноx
(левая вставка вычисляется аналогично).
Ссылки:
Примеры:
Факториал:
Пример для версий Interactive FPЭтот пример определяет четыре функции — две по необходимости, и две для читабельности. Все они принимают на вход скалярные значения; seq
возвращает последовательность скаляров, остальные три — скаляры.
-
zero
проверяет, равен ли ее аргумент нулю; -
dec
уменьшает аргумент на единицу; -
seq
возвращает<0>
, если ее аргументx
равен нулю, и результат примененияseq
к(x-1)
с присоединенным справаx
иначе (если мы развернем это рекурсивное определение, мы получим просто последовательность<0 1 … x>
) . -
factorial
возвращает 1, если ее аргументx
равен нулю, и результат примененияfactorial
к(x-1)
, умноженный наx
, иначе.
Последняя строка примера применяет factorial
к каждому элементу последовательности, полученной применением seq
к входному параметру — 16. Следует отметить, что все матеметические операции возвращают числа с плавающей запятой, поэтому результат выполнения программы будет иметь следующий вид:
< 1 1.0 2.0 6.0 24.0 120.0 720.0 5040.0 40320.0 362880.0 3628800.0 3.99168E7 4.790016E8 6.2270208E9 8.7178289E10 1.30767428E12 2.09227885E13 >
{ zero ( = @ [id, %0] ) }
{ dec ( - @ [id, %1] ) }
{ seq ( zero -> %<0> ; apndr @ [ seq @ dec , id ] ) }
{ factorial ( zero -> %1 ; * @ [id, factorial @ dec ] ) }
&factorial @ seq:16
Числа Фибоначчи:
Пример для версий Interactive FPЭтот пример работает так же, как пример факториала, но без добавления функций для читабельности.
{ seq ( = @ [id, %1] -> %<1> ; concat @ [ seq @ - @ [id, %1] , [id] ] ) }
{ fibonacci ( < @ [id, %3] -> %1 ; + @ [ fibonacci @ - @ [id, %1], fibonacci @ - @ [id, %2] ] ) }
&fibonacci @ seq:16
Hello, World!:
Пример для версий Furry Paws~x
— функция-константа (обозначенная как % в Interactive FP). emit
— стандартная функция, выводящая свой аргумент в стандартный поток вывода. main
— функция, наличие которой в программах на Furry Paws обязательно, т.к. при выполнении программы она вызывается первой.
main = emit.(return ~"Hello, World!\n")
Факториал:
Пример для версий Furry PawsЭтот пример работает точно так же, как пример для Interactive FP, за исключением отсутствия определения функции zero
, являющейся встроенной. Следует отметить, что здесь все операции выполняются в пределах стандартного целочисленного типа, и 13! вызывает ошибку переполнения, поэтому программа может быть вызвана только для факториалов до 12!. show
— альтернативный способ вывода информации.
dec = sub.[id, ~1]
seq = zero -> [id] ; cat.[seq.dec, [id]]
factorial = zero -> ~1 ; mul.[id, factorial.dec]
main = show.(return @factorial.(seq.~12))
Числа Фибоначчи:
Пример для версий Furry Pawsone = eq.[id, ~1]
dec = sub.[id, ~1]
seq = one -> [~1] ; cat.[seq.dec, [id]]
fibonacci = lt.[id, ~3] -> ~1 ; add.[fibonacci.sub.[id, ~1], fibonacci.sub.[id, ~2]]
main = show.(return @fibonacci.(seq.~16))
Комментарии
]]>blog comments powered by Disqus
]]>