O Claude fez meu compilador em 3 minutos. E isso deveria me preocupar?
Eu passei semanas construindo o BrainJuck. Um compilador de Brainfuck pra JVM, escrito na mão, em Node.js, sem dependência nenhuma. Semanas lendo hex dump, brigando com a StackMapTable, calculando offset de jump errado às duas da manhã. Eu já escrevi sobre isso.
Ontem eu abri o Claude Code e mandei um prompt. Um prompt só. Sem ir e voltar, sem corrigir, sem guiar. Colei e fui fazer café:
create a compiler from Brainfuck to JVM in Node.js with no dependencies. Full Node.js.
the interface should be ./compiler somefile.bf SomeFile
i should be able to run SomeFile just by running "java SomeFile"
every brainfuck command should be accepted and the produced .class must not have a warning.
You must test everything, from the parser to the generation of the .class.
Quando voltei, três minutos depois, o compilador estava pronto. 51 testes passando, .class válido, Hello World rodando sem um warning no stderr. Um prompt. Três minutos.
Minha primeira reação foi rir. A segunda foi ficar quieto.
O que ele gerou
O compilador do Claude é um arquivo só, ~300 linhas. Parser, constant pool, geração de bytecode, StackMapTable, montagem do .class - tudo junto. Funciona. Os oito comandos do Brainfuck compilam corretamente pra bytecode JVM. Os loops geram ifeq/goto com offsets corretos. O append_frame na StackMapTable declara as variáveis locais certas. O javap -v mostra uma classe válida.
A suíte de testes é decente: testa o parser isolado, o constant pool, a geração de bytecode, a StackMapTable, a estrutura do .class, e faz 19 testes de integração que compilam Brainfuck, rodam com java, e verificam a saída. Hello World, loops aninhados, input, wrapping de célula, todos os 8 comandos juntos.
Funciona. Sem truque, sem gambiarra. Ele até acertou o append_frame de primeira - ok, na segunda tentativa. Na primeira ele usou same_frame e tomou um VerifyError, igual aconteceu comigo. Mas corrigiu sozinho em segundos.
Onde o meu é melhor
O BrainJuck não é só um compilador que funciona. Ele é um compilador que pensa.
O parser do Claude pega +++ e gera três iadd separados. O meu parser combina em um increment(3) e gera um sipush 3 + iadd. Menos bytecode, menos trabalho pra JVM.
O BrainJuck tem uma camada de IR entre o parsing e a geração de código. Isso significa que eu posso adicionar otimizações sem mexer no gerador de bytecode. O Claude foi direto do parsing pro bytecode - funciona, mas é rígido.
O meu rastreia a posição do ponteiro em tempo de compilação. >>><< vira move_head(1) com posição absoluta. O do Claude gera cinco iinc separados. De novo - funciona, mas é ingênuo.
A arquitetura tem separação real: index.js pro parser, class_generator.js pra montagem do .class, helpers/jvm.js pros opcodes. O do Claude enfiou tudo num arquivo. Pra 300 linhas até que dá. Pra evoluir, não dá.
Onde o dele é melhor
A cobertura de testes. Tenho que admitir.
Eu tenho 6 testes unitários e 1 teste de integração. O Claude gerou 51 testes cobrindo cada camada individualmente. Testa edge cases que eu nem pensei - loop vazio [], loops consecutivos [][], wrapping de célula, programa vazio.
Meu teste de integração é sólido - compila o Hello World, roda com java, verifica stdout e stderr. Mas é um cenário só. O Claude testou 19 cenários diferentes de integração.
O que realmente importa
Aqui é onde a coisa fica honesta.
O compilador do Claude funciona. Se alguém me pedisse “preciso de um compilador de Brainfuck pra JVM até amanhã” e eu usasse o Claude, o trabalho estaria entregue. Ninguém olharia pro .class gerado e saberia que foi feito em 3 minutos.
Mas eu não saberia nada.
Eu não saberia que o constant pool é 1-indexed e que a entrada 0 não existe. Não saberia que baload faz sign-extend pra int. Não saberia que o slot 0 das variáveis locais é reservado pros argumentos do método. Não saberia que o offset_delta da StackMapTable é calculado em relação ao frame anterior, não ao início do método. Não saberia a diferença entre same_frame e append_frame, nem por que o primeiro frame de um método com branches precisa ser append_frame se você declarou variáveis locais depois da assinatura.
Nada disso. Minha cabeça estaria vazia.
Quando eu estava debugando o BrainJuck às duas da manhã, comparando hex dump com a spec da JVM, errando cálculo de offset pela décima vez - aquilo era conhecimento entrando. Cada VerifyError era uma lição. Cada byte errado no hex dump que eu encontrava era uma conexão nova no meu cérebro.
O Claude não precisou debugar nada disso. Ele já sabia. Ele foi treinado com a spec da JVM, com milhares de implementações parecidas, com décadas de conhecimento acumulado. Pra ele, gerar uma StackMapTable correta é interpolação. Pra mim, foi o chefe de fase do projeto.
Não é sobre a IA ser ruim
Eu uso IA pra programar. Uso Claude Code praticamente todo dia. Não sou contra, não acho que vai destruir a profissão, não tenho medo de perder o emprego. Que fique claro.
Mas tem uma diferença entre usar a IA pra acelerar um trabalho que você entende e usar a IA pra fazer um trabalho que você não entende. No primeiro caso, você ganha tempo. No segundo, você ganha uma ilusão.
O BrainJuck demorou semanas. O compilador do Claude demorou 3 minutos. O resultado final é parecido - os dois geram .class válido, os dois compilam Hello World, os dois passam no verificador da JVM. Mas depois daquelas semanas, eu sei como a JVM funciona por dentro. Sei ler bytecode, sei o que um VerifyError significa, sei dissecar um .class com xxd. Essas semanas me deram algo que nenhum prompt dá.
O compilador do Claude é melhor testado que o meu. É mais rápido de produzir. Se eu quisesse, eu poderia pegar o código dele e melhorar - adicionar as otimizações que o meu tem, separar em módulos, evoluir a arquitetura.
Mas eu nunca teria a base pra fazer isso se não tivesse passado por aquelas semanas primeiro.
O teste real
Se eu te der o compilador do Claude e pedir pra você adicionar uma otimização - combinar [-] num clear cell direto no bytecode - você conseguiria? Se aparecer um VerifyError novo, você saberia por onde começar?
Se você construiu o seu, a resposta é sim. Se a IA construiu pra você, a resposta honesta é provavelmente não.
Esse é o ponto. Não é que a IA faz código ruim. O código é bom. É que código bom que você não entende é tão útil quanto código ruim que você não entende. Nos dois casos, quando quebrar, você tá perdido.
Pra quem tá aprendendo
Se você é dev e quer entender compiladores, máquinas virtuais, bytecode - faz na mão. Pelo menos uma vez. Não precisa ser Brainfuck, não precisa ser JVM. Pega qualquer linguagem simples e compila pra qualquer target. O importante é passar pelo processo.
Depois que você entendeu, aí sim - usa a IA pra ir mais rápido, pra testar mais cenários, pra explorar variações. A IA é uma ferramenta absurda quando você sabe o que tá fazendo. Quando você não sabe, ela é só um gerador de confiança falsa.
O BrainJuck tá no GitHub. Lê o código, brinque, quebre. E se der vontade, faz o seu.
Por hoje é só. Abraços.