Filosofia de engenharia: Edsger Dijkstra, elegância não é opcional

Principais conclusões
- Elegância não é opcional. Para Dijkstra, a simplicidade é a precondição da correção, não uma recompensa colhida depois dela – você não pode provar aquilo que não consegue compreender por completo.
- A prova vence o teste. “Testar mostra a presença, não a ausência de defeitos.” A confiança na correção vem do raciocínio sobre um programa, nunca do acúmulo de testes que passam.
- Pense antes de programar. Ele projetou seu algoritmo de caminho mais curto sem lápis nem papel, forçando-o a ser pequeno o bastante para caber em uma só cabeça – a restrição produziu a elegância.
- Escrever é pensar. Os manuscritos EWD, redigidos à mão com caneta-tinteiro e sem desfazer, faziam um argumento valer ou ruir na própria tinta – a mesma disciplina aplicada à prosa.
O princípio
“A simplicidade é pré-requisito da confiabilidade.” – Edsger W. Dijkstra, atribuído (c. 1975)1
A frase sobrevive como um aforismo de uma linha, quase uma anotação de margem, associada aos seus memorandos deliberadamente provocativos de cerca de 1975. Despida de contexto, soa como um slogan, mas Dijkstra a entendia como uma afirmação lógica estrita. Confiabilidade não é algo que você acrescenta a um sistema complicado testando-o com mais afinco. Um sistema que você não consegue entender por inteiro é um sistema que você não consegue provar correto, e um sistema que você não consegue provar correto vai falhar de maneiras que você não previu. A simplicidade não é uma preferência estilística que compete com a correção. É aquilo de que a correção é feita. Você não pode ter a segunda sem a primeira.
Isso inverte o modo como a maior parte do software é de fato escrita. O instinto comum é construir a coisa, fazê-la funcionar e então testar até os defeitos pararem de aparecer – tratando a simplicidade como um luxo a perseguir depois, se houver tempo. A carreira inteira de Dijkstra foi um argumento de que essa ordem é invertida e perigosa. Sua frase mais citada é a advertência que decorre diretamente disso: “Testar mostra a presença, não a ausência de defeitos.”2 Um teste que passa nada diz sobre as entradas que você não experimentou. A única forma de saber que um programa não tem defeitos é raciocinar sobre ele – e você só consegue raciocinar sobre o que é simples o bastante para caber em uma só cabeça humana. A elegância, para Dijkstra, “não é um luxo dispensável, mas um fator que muitas vezes decide entre o sucesso e o fracasso.”3
Essa convicção o coloca na nascente desta série. Onde Linus Torvalds remodela um problema até o caso especial desaparecer e John Carmack reduz um problema ao seu núcleo veloz, Dijkstra forneceu a afirmação subjacente que ambos herdaram: a solução elegante e a solução correta são a mesma solução. É o argumento original para tratar o bom gosto como um sistema técnico em vez de uma indulgência estética – e o argumento pela prova acima da plausibilidade décadas antes de alguém chamá-lo assim.
Contexto
Edsger Wybe Dijkstra nasceu em 11 de maio de 1930 em Roterdã, nos Países Baixos, e morreu em 6 de agosto de 2002 em Nuenen.4 Seu pai era químico e presidente da Sociedade Química Neerlandesa; sua mãe era matemática com, por relato dele próprio, uma noção incomumente clara de quando um argumento matemático era elegante e quando apenas funcionava. Ele estudou matemática e física teórica em Leiden, e então aceitou um emprego como programador no Centro Matemático de Amsterdã em 1952 – num momento em que “programador” ainda não era uma profissão reconhecida. Quando tentou registrá-la como sua ocupação em sua certidão de casamento em 1957, as autoridades neerlandesas teriam se recusado a aceitá-la, porque tal cargo não existia oficialmente; ele teve de escrever “físico teórico” em seu lugar.4
Esse detalhe não é mera curiosidade. Dijkstra passou o resto da vida insistindo que a programação era uma disciplina intelectual rigorosa, e não um ofício de escrivão, e a insistência começou antes de a disciplina ter um nome. Ele ocupou um cargo no Centro Matemático, depois tornou-se professor na Universidade de Tecnologia de Eindhoven em 1962, passou os anos 1970 como pesquisador associado na Burroughs Corporation e, em 1984, assumiu a Cátedra do Centenário Schlumberger em Ciências da Computação na Universidade do Texas em Austin, onde permaneceu até sua aposentadoria em 1999.4
Em 1972 recebeu o Prêmio Turing da ACM. Vale ler a justificativa por inteiro, porque ela nomeia o princípio melhor do que qualquer resumo: “Por contribuições fundamentais à programação como um alto desafio intelectual; pela insistência eloquente e demonstração prática de que os programas devem ser compostos corretamente, não apenas depurados até a correção; pela percepção esclarecedora de problemas nos fundamentos do design de programas.”5 Compostos corretamente, não apenas depurados até a correção. Essa frase é o homem inteiro.
A obra
O algoritmo de caminho mais curto (1956, publicado em 1959)
Em 1956, pediram a Dijkstra que encontrasse um problema capaz de exibir o novo computador ARMAC em sua inauguração oficial – algo que uma plateia leiga conseguisse acompanhar. Ele escolheu a rota mais curta entre duas de 64 cidades neerlandesas, porque qualquer um conseguiria entender a pergunta e verificar a resposta. A solução lhe veio de um jeito que ele nunca se cansou de recontar: “Numa manhã eu estava fazendo compras em Amsterdã com minha jovem noiva e, cansados, sentamo-nos no terraço de um café para tomar uma xícara de café, e eu estava justamente pensando se conseguiria fazer isso, e então projetei o algoritmo do caminho mais curto.”6 Levou cerca de vinte minutos.
O método pelo qual ele o encontrou é a lição. “Uma das razões pelas quais é tão bonito”, disse mais tarde, “é que eu o projetei sem lápis nem papel. Aprendi depois que uma das vantagens de projetar sem lápis e papel é que você é quase forçado a evitar toda complexidade evitável.”6 Ele não podia se apoiar em rascunhos, então a ideia tinha de ser pequena o bastante para caber inteira em sua mente. A restrição produziu a elegância. Ele não o publicou por três anos – o artigo de 1959, “A Note on Two Problems in Connexion with Graphs”, na Numerische Mathematik, mal passa de uma página – porque, como ele dizia, a programação ainda não era considerada uma atividade respeitável o bastante para se escrever a respeito.6
O algoritmo é guloso: ele sempre expande primeiro o nó não visitado mais próximo, uma frente de onda em expansão que alcança cada ponto por sua menor distância, um a um. É simples o bastante para explicar na mesa de um café, e é comprovadamente ótimo – na primeira vez que a frente de onda toca o destino, esse caminho não pode ser superado. Simples e correto não estão em tensão aqui. São o mesmo fato.
“Go To Statement Considered Harmful” e a programação estruturada (1968)

