A primeira linha da documentação introdutória do SwiftUI inevitavelmente menciona um “framework declarativo”. React e Jetpack Compose também se descrevem como declarativos.
Mas, quando alguém pergunta “o que significa declarativo?”, a resposta não é tão simples. “É código limpo” não está correto.
A diferença entre declarativo e imperativo se resume a uma frase. Você escreve “How” ou “What”?
Este artigo aborda esse critério com exemplos do dia a dia, confirma a diferença com código UIKit e SwiftUI e mostra que o declarativo não é gratuito.
Este é o resumo principal.
- Imperativo: instruir passo a passo o procedimento para chegar ao resultado desejado — How
- Declarativo: descrever o resultado desejado e deixar o procedimento para o sistema — What
- SQL, HTML, map/filter e SwiftUI são exemplos representativos de programação declarativa
- A essência da UI declarativa: declarar “quando o estado for este, a tela será assim”, deixando as atualizações decorrentes da mudança de estado para o framework
Uma analogia com um táxi
No modelo imperativo, você orienta o motorista diretamente: “vire à direita, siga por 300 metros, vire à esquerda no sinal…”. Você instrui cada etapa, e a soma delas produz o resultado de chegar ao destino.
No modelo declarativo, você diz: “Me leve à estação Gangnam”. Informa apenas o destino (What) e deixa a escolha da rota (How) para o motorista e o navegador.
Os dois chegam ao destino. A diferença é se eu sou dono do procedimento ou apenas da descrição do resultado.
No código, a mesma tarefa pode ser escrita de duas formas
Vamos escrever de duas formas o código que seleciona números pares e os eleva ao quadrado.
// Imperativo: eu indico como iterar e onde armazenar o resultado
var result: [Int] = []
for n in numbers {
if n % 2 == 0 {
result.append(n * n)
}
}
// Declarativo: descrevo apenas o que quero
let result = numbers.filter { $0 % 2 == 0 }.map { $0 * $0 }
A versão imperativa expõe as “peças do procedimento”, como a variável do loop, o array intermediário e a ordem. A versão declarativa deixa apenas a intenção: “filtrar os pares e elevá-los ao quadrado”. O método de iteração fica oculto dentro de filter e map.
Você provavelmente já usa formas declarativas mais conhecidas. Em SQL, escreve apenas “quero as linhas com estas condições”, não como pesquisar o índice. Em HTML, declara a estrutura —“um título aqui, um parágrafo ali”—, não o procedimento de renderização.
Na UI, a diferença aumenta drasticamente
A UI imperativa (UIKit) usa procedimentos para alterar a tela.
// UIKit: Instruir diretamente as operações da tela sempre que o estado mudar
func updateBadge(count: Int) {
if count > 0 {
badgeLabel.isHidden = false
badgeLabel.text = "\(count)"
} else {
badgeLabel.isHidden = true
}
}
A dificuldade é que o desenvolvedor precisa acompanhar continuamente “em que estado a tela atual está”. Quando há vários caminhos de atualização, é fácil esquecer um deles, gerando o bug clássico: “os dados mudaram, mas a tela continua igual”.
A UI declarativa (SwiftUI) declara como a tela deve aparecer para determinado estado.
// SwiftUI: countDeclarar que, quando o estado for este, a tela será assim
struct BadgeView: View {
let count: Int
var body: some View {
if count > 0 {
Text("\(count)").badgeStyle()
}
}
}
Quando count muda, você não escreve como corrigir a tela. O SwiftUI compara a declaração anterior com a nova e atualiza apenas as partes necessárias. A UI vira uma “função do estado”. Como o framework assume a propriedade do procedimento de atualização, não há código de atualização para esquecer.
O declarativo não é gratuito
Para manter o equilíbrio, também precisamos olhar o outro lado.
Esconder o procedimento é frustrante quando você precisa dele. Um pedido imperativo como “mova a rolagem exatamente para este offset” pode exigir um contorno em um framework declarativo.
A depuração tem uma natureza diferente. No imperativo, você acompanha o procedimento; no declarativo, precisa rastrear as decisões do framework, perguntando “por que foi redesenhado?”. Não dá para ignorar completamente o How oculto.
O ajuste de desempenho acaba exigindo entender os internos. Quando o SwiftUI recalcula views em excesso, é preciso entender como diffing e rastreamento de dependências funcionam para resolver o problema.
Por isso, a perspectiva correta não é “o declarativo é superior”, mas uma escolha do nível de abstração. Transferir a propriedade do procedimento simplifica o código em torno da intenção, mas deixa o controle detalhado e o entendimento interno como desafios.
Resumo
- O imperativo instrui o procedimento para chegar ao resultado (How), enquanto o declarativo descreve o resultado desejado (What)
- SQL, HTML e map/filter já são formas declarativas conhecidas
- A UI imperativa escreve os procedimentos que alteram a tela e tende a gerar bugs de inconsistência entre estado e tela
- A UI declarativa declara “quando o estado for este, a tela será assim”, e o framework cuida das atualizações (UI = função do estado)
- O custo do declarativo: o controle detalhado dos procedimentos é difícil e, no fim, é necessário entender o funcionamento interno do framework
- A essência não é superioridade, mas escolher quem possui o procedimento

