В компютърните науки функционално програмиране е парадигма за програмиране – стил за изграждането на структурата и елементите на компютърни програми, който третира като изчислява оценката на математически функции и избягва променящите състоянието непостоянни данни. Това е декларативна парадигма за програмиране, което означава, че програмирането се извършва с изрази. Във функционален код, изходната стойност на функция зависи само от аргументите, които са вложени по време на функцията, така призованата функция е два пъти с една и съща стойност за един аргумент Х и тя ще произведе същия резултат (Х) всеки път. Премахване на нежелани реакции, т.е. промени в състоянието, което не зависи от входовете на функцията, може да направи много по-лесно разбирането и да се предскаже поведението на една програма, което е един от основните мотиви за развитието на функционално програмиране.

Функционално програмиране има своите корени в ламбда-смятането, което е официална система, разработена през 1930 г., за да разследва изчислимост на дефиниция на функция, приложение функция и рекурсия. Много функционални езици за програмиране могат да бъдат разглеждани като изградени върху ламбда-смятането. Друга добре позната декларативна парадигма за програмиране е логическото програмиране което, се основава на релацията.

За разлика, императивното програмиране променя състоянието, чрез команди в началния език, най-прост пример за това е задачата. Императивното програмиране наистина има функции, не в математическия смисъл, а в смисъл на подпрограми. Те могат да имат странични ефекти, които могат да променят стойността на програмата. Функции без стойности за връщане могат да доведат до това. Поради това, че те нямат референтна прозрачност, т.е. същия израз в друг език може да доведе до различни стойности по различно време в зависимост от състоянието на изпълняващата програмата.

Функционални програмни езици, особено изцяло функционални такива като Hope и Rex, са използвани повече в академичните среди, отколкото в развитието на търговски софтуер. Въпреки това, видни функционални езици за програмиране като Common Lisp, Scheme, Clojure, Language Wolfram Language, Racket, Erlang, OCaml, Haskell, и F# са били използвани в промишлени и търговски заявления от голямо разнообразие от организации. Функционално програмиране се подкрепя и в някои специфични програмни езици за домейн като R, J, K и (programming language from Kx Systems) Q от Kx Systems (финансов анализ), XQuery / XSLT (XML), и Opal. Широко разпространени специфични програмни езици за домейн като SQL и Lex / Yacc използват някои елементи на функционалното програмиране.

Програмиране на функционален стил може да се осъществи в езици, които не са специално предназначени за функционално програмиране. Например, императивния Perl език за програмиране е бил обект на една книга, описваща как да се прилагат концепции на функционалното програмиране. Това е вярно и за езика PHP. C # 3.0 и Java 8 добавят конструкции за улесняване на функционалния стил. Езикът Julia също предлага функционални възможности за програмиране. Интересен случай е този на Scala – често се пише във функционален стил, но присъствието на странични ефекти и непостоянни състояния го провежда в сивата зона между императивни и функционални езици.

История Ламбда-смятането осигурява теоретична рамка за описване на функции и тяхната оценка. Въпреки че е по-скоро математическа абстракция, отколкото език за програмиране, то е в основата на почти всички функционални програмни езици днес. Една равностойна теоретична формулировка, комбинаторната логика, обикновено се възприема като по-абстрактна от ламбда-смятането. Комбинаторната логика и ламбда-смятането са първоначално разработени, за да се постигне по-ясен подход към основите на математиката.

Един от ранните функционални език е Lisp, разработен от Джон Маккарти, в Масачузетския технологичен институт (MIT) за серията 700/7000 на IBM – научни компютри от края на 50-те години на XX век. Lisp въвежда много функции, които могат да се намерят и в съвременните функционални езици. Scheme и Dylan са по-късни опити да се опрости и подобри Lisp.

Езикът за обработка на информация IPL е първият компютърнобазиран функционален език за програмиране. Това е език за обработка на списъци от символи. Той съдържа така наречения генератор – функция, която приема друга функция като аргумент. Въпреки това той разчита основно на структури от променливи списъци и подобни императивни свойства.

Кенет Айвърсън разработва APL в началото на 60-те години на XX век и го описва в книгата си „A Programming Language“, издадена през 1962 г. По модела на APL Джон Бекъс създава езика FP. В началото на 90-те години на XX век Айвърсън и Роджър Хюи създават езика J. В средата на 90-те години Артър Уитни, който преди това е работил с Айвърсън, създава езика K, който се използва комерсиално във финансовите индустрии заедно със своя наследник Q.

Джон Бекъс представя FP в своята лекция по време на наградите Тюринг, през 1977, наименувана „Може ли програмирането да бъде освободено от архитектурата на фон Нойман? Функционалният стил и неговата алгебра от програми“. Научната статия на Бакъс популяризира изследванията в областта на функционалното програмиране, макар че набляга на програмиране на функционално ниво, а не на стила на ламбда-смятането, който се свързва по-често с функционалното програмиране.