Em 1968, Dijkstra submeteu uma carta ao Communications of the ACM sob o título “A Case Against the Goto Statement”. O editor, Niklaus Wirth, rebatizou-a “Go To Statement Considered Harmful” – uma expressão que gerou um gênero inteiro de imitações e hoje é mais famosa do que qualquer coisa na própria carta.7 O argumento de Dijkstra não era um guia de estilo. Era epistemológico. O goto sem restrição permite que o controle salte para qualquer lugar, o que significa que, para entender o que um programa faz em uma dada linha, você pode ter de rastrear todo caminho que poderia ter levado até ali. O texto do programa e o comportamento do programa se descolam. Com controle estruturado – sequência, seleção e laços –, o texto e a execução permanecem em correspondência, e você pode raciocinar sobre um bloco lendo o bloco.
O argumento é o mesmo princípio da restrição do caminho mais curto, aplicado ao design de linguagens: mantenha a coisa pequena o bastante para se raciocinar sobre ela. A programação estruturada não era sobre banir uma palavra-chave. Era sobre preservar a capacidade humana de provar, pela leitura, que o programa está correto. A lista de termos do seu vocabulário evocada na justificativa do Turing – “abraço mortal”, “semáforo”, “programação sem go-to”, “programação estruturada” – é um registro de quão profundamente ele remodelou a linguagem em que os programadores pensam.5
Seu trabalho em sistemas operacionais carregava o mesmo DNA. O sistema de multiprogramação THE (1968) foi construído como níveis de abstração estritamente em camadas, cada um verificável por si só. Para coordenar processos concorrentes, ele inventou o semáforo e suas operações P e V, e formulou o problema dos filósofos jantando como uma destilação didática de deadlock e starvation – uma questão difícil de concorrência tornada pequena o bastante para caber na mente.45 Mais tarde vieram a autoestabilização e, em A Discipline of Programming (1976), o cálculo do transformador de predicados / precondição mais fraca: um método para derivar um programa e sua prova de correção juntos, lado a lado, em vez de escrever código e torcer para verificá-lo depois.45
The Humble Programmer: prova acima do teste (1972)
A palestra do Prêmio Turing de Dijkstra, “The Humble Programmer” (EWD340), é a formulação mais clara de por que a simplicidade é uma preocupação moral, e não apenas prática. Sua afirmação central é sobre o tamanho da mente humana. “O programador competente tem plena consciência do tamanho estritamente limitado de seu próprio crânio; por isso aborda a tarefa de programar com plena humildade e, entre outras coisas, evita truques espertos como se fossem a peste.”8 Esperteza não é uma virtude. É uma aposta de que você consegue reter na cabeça mais do que de fato consegue, e a aposta é liquidada em produção, contra você.
A palestra aterrissa numa prescrição que se lê como a carta fundadora do software correto por construção: “Faremos um trabalho de programação muito melhor, desde que abordemos a tarefa com plena valorização de sua tremenda dificuldade, desde que nos atenhamos a linguagens de programação modestas e elegantes, desde que respeitemos as limitações intrínsecas da mente humana e abordemos a tarefa como Programadores Muito Humildes.”8 O teste, nesse enquadramento, é fundamentalmente insuficiente – não porque testar seja inútil, mas porque ele só pode amostrar o espaço de entradas. A forma canônica mais longa de sua advertência, de “Notes on Structured Programming”, é inequívoca: “O teste de programas pode ser usado para mostrar a presença de defeitos, mas nunca para mostrar sua ausência!”9 Se você quer a ausência de defeitos, tem de prová-la, e você só pode provar aquilo que consegue compreender.
Os manuscritos EWD como prática (anos 1960–2002)

