Explicação e prova
Linguagens de programação não existem apenas para comunicar instruções à máquina. Elas existem para transformar ideias vagas em representações formais, livres de ambiguidades.
O impacto de ferramentas de IA generativa baseadas em LLMs na indústria de desenvolvimento de software tem sido indubitavelmente considerável (e polêmico). Entre os vários questionamentos e reflexões que se tem feito, uma chama minha atenção em particular: o que será das linguagens de programação agora que agentes são capazes de escrever programas inteiros através de ciclos de interação com humanos? Dado que essas interações baseam-se na explicação das especificações do programa em linguagem natural, a formulação de uma representação do programa em JavaScript, C, Rust ou Go, por exemplo, passaria a ser obsoleta, redundante. Sendo assim, por que deveríamos ensinar as novas gerações a programar? O agente poderia gerar o código binário, já pronto para ser executado, certo? Bom… talvez não exatamente. O equívoco que observo nessa prospectiva está na não observância da diferença fundamental entre explicação e prova.
Um bom prompt
Uma pessoa pode explicar à máquina comandos, comportamentos e características que gostaria que integrassem um programa. A linguagem natural, no entanto, carrega intrinsecamente ambiguidades, que tem lá sua função na comunicação humana, mas que condicionam o entendimento da explicação a um caráter não determinístico. Ou seja, é possível que a interpretação da mensagem pelo receptor encontre compatibilidade com a intenção do emissor, mas também pode ser que não o faça.
O código-fonte, por outro lado, lança mão de estruturas formais para definir fluxos e relações lógicas, escopo, variáveis, etc.. Isso garante correspondência determinística entre aquilo que é representado no código e o efeito de sua execução. Portanto, um programa, ao provar a idéia em seu código, não simplesmente comunica as suas características, mas é incorporado pela máquina que o executa quando garante uma execução determinística.
Nota-se que por muitas vezes se diz que um bom prompt deve usar as palavras certas, deve ser construído de uma maneira sucinta e objetiva, expondo pontos de interesse específicos, não pode conter informações supérfluas, etc.. Todo esse cuidado serve para que a máquina não se perca em interpretações que desviem da intenção original do prompt. Se seguíssemos estreitando as possibilidades de comunicação (palavras que podem ser usadas, formulações sintáticas) para mitigar ambiguidades, qual seria o resultado? Não seria isto a conversão de uma linguagem natural em uma linguagem formal?
Um ponto de vista matemático
No processo de desenvolvimento de software, partimos da coleta de requisitos que consolidam uma idéia, ainda em nível alto de abstração. Quando usamos uma linguagem de programação para transcrever tal idéia em código-fonte, estamos definindo uma representação que procura formalizá-la.
Para ilustrar esse ponto, recorramos à matemática. Consideremos a seguinte descrição:
Uma linha parte do chão, passa pelo ponto onde a altura está a 1 metro do chão, e toca o chão de novo a um metro da origem.
Agora tentemos representar essa idéia através de um desenho.

Todos os requisitos dessa primeira explicação são verificáveis na representação gráfica acima, porém, esta não é necessariamente acurada em relação à idéia imaginada inicialmente. Podemos reiterar a explicação e tentar nos aproximar da idéia, mas esta carregará sempre um grau de imprecisão que transforma essa busca em algo praticamente aleatório.



Por fim, descrevamos a linha lançando mão da seguinte notação:
x → distância horizontal em metros com origem no ponto inicial da linha,
y → altura em metros partindo do chão
Assim, é possível observar a posição inequívoca da linha em cada ponto da trajetória entre a origem e o destino.

Essa precisão e observabilidade só é alcançada através da proposta de uma prova formal da idéia, que exclui ambiguidades. Se dissermos que a linha ainda não corresponde à especificação inicial (o que seria um bug), podemos e sabemos como ajustar a expressão matemática dada a fim de alcançar o resultado desejado. Expressões matemáticas e programas computacionais, equivalentes por sua natureza formal, compartilham dessa mesma capacidade.
Quem lerá o código de amanhã?
O que os Agentes de IA baseados em LLM fazem atualmente é traduzir uma explicação, dada em linguagem natural, em código-fonte feito com retalhos. Remover por completo o fardo humano de aprender regras de sintaxe de uma linguagem formal, delegar todo o peso de interpretação à máquina e aos seus modelos de linguagem pode parecer tentador. No entanto, não creio que seja desejável para ninguém (empresas, bancos, hospitais, órgãos de governo, etc..) que programas se tornem artefatos inobserváveis, virtualmente incorrigíveis, cuja única possibilidade de retificação seria mais um prompt e fé em que o agente acerte a especificação. Haverá sempre a necessidade de que alguém valide, mantenha, interprete falhas e certifique a segurança do que é produzido. Estamos presos à necessidade de manter programas em uma forma que seja inteligível por nós e incorporável pela máquina. As linguagens de programação continuam sendo elementos fundamentais na engenharia de software e, com isso, a necessidade de pessoas que as compreendam.