Eu diria que é mais Programação Funcional vs Programação Imperativa .
A maior diferença é que a programação imperativa é sobre fluxo de controle enquanto a programação funcional é sobre fluxo de dados . Outra maneira de dizer é que a programação funcional usa apenas expressões enquanto na programação imperativa são usadas expressões e declarações .
Por exemplo, em variáveis de programação imperativas e loops são comuns ao lidar com estado, enquanto na programação funcional o estado é tratado via passagem de parâmetros, o que evita efeitos colaterais e atribuições.
Pseudo-código imperativo para uma função para calcular a soma de uma lista (a soma é mantida em uma variável):
int sumList(List<int> list) {
int sum = 0;
for(int n = 0; n < list.size(); n++) {
sum = sum + list.get(n);
}
return sum;
}
Pseudo-código funcional para a mesma função (a soma é passada como um parâmetro):
fun sumList([], sum) = sum
| sumList(v::lst, sum) = sumList(lst, v+sum)
Eu recomendo a apresentação Taming Effects com programação funcional Simon Peyton -Jones para uma boa introdução aos conceitos funcionais.