Por cerca de quarenta anos Dijkstra escreveu uma série numerada de manuscritos – memorandos, provas, relatos de viagem, ensaios e argumentos – prefixados com suas iniciais, “EWD”. A série vai até o EWD1318, com mais de mil documentos de fato; os números excedem os documentos porque ele atribuía um número quando começava uma peça, e nem toda peça era concluída.410 A maioria foi composta à mão, numa caligrafia notoriamente precisa, com caneta-tinteiro. Ele não rascunhava no computador. Escrevia um manuscrito, fotocopiava-o e o enviava por correio a um pequeno círculo de colegas, que o copiavam e o repassavam adiante – um samizdat pré-internet que deu aos EWDs uma influência desproporcional ao fato de quase nenhum ter sido formalmente publicado.410 A série completa está hoje digitalizada e disponível gratuitamente no E.W. Dijkstra Archive, na UT Austin.10
A prática era inseparável da filosofia. Escrever à mão, devagar, sem desfazer, impõe a mesma disciplina de projetar sem lápis nem papel: você não pode se esconder atrás do volume ou da revisão. Um argumento ou vale ou não vale, e você se compromete com ele em tinta. Os EWDs são a aparência de um engenheiro que trata a própria escrita como uma ferramenta para pensar com clareza, e a clareza como o objetivo inteiro.
O método
O método é uma única convicção aplicada incansavelmente ao longo de quarenta anos.
Torne-o pequeno o bastante para raciocinar sobre ele. O algoritmo do café, o fluxo de controle estruturado, o sistema THE em camadas, a destilação dos filósofos jantando – cada um é um ato de encolher um problema até uma mente humana conseguir reter o todo dele e verificá-lo. A complexidade que você não consegue examinar é complexidade em que você não pode confiar.
Prove, não teste. O teste amostra; a prova certifica. O cálculo do transformador de predicados de Dijkstra existe para que a prova e o programa sejam derivados juntos, não para que um seja escrito e o outro aparafusado depois. “Compostos corretamente, não apenas depurados até a correção” é o método em cinco palavras.5
Trate a elegância como evidência, não como decoração. Quando uma solução é feia, essa feiura costuma ser um sinal de que o problema não foi compreendido. A elegância “decide entre o sucesso e o fracasso” porque a forma elegante é aquela com o menor número de lugares em que se pode estar errado.3
Escreva para pensar. Os EWDs não eram documentação produzida depois do trabalho. Eles eram o trabalho – raciocínio tornado visível, num meio que punia a enrolação. Projetar sem lápis nem papel e então comprometer o resultado à caneta-tinteiro é a mesma disciplina duas vezes.
Cadeia de influência
Quem o moldou
Sua mãe, a matemática. Dijkstra creditava a ela o seu senso de elegância matemática – o instinto treinado para reconhecer quando uma prova não é apenas válida, mas limpa. Essa distinção, entre um argumento que funciona e um argumento que é belo, tornou-se o eixo de toda a sua carreira. (Influência formativa)
O esforço do Algol 60. Dijkstra coconstruiu um dos primeiros compiladores de Algol 60, e a estrutura de blocos e a recursão da linguagem lhe deram a matéria-prima para a programação estruturada. O Algol foi a prova de que uma linguagem de programação podia ser projetada para a clareza, em vez de acumulada por conveniência. (Influência direta)
A tradição matemática da prova. Formado como matemático e físico antes de a “ciência da computação” existir, Dijkstra importou o padrão da prova por inteiro. Para ele, um programa era um objeto matemático, e a pergunta nunca era “parece funcionar?”, mas “você consegue demonstrar que necessariamente funciona?”. (Influência formativa)
Quem ele moldou
Todo programador que escreve código estruturado. O desaparecimento do goto da programação cotidiana, a universalidade da sequência/seleção/iteração e todo o vocabulário da concorrência – semáforos, deadlock, exclusão mútua – são seu legado operando invisivelmente em toda base de código escrita desde então.
Os métodos formais e a verificação de programas. O cálculo do transformador de predicados e o ideal de correção por construção são os ancestrais diretos da verificação moderna, do model checking e do código que carrega sua própria prova. O atual ressurgimento de software de sistema formalmente verificado é o argumento de Dijkstra finalmente encontrando hardware veloz o bastante para executá-lo.
A autoimagem da disciplina. Mais do que qualquer artefato específico, Dijkstra estabeleceu a ideia de que a programação é um ramo da matemática aplicada digno de rigor – não um ofício a ser aprendido por tentativa e erro. A consciência da área, para o bem e para o mal, ainda fala em sua cadência.
O fio condutor
Dijkstra é a fonte da qual o resto desta série flui. O “bom gosto” de Linus Torvalds – a reescrita em que o caso especial desaparece – é a simplicidade-como-correção de Dijkstra no idioma de um hacker de kernel: menos ramificações significam menos lugares em que se pode estar errado. O núcleo veloz e simples de John Carmack é a mesma subtração mirada no teto do hardware em vez da prova. E a insistência de Andrej Karpathy em reconstruir um sistema do zero para realmente entendê-lo é o “projetar sem lápis nem papel” de Dijkstra usando um chapéu de deep learning. Os quatro discordam de quase tudo, exceto da única coisa que importa: a estrutura elegante não é aplicada por cima da solução correta. Ela é a solução correta. (Ponte da série)
O que eu tiro disto
A frase à qual eu volto é a inversão: a simplicidade é o pré-requisito da confiabilidade, não uma recompensa que você colhe depois de alcançá-la. A maior parte do software lento e frágil não é lenta e frágil porque alguém pulou os testes. É lenta e frágil porque ninguém jamais a tornou pequena o bastante para entender, então ninguém conseguiu raciocinar sobre ela, então a única estratégia de qualidade disponível foi testar até os defeitos visíveis pararem – o que, como disse Dijkstra, não certifica nada. A inversão é o mesmo padrão de a qualidade ser a única variável: a pergunta nunca é “os testes passaram?”, mas “eu entendo isto bem o bastante para saber que está correto?”.
No mundo em que construo agora – agentes de IA, laços de ferramentas, sistemas que geram código mais rápido do que qualquer humano consegue ler –, a advertência de Dijkstra é mais afiada do que jamais foi. Quando um agente escreve mil linhas e os testes estão verdes, é exatamente a situação que ele descreveu: a presença de defeitos não foi mostrada, e a ausência deles não pode ser. O movimento de Dijkstra é recusar deixar a compreensão diminuir conforme a geração aumenta – insistir que o sistema permaneça pequeno o bastante, em camadas o bastante e legível o bastante para que alguém ainda consiga prová-lo correto. A disciplina é a razão pela qual trato a camada de verificação como estrutural mesmo quando nenhum humano lê o código: o teste mostra presença, não ausência, e uma frente de onda de marcas verdes não é uma prova.
Perguntas frequentes
Qual é a filosofia de engenharia de Edsger Dijkstra?
Dijkstra sustentava que a simplicidade é o pré-requisito da confiabilidade: um programa precisa ser simples o bastante para um humano compreendê-lo por completo, porque só um programa compreensível pode ser objeto de raciocínio e provado correto. Ele defendia que os programas deveriam ser “compostos corretamente, não apenas depurados até a correção”, que o teste pode mostrar a presença de defeitos, mas nunca sua ausência, e que a elegância não é decoração, mas “um fator que muitas vezes decide entre o sucesso e o fracasso”. A esperteza, em sua visão, era um vício, porque excedia a capacidade limitada da mente humana.3589
O que Edsger Dijkstra inventou?
Dijkstra inventou o algoritmo de caminho mais curto que leva seu nome (concebido em 1956, publicado em 1959), introduziu o semáforo e as operações P/V para coordenar processos concorrentes, construiu o sistema de multiprogramação THE em camadas, formulou o problema dos filósofos jantando, fez avançar a programação estruturada, originou o conceito de autoestabilização em sistemas distribuídos e desenvolveu o cálculo do transformador de predicados / precondição mais fraca para derivar programas junto com suas provas de correção (em A Discipline of Programming, 1976). Recebeu o Prêmio Turing da ACM em 1972.45
O que significa “Testar mostra a presença, não a ausência de defeitos”?
Significa que um teste só pode demonstrar que um defeito existe, ao acioná-lo – ele nunca pode demonstrar que não existem defeitos, porque nenhum conjunto finito de testes cobre toda entrada possível. Dijkstra o afirmou na Conferência de Engenharia de Software da OTAN de 1969 e deu a forma canônica mais longa em “Notes on Structured Programming”: “O teste de programas pode ser usado para mostrar a presença de defeitos, mas nunca para mostrar sua ausência!” Sua conclusão era que a confiança na correção deve vir da prova e do projeto de programas simples o bastante para se raciocinar sobre eles, não do acúmulo de testes que passam.29
Por que Dijkstra escrevia à mão e distribuía os manuscritos EWD por fotocópia?
Os EWDs eram uma série de mais de mil manuscritos numerados que Dijkstra escreveu ao longo de cerca de quatro décadas, a maioria à mão com caneta-tinteiro, depois fotocopiados e enviados pelo correio a um pequeno círculo que os copiava e repassava adiante. Escrever devagar, à mão, sem uma tecla de desfazer, impunha a mesma disciplina do seu hábito de projetar algoritmos sem lápis nem papel: forçava a clareza e punia a enrolação, porque um argumento comprometido à tinta tinha de de fato valer. A série completa está arquivada e disponível gratuitamente na Universidade do Texas em Austin.610
Fontes
-
“A simplicidade é pré-requisito da confiabilidade” – atribuído a Dijkstra, c. 1975. A frase circula amplamente, mas não aparece literalmente na transcrição do memorando ao qual costuma ser vinculada, “How do we tell truths that might hurt?” (EWD498, 18 de junho de 1975, E.W. Dijkstra Archive, UT Austin). É melhor tratada como um aforismo atribuído; veja Wikiquote: Edsger W. Dijkstra, que cita o EWD498 (1975) como fonte. ↩
-
Edsger W. Dijkstra, comentário na Conferência de Engenharia de Software da OTAN de 1969 (Roma, outubro de 1969), conforme registrado em J.N. Buxton e B. Randell, eds., Software Engineering Techniques (OTAN, abril de 1970), p. 16. A forma curta amplamente citada: “Testar mostra a presença, não a ausência de defeitos.” ↩↩
-
Edsger W. Dijkstra, “Elegance and effective reasoning,” EWD1237, outono de 1996 (E.W. Dijkstra Archive, UT Austin). Texto exato: “elegance is not a dispensable luxury, but a factor that often decides between success and failure.” (Frequentemente parafraseado como “…uma qualidade que decide entre o sucesso e o fracasso.”) ↩↩↩
-
“Edsger W. Dijkstra,” Wikipédia. Nascido em 11 de maio de 1930, Roterdã; morto em 6 de agosto de 2002, Nuenen; a anedota da ocupação “programador” (sua profissão declarada foi rejeitada pelas autoridades em seu casamento de 1957); Centro Matemático, Eindhoven (professor a partir de 1962), pesquisador associado da Burroughs (a partir de 1973) e a Cátedra do Centenário Schlumberger na UT Austin (1984, aposentado em novembro de 1999); o sistema THE, semáforos, autoestabilização, transformadores de predicados e a série EWD escrita à mão e distribuída por fotocópia. ↩↩↩↩↩↩↩↩
-
“Edsger Wybe Dijkstra – A.M. Turing Award Laureate,” ACM (espelho arquivado, já que a página ao vivo bloqueia o acesso automatizado). A justificativa completa de 1972 (“composed correctly, not just debugged into correctness”); a lista de vocabulário (“deadly embrace”, “semaphore”, “go-to-less programming”, “structured programming”); A Discipline of Programming e os transformadores de predicados; a palestra Turing “The Humble Programmer”. ↩↩↩↩↩↩↩
-
Edsger W. Dijkstra, conforme citado na origem por história oral de seu algoritmo de caminho mais curto; veja “Dijkstra’s algorithm,” Wikipédia. A história do café de Amsterdã (“…sentamo-nos no terraço do café… e então projetei o algoritmo do caminho mais curto”), a reflexão do “sem lápis nem papel”, a demonstração do ARMAC de 1956 sobre 64 cidades neerlandesas e a publicação de 1959 “A Note on Two Problems in Connexion with Graphs” na Numerische Mathematik. ↩↩↩↩
-
“Considered harmful,” Wikipédia. A carta de Dijkstra foi submetida ao CACM como “A Case Against the Goto Statement”; o editor Niklaus Wirth mudou o título para “Go To Statement Considered Harmful”, publicado em março de 1968. ↩
-
Edsger W. Dijkstra, “The Humble Programmer,” EWD340, palestra do Prêmio Turing da ACM de 1972 (E.W. Dijkstra Archive, UT Austin). “The competent programmer is fully aware of the strictly limited size of his own skull…” e “…approach the task as Very Humble Programmers.” ↩↩↩
-
Edsger W. Dijkstra, “Notes on Structured Programming,” EWD249, agosto de 1969 (E.W. Dijkstra Archive, UT Austin). “Program testing can be used to show the presence of bugs, but never to show their absence!” – a forma canônica mais longa do aforismo sobre testes. ↩↩↩
-
“E.W. Dijkstra Archive: Home page,” Departamento de Ciência da Computação, Universidade do Texas em Austin. A série EWD completa (numerada até o EWD1318, mais de mil documentos), digitalizada e disponível gratuitamente; o hábito de Dijkstra de escrever manuscritos à mão com caneta-tinteiro e distribuí-los por fotocópia a um pequeno círculo de repasse. ↩↩↩↩