Muito do que aprendemos na prática de engenharia de software nos últimos 30 anos é da forma "a tecnologia X pode acelerar o desenvolvimento inicial de novo software, mas se você não gastar tanto ou mais tempo pensando em como e Quando usá-lo como você salvou, a longo prazo, transformará seu aplicativo em um pântano de dívida técnica, custando a você ordens de magnitude mais tempo e esforço em manutenção ".
As tecnologias que se enquadram nessa ferramenta incluem: linguagem assembly codificada manualmente, compiladores, intérpretes, bibliotecas de procedimentos, programação imperativa, programação funcional, programação orientada a objetos, alocação manual de memória, coleta de lixo, tipos estáticos, tipos dinâmicos, escopo lexical, escopo dinâmico , ponteiros "seguros", ponteiros "inseguros", ausência de ponteiros como conceito de linguagem, formatos de arquivos binários, formatos de arquivos de marcação estruturada, macros, modelos, evitação de macros e modelos, memória compartilhada, passagem de mensagens, threads, corotinas, loops de eventos assíncronos, serviços remotos centralizados, serviços distribuídos, software instalado localmente, matrizes, listas vinculadas, tabelas de hash e árvores.
O fato de muitos dos itens da lista acima aparecerem em grupos que, juntos, esgotam o espaço conhecido da solução é muito intencional e deve, por si só, lhe dizer uma coisa. Pode-se argumentar que a única inequívoca, todo-o-board melhorias na práxis que tivemos desde que primeiro acendeu a Z3 são bloco estruturado de programação (em oposição ao código espaguete) e proteção de memória (menino, eu já não falta os dias em que um erro de digitação pode derrubar meu computador inteiro).