💻 Código Imperativo vs Declarativo: o futuro da programação

Fome

Imagine que você está atrasado para ir para o trabalho e bate aquela fome da hora do almoço. Você está sem tempo mas precisa comer. O que você faz? Vai no App, pede uma comida rápida, come e vai para o seu dia de trabalho resolver a pilha de coisas que você tem pendente.

Mas já parou para pensar que, a pouco tempo atrás, para podermos comer, precisávamos comprar uma terra e sementes, plantar, esperar chover, preocupar-se com estiagem, regar, esperar crecer, colher e ainda cozinhar para poder então finalmente comer? Bom, provavelmente não iria sobrar tempo para você terminar a sua pilha de tarefas no seu trabalho!

A verdade é que hoje vivemos cada dia mais em um mundo mais "Declarativo", aonde somente ao toque de um comando no celular, pedimos comida em casa e automaticamente, tudo o que eu falei anteriormente, acontece. Às vezes de maneira assíncrona ou síncrona, para atender ao seu pedido da maneira mais simples possível. Não nos preocupamos com o clima, estação do ano para que a comida chegue a nossas mesas.

Mas eai, vai falar de programação ou de comida?

Tendo em mente o que disse no inicio, agora você vai entender melhor o que é um Código Imperativo e um Código Declarativo. Definimos assim:

Código imperativo: é aquele que diz exatamente como resolver um problema, passo a passo. Ele se preocupa com os detalhes de como o código deve ser executado. Como se a máquina fosse um bebê, escrevemos todas as instruções (seria como seu eu tivesse que plantar e colher todos os dias para fazer as atividades do dia-a-dia).

Código declarativo: se preocupa com o que deve ser feito, mas não com os detalhes de como fazê-lo (como pedir no iFood, eu não me preocupo com os passos que estão por trás, eu só declaro que "Quero comida agora!").

Exemplo:

Mas como Devs gostam de código, vou dar um exemplo em JavaScript de como extrair a raíz quadrada de um número de maneira Imperativa e de maneira Declarativa:

Forma Imperativa:

function getSquareRoot(n) {
  let root = n / 2;
  let precision = 0.00001;
  while (n - root * root > precision || root * root - n > precision) {
    root = (n / root + root) / 2;
  }
  return root;
}
const result = getSquareRoot(9),
console.log(result);

Forma Declarativa:

const result = Math.sqrt(9);
console.log(result);

Percebeu a diferença? Na forma imperativa eu digo passo-a-passo o que deve ser feito. Já na forma declarativa, já existe uma função que faz todo o trabalho árduo para você. Você só tem que chamá-la!

Mas como isso? Mágica?

Na verdade todo código Declarativo somente "emcapsula" a sua parte Imperativa. Alguém teve que escrever imperativamente para você não ter esse trabalho. Por exemplo, a implementação do método Math.sqrt em JS está escrita em C, da seguinte forma:

double sqrt(double x) {
  // Check for negative and non-numeric input.
  if (x < 0 || isnan(x)) {
    return NAN;
  }

  // Check for exact result.
  if (x == 0 || x == 1) {
    return x;
  }

  // Initialize variables.
  double xHalf = 0.5 * x;
  double y = x;
  double z = 1;

  // Iterate until result is accurate.
  while (z != y) {
    y = z;
    z = x / y;
    z = 0.5 * (z + y);
  }

  return z;
}

Viu? Não existe mágica, somente simplificação do código. Assim como a comida não chega na porta da sua casa em passe de mágica. Conforme vamos aumentando a complexidade de um programa, vamos deixando para outras "pessoas" as implementações específicas, para que nos preocupemos com o mais importante.

Vantagens e Desvantagens:

vs

Nos códigos imperativos, personalizamos à nossa maneira, de acordo com o nosso gosto, em troca, temos o trabalho de pensar em todos os detalhes. É como comprar pão no mercado. Por exemplo os de "saquinho": tenho a facilidade de ir, comprar e nem pensar mais em nada sem ter que assá-lo em casa, limpar a sujeira de trigo na mesa ou ter que ficar vigiando para não queimar. Mas, não posso escolher o tipo de fermentação, trigo, tempo no forno e outras coisas.

Vantagens/Tipo Código Código Declarativo Código Imperativo
Vantagens Mais simples e direto Mais fácil de entender quando há bugs internos
Mais legível Mais fácil de testar
Mais fácil de entender a finalidade Mais fácil de implementar soluções personalizadas
Desvantagens Menos explorável Mais verboso
Menos flexível Mais propenso a erros

Tudo é Encapsulação

Under the hood