През 70-те години на 20 век Робин Милнер създава езика ML в Единбургския университет, а Дейвид Търнър, първоначално разработва езика SASL в университета Сейнт Андрюс и по-късно езика Miranda в университета Кент. Също така в Единбург през 70-те години, Бурсщал и Дарлингтън разработват функционалния език NPL. NPL се основава на рекурсивните теореми на Клийн и за първи път го въвеждат в работата им по трансформация на програми. Бурсщал, МакКуийн и Санела по-късно въвеждат полиморфичния вид проверка от ML, за да измислят езика Hope. След време ML се разделя на няколко диалекта, най-често срещаните от които са OCaml и Standard ML. В същото време, развитието на Scheme (от части функционален диалект на Lisp), показва на обществото занимаващо се с програмни езици истинската сила на функционалното програмиране.

През 80-те години, Пер Мартин-Льоф разработва неговата интуиционистка теория (наричана също конструктивна теория), която свързва функционалните програми с конструктивните доказателства за произволно сложни математически твърдения, изразени като зависими типове. Това довежда до мощни нови подходи към интерактивното доказване на теореми и повлиява на развитието на много последващи функционални програмни езици.

Езикът Haskell започва с консенсус през 1987 г., за да създаде отворен стандарт за изследвания в сферата на функционалното програмиране; имплементациите продължават от 1990 г. до днес.

Концепции Определен брой концепции и парадигми са специфични за функционалното програмиране и като цяло чужди на императивното програмиране (включително и обектно-ориентираното програмиране). Въпреки това, програмните езици често са хибриди на няколко програмни парадигми, така че програмистите използващи "предимно императивни” езици може и да използват някои от тези понятия.

Първокласни функции и функции от по-висок ред Функции от по-висок ред са функции, които могат или да приемат други функции като аргументи или да ги върнат като резултат. В пресмятането пример за функция от по-висок ред е диференциалния оператор, който връща производната на дадена функция.

Функциите от по-висок ред са тясно свързани с първокласните функции по това, че и двата типа функции позволяват функции като аргументи и резултати от други функции. Разликата между двете е малка: „по-висок ред“ описва математическо понятие от функции, които работят върху други функции, докато „първокласни“ е термин от компютърната наука, който описва единици в програмния език, които нямат ограничение за тяхното ползване (по този начин първокласните функции могат да се появяват навсякъде в програмата, където и други първокласни единици, като числата, могат, както и като аргументи на други функции и като техните стойности за връщане).

Функциите от по-висок ред позволяват частично прилагане, техника, при която една функция се прилага към нейните аргументи един по един, като всяко прилагане връща нова функция, която приема следващия аргумент. Това позволява да се изрази накратко, например, функцията наследник като оператора за събиране е частично приложен към естественото число едно.

Чисти функции Чистите функционални функции (или изрази) нямат никакви странични ефекти (памет или I / O). Това означава, че чистите функции имат няколко полезни свойства, много от които могат да бъдат използвани за оптимизиране на кода: Ако не се използва в резултат на чистото изразяване, тя може да бъде отстранена без да се засягат други изрази.

Ако чистата функция се нарича с аргументи, които не причиняват странични ефекти, резултатът е константа по отношение на този списък с аргументи (понякога се нарича референтна прозрачност), т.е. ако чистата функция отново е призована със същите аргументи, същият резултат ще бъде върнат.

Ако няма зависимост от данни между два чисти израза, тяхната цел може да бъде обърната, или може да се извършва успоредно и те не могат да пречат един на друг (с други думи, оценката на всеки чист израз е безопасна).

Ако пълния език не позволява странични ефекти, тогава всяка стратегия за оценка може да бъде използвана; това дава свободата на компилатора да преподреди или комбинира оценката на изразяване в програма.

Докато повечето компилатори за императивни езици за програмиране засичат чисти функции и изпълняват елиминиране за чисти функционални разговори, те не винаги могат да направят това за предварително компилирани библиотеки, които по принцип не излагат тази информация, като по този начин предотвратява оптимизации, които включват тези външни функции. Някои компилатори, като GCC, добавят думи за един програмист за да отбележат изрично външни функции като чистите, за да се даде възможност за тези оптимизации. Fortran 95 също така позволява на функции да бъдат определени като „чисти“.

Рекурсия Повторение (итерация) във функционалните езици обикновено се осъществява чрез рекурсия. Рекурсивни функции се позовават, позволявайки на операция, да се извърши отново и отново, докато се достигне базовия модел. Въпреки че някои рекурсии изисква поддържане на стека, „опашатата“ рекурсия може да бъде разпозната и оптимизирана чрез компилатора в същия код, използван за въвеждане на итерация в императивните езици. Стандартът за език „Схема“ (Scheme) изисква имплементации за да разпознава и да се оптимизира опашатата рекурсия (Tail call). Оптимизацията на опашатата рекурсия може да бъде имплементирана чрез трансформиране на програмата към продължителен стил (Continuation-passing style (CPS), стил на програмиране при който функциите не връщат стойности), наред и с други подходи.

Общи модели на рекурсия може да се отчитат, като се използват по-високи функции за поръчка, с катаморфизъм и анаморфизъм (или „гънки“ и „разгъвки“) са най-очевидните примери. Такива високи поръчкови функции играят роля, аналогична на вградени контролни структури като цикли в императивните езици.