Funkcyjny paradygmat programowania jest podparadygmatem programowania deklaratywnego. W programowaniu funkcyjnym (funkcjonalnym), tak jak w deklaratywnym, opisujemy pożądany wynik ale w postaci funkcji. Zadaniem interpretera lub kompilatora języka funkcyjnego jest obliczenie wartości funkcji, a więc pewnego wyrażenia.
W programowaniu czysto funkcyjnym funkcje zawsze przyjmują tę samą wartość dla tych samych argumentów a więc nie zależą ani od stanu maszyny, ani od urządzeń wejścia/wyjścia, użytkownika, pamięci zewnętrznej itd.
W związku z pojęciem programu jako złożenia pewnych funkcji, w programowaniu funkcyjnym nie występują zmienne znane z programowania imperatywnego ani pętle, zamiast których używa się rekurencji (zmienne i pętle potrzebują dostępu do stanu maszyny, którego tu nie ma).
Z drugiej strony, funkcje te mogą być takimi samymi wartościami argumentów i wyników innych funkcji jak dane - liczby, napisy, listy...
Możliwe jest tutaj tzw. leniwe wartościowanie wyniku funkcji, czyli obliczanie tylko fragmentów wyniku, potrzebnych dla innej funkcji.
Umożliwia to obliczanie składowych funkcji niezależnie od siebie, co pozwala na automatyczne zrównoleglanie kodu i przetwarzanie potokowe.
W programowaniu logicznym (należącym do paradygmatu deklaratywnego) — nie opisuje się drogi do rozwiązania, lecz dostarczamy maszynie zbiór przesłanek oraz tezę do dowiedzenia w postaci pytania. Maszyna ma udowodnić tezę na podstawie danych przesłanek. Wszystkie inne działania maszyny są efektami ubocznymi tego dowodzenia.