Basicamente é como um carro. Só precisamos saber dirigir, não precisamos saber como as rodas giram ou quantas moléculas de Etanol ou Benzeno são necessárias para fazê-lo rodar. Mas, debaixo do capô (Under the Hood), sem todo esse processo, mesmo você sabendo dirigir, o carro não andará.

React, Vue, Angular, Solid, Svelt (e qualquer outro framework que nasça do dia para noite no universo JS), tem o objetivo de simplicar o processo de apresentação dos dados no Front-End, oferecendo métodos Declarativos para fazer funções complexas que, Under the Hood, fazem várias alterações Imperativas.

Futuro

IA

Com o advento da Inteligência Artificial (AI), creio que ela será capaz, em pouco tempo, de até mesmo criar sua própria linguagem de programação para oferecer ao Dev um solução totalmente Declarativa e ela será a responsável de criar o código Imperativo por trás, até mesmo transpilá-o para Assembly ou direto para Binário.

Será que estamos próximos de poder rodar um código mais ou menos assim:?


AppBuilder.createABeaultifullApp()
          .withGreatDesign()
          .fastLikeSpeedOfLight()
          .thatRunsEverywhere()
          .andGiveMeALotOfMoney()
          .thanks();

E você, o que você acha disso tudo? Quais são para você as vantagens da forma Declarativa e Imperativa? E a AI (que está de moda), nos ajudará a ter uma vida mais fácil (tal qual já não precisamos todos viver no campo)? 👇🏻

Acredito que o declarativo tem formado muitos programadores sem fundamento ou base sólida. Muito em parte da modinha atual de programação funcional sendo vendida como a verdade do universo.

Concordo plenamente. A abstração da programação deixa os programadores mais "preguiçosos", sem a mínima capacidade de entender o que de fato ocorre por trás... Mas, será que em um futuro não tão distante, essa não será a nova realidade?
Isso vale para quem está entrando nesse universo, a barreira de entrada será cada vez mais menor e mais gente poderá entrar na programação, se preocupando mais em integrar diferentes sistemas do que desenvolver o sistema em si, já que ele estará utilizando as abstrações. Mas, ao mesmo tempo, apesar de existir milhares de abstrações existentes, cada vez mais será necessário entender o "capo do carro" para construir novas abstrações, um grande exemplo é a recente crescente da linguagem de programação Rust, criada para lidar com sistemas low-level (Da mesma forma que C e C++). E isso é uma das principais diferenças entre os programadores iniciantes e os que têm experiência, enquanto o iniciante utiliza as abstração (sem entendê-las) para criar algo maior (sistemas integrados a outros sistemas), os programadores experientes entendem essas abstrações e sabem escolher as melhores para solucionar o determinado problema. São é apenas necessário saber usas abstrações, mas como entendê-las e construí-las também!!, ai que entram vários dos design patterns e conceitos que aprendemos. Portanto abstrações não são ruins! O Filipe Deschamps já comentou a respeito disso no vídeo [O que um Sênior sabe, que um Pleno não sabe e um Júnior menos ainda](https://www.youtube.com/watch?v=DYz3A9DT-Qc). Paradigma funcional não é a verdade universal, mas certamente seus padrões estão sendo replicados para outras linguagens populares como Java, JS e Python.
Infelismente sim, acredito que n futuro será assim. Talvez uma maneira do mercado se auto regular com programdores quase low-code. Tipo os juniores que spo sabem usar um framework.

Na minha visão essa dicotomia vai de fato se desenvolver cada vez mais, principalmente com as ferramentas que a IA fornece. Contudo, por serem bastante diferentes entre si, a utilidade das duas sempre será algo real, visto que a praticidade está aliada com o avanço tecnológico, demandando, no caso, o código declarativo. Por sua vez, a sociedade tem esse padrão de "sair do padrão" e sempre buscar por novas tendência e pensar fora da caixa, demandando coisas mais personalizadas e desafiadoras.

Sim certamente! Ainda hoje temos "trabalhadores do campo", ou seja, mesmo no futuro, ainda haverá muito espaço para Devs especializados em desenvolvimento de baixo nível ou similares.

Pessoalmente; acho que o declarativo às vezes pode ter uma curva de aprendizagem mais inclinada, e algumas vezes quando recorremos ao declarativo precisamos pesquisar. O que é diferente quando vamos resolver de uma forma mais imperativa; mesmo correndo o risco de estar "reinventando a roda", já dominamos as ferramentas.

Decidir quando ser mais ou menos declarativo ou imperativo envolve técnica e experiencia (e talvez até bom censo).

Em ambas situações; quanto temos tempo, é interessante dar uma olhada em baixo do capô para enterder como o motor funciona (aproveitando a sua analogia).