# Programação declarativa

Programação declarativa é um paradigma de programação baseado em programação funcional, programação lógica e programação restritiva. Tal termo é utilizado para discernir tais linguagens em relação à linguagens de programação imperativa. Esta programação dita que o programador deve modelar um dado problema através de assertivas acerca dos objetos do universo de discurso, ou seja, definindo o relacionamento lógico existente entre a cabeça e o corpo da cláusula, e nunca descrevendo como seus procedimentos funcionam. As soluções declarativas são usualmente mais fáceis de desenvolver e possuem a clareza e limpidez da pura lógica.
É considerada o paradigma fundamental da programação lógica, sendo o oposto da programação procedimental, que é típica das linguagens convencionais. Em particular, a programação restritiva e a programação lógica descrevem propriedades da solução desejada, não especificando como o algoritmo em si deve agir. Apesar disso a maioria das linguagens desses paradigmas permite que os algoritmos sejam implementados com detalhes, então não constituem uma linguagem declarativa pura por definição.
Similarmente, é possível escrever programas de forma declarativa utilizando linguagens de programação imperativas. Isso pode ser obtido utilizando métodos como encapsulamento para esconder detalhes de implementação fora de uma biblioteca. A programação declarativa geralmente considera os programas como teorias de uma lógica formal e os cálculos como deduções nesse espaço lógico e busca simplificar bastante a escrita e desenvolvimento de programas paralelos.
Linguagens funcionais que admitem tal abordagem incluem Erlang, Haskell e Lisp. Linguagens lógicas que admitem tal abordagem incluem Prolog e Mercury. Linguagens restritivas que admitem tal abordagem incluem Oz. Existem ainda as linguagens baseadas em consultas de banco de dados (por exemplo, SQL , XQuery).

## Definição geral

Apesar de possível utilizar linguagens imperativas em programação declarativa através de encapsulamento, a definição da mesma, é totalmente contrária às predisposições da programação imperativa. Algumas das definições da programação declarativa são:
* Um programa de alto nível que descreve o que o computador deve executar;
* Qualquer linguagem de programação que não tenha efeitos colaterais (em geral, que possua referenciamento transparente);
* Uma linguagem correspondente à lógica matemática.
A programação declarativa é um estilo de programação não imperativa, na qual os programas descrevem os resultados desejados sem listar explicitamente os comandos ou etapas que devem ser executados. Linguagens de programação funcionais e lógicas são caracterizadas por um estilo de programação declarativa. Em linguagens lógicas de programação, os programas consistem em instruções lógicas e o programa é executado procurando provas das instruções.
Em uma linguagem funcional pura, como Haskell, todas as funções não têm efeitos colaterais e as alterações de estado, são representadas apenas como funções que transformam o estado, que é explicitamente representado como um objeto de primeira classe no programa. Embora as linguagens funcionais puras não sejam imperativas, elas geralmente fornecem uma facilidade para descrever o efeito de uma função como uma série de etapas. Outras linguagens funcionais, como Lisp , OCaml e Erlang , suportam uma mistura de programação procedural e funcional.
Algumas linguagens lógicas de programação, como o Prolog, e linguagens de consulta de banco de dados, como SQL, embora declarativas em princípio, também suportam um estilo de programação procedural.

## Exemplo

Para facilitar o entendimento na pratica, se pode considerar o seguinte exemplo que compara a programação declarativa com a programação procedimental.
No seguinte exemplo podemos perceber que a programação declarativa determina se um dado objetivo é verdadeiro e, se for, indica em que valores de variáveis isto se verifica. Observa-se também que ele apenas descreve o que o "programa" faz, não listando como seus procedimentos funcionam, o que é uma das características base de tal programação.
* Programação declarativa:
Por outro lado, a programação procedimental não apenas define o relacionamento lógico existente entre a cabeça e o corpo do cláusula, o que acontece na declarativa, como também exige a existência de uma ordem e procedimento no qual os objetivos serão processados.
* Programação procedimental:
É importante ressaltar que durante o desenvolvimento de uma solução, deve-se buscar as ideias adequadas para decompor o problema principal em subproblemas de solução mais fácil, que pode corroborar na eficiência do programa.

### Exemplos de linguagens
#### LISP
## Subparadigmas

Por se tratar de um modo abrangente, a programação declarativa em geral inclui vários dos paradigmas de programação mais conhecidos.

### Programação de restrição

A programação de restrições indica relações entre variáveis ​​na forma de restrições que especificam as propriedades da solução de destino. O conjunto de restrições é resolvido fornecendo um valor para cada variável, de modo que a solução seja consistente com o número máximo de restrições. A programação de restrições geralmente complementa outros paradigmas: programação funcional, lógica ou até imperativa.

### Linguagens específicas de domínio

Exemplos conhecidos de linguagens declarativas específicas de domínio (DSLs), incluem a linguagem de entrada do gerador de analisador yacc, QML, a linguagem de especificação de compilação Make, linguagem de gerenciamento de configuração do Puppet, expressões regulares e um subconjunto de SQL (consultas SELECT, por exemplo). As DSLs têm a vantagem de serem úteis, embora não precisem necessariamente ser computacionalmente universal, o que torna mais fácil para uma linguagem ser puramente declarativa.
Muitas linguagens de marcação, como HTML, MXML, XAML, XSLT ou outras linguagens de marcação da interface do usuário, são frequentemente declarativas. O HTML, por exemplo, descreve apenas o que deve aparecer em uma página da Web, não especifica nem o fluxo de controle para renderizar uma página, nem as possíveis interações da página com um usuário.
A partir de 2013, alguns sistemas de software combinam linguagens de marcação de interface de usuário tradicionais (como HTML) com marcação declarativa que define o que (mas não como) os sistemas de servidor de backend devem fazer para suportar a interface declarada. Esses sistemas, geralmente usando um namespace XML específico do domínio, podem incluir abstrações da sintaxe do banco de dados SQL ou chamadas parametrizadas para serviços da Web usando transferência de estado representacional (REST) ​​e SOAP.

### Linguagens híbridas

Veja também: Linguagem de programação multiparadigmática
Makefiles, por exemplo, especificam dependências de forma declarativa, mas incluem uma lista imperativa de ações a serem tomadas também. Da mesma forma, o yacc especifica uma gramática livre de contexto declarativamente, mas inclui trechos de código de uma linguagem de host, que geralmente é imperativa (como C ).

### Programação lógica

Linguagens de programação lógica, como estado Prolog e relações de consulta. As especificidades de como essas consultas são respondidas dependem da implementação e de seu teorema, mas geralmente assumem a forma de algum tipo de unificação. Como a programação funcional, muitas linguagens de programação lógica permitem efeitos colaterais e, como resultado, não são estritamente declarativas.

### Modelagem

Modelos, ou representações matemáticas, de sistemas físicos podem ser implementados em código de computador que é declarativo. O código contém um número de equações, não atribuições imperativas, que descrevem ("declare") as relações comportamentais. Quando um modelo é expresso nesse formalismo, um computador é capaz de realizar manipulações algébricas para melhor formular o algoritmo de solução. A causalidade matemática é tipicamente imposta nos limites do sistema físico, enquanto a descrição comportamental do próprio sistema é declarativa. Linguagens e ambientes de modelagem declarativa incluem Analytica, Modelica e Simile.