$ portaldoshell

carreira · 6 min de leitura # menos que a reunião que podia ter sido um e-mail

Escrever código ficou barato, e quem lê ficou caro

Aprovar sem ler é o jeito mais rápido de virar coautor de um defeito.

$ whoami
Julio Cezar Neves

Num escritório moderno, uma senhora de cabelos brancos curtos, óculos de leitura, blusa clara e lenço estampado no pescoço, sentada numa poltrona, circula com caneta vermelha um único ponto minúsculo numa folha de papel, com ar satisfeito. Atrás dela, uma impressora enorme despeja uma montanha de folhas que soterra até o peito três colegas jovens de fones de ouvido, que comemoram aos gritos com os punhos erguidos.

Escrever código ficou barato nesta década, e ler código virou a habilidade mais cara da profissão. A semana trouxe duas provas disso, as duas vindas de projetos que tratam qualidade como assunto sério. Quem ainda mede a própria carreira pela quantidade de linhas que produz está contando uma moeda que acabou de perder valor no câmbio.

A primeira prova veio do kernel. O LWN registrou nesta quarta-feira a primeira série de patches que Linus Torvalds preparou com o auxílio de um modelo de linguagem, conforme ele mesmo havia contado no encontro anual dos mantenedores. São dez patches que mudam a forma como o kernel procura páginas de arquivo na memória, e um teste carregado de chamadas read() ficou cerca de dez vezes mais rápido. A revisão, fiel à tradição da casa, já encontrou uma condição de corrida no código.

A segunda prova chegou do PostgreSQL. Peter Eisentraut, da equipe central do projeto, escreveu na semana passada um texto comentado pelo LWN em que explica por que o beta da versão 19 viu um número incomumente alto de funcionalidades revertidas. Parte da explicação está na revisão de código assistida por LLMs, que passou a encontrar defeitos muito mais depressa. Segundo ele, quase todo o código revertido foi escrito há bastante tempo, quando ninguém ainda pedia programa a uma máquina.

Repare no desenho das duas histórias. Num caso, a máquina ajudou a escrever, e quem leu com atenção já achou um problema. No outro, gente competente escreveu tudo à mão anos atrás, e a máquina ajudou a ler. Defeito antigo tem uma qualidade admirável, porque espera anos, sem reclamar, a chegada de alguém disposto a ler com cuidado. Em ambos os casos, o trabalho que decidiu o destino do código aconteceu depois da escrita.

Estou na computação desde 1969 e já vi a escrita de programas ficar mais fácil muitas vezes. Cada linguagem nova prometia que agora qualquer um escreveria software, e a promessa costumava se cumprir. O que mudava pouco era a outra ponta, a de entender o que o programa faz quando dois eventos acontecem ao mesmo tempo ou quando a entrada chega torta. Essa ponta continua cobrando o mesmo preço de sempre, e agora a conta chega mais cedo.

A condição de corrida, aliás, merece um exemplo, porque ela é o defeito preferido de quem lê com pressa. Pense num script de backup agendado no cron que precisa evitar duas execuções simultâneas. A versão que mais aparece por aí confere se existe um arquivo de trava e, se ele faltar, cria o arquivo e segue em frente:

if [ ! -e /tmp/backup.lock ]; then
  touch /tmp/backup.lock
  echo "$$ entrou"
  sleep 1
  rm /tmp/backup.lock
fi

Quem lê esse trecho de cima para baixo enxerga uma lógica impecável. Quem lê pensando em dois processos enxerga um intervalo entre o teste e o touch, e nesse intervalo cabe outro script inteiro. Disparei duas cópias ao mesmo tempo, vinte vezes seguidas, no Bash 5.2.21. As duas entraram nas vinte rodadas, e em todas uma delas ainda reclamou ao apagar uma trava que a outra já tinha removido. Condição de corrida tem um talento raro, porque some sempre que o autor testa o script sozinho, com um processo só e a melhor das intenções.

A correção cabe na mesma quantidade de linhas e troca o teste seguido de ação por uma operação única. O mkdir cria o diretório ou falha, num só passo, e o sistema operacional garante que apenas um dos concorrentes vence:

if mkdir /tmp/backup.lock 2>/dev/null; then
  trap 'rmdir /tmp/backup.lock' EXIT
  echo "$$ entrou"
  sleep 1
else
  echo "$$ achou outro backup rodando" >&2
  exit 1
fi

Rodei as mesmas vinte rodadas com duas cópias simultâneas, e em todas exatamente um processo entrou enquanto o outro avisou que havia backup em andamento. O trap cuida de remover a trava quando o script termina, inclusive se ele sair antes da hora por causa de um erro. As duas versões passam em qualquer teste feito por uma pessoa só diante do terminal. A diferença entre elas aparece apenas para quem lê o código imaginando o que pode acontecer em paralelo.

Esse tipo de leitura se aprende, e aprende-se devagar. Ela exige saber o que o mkdir e o trap prometem ao sistema, e exige também a desconfiança treinada de quem já viu script bonito derrubar servidor. Uma ferramenta capaz de gerar as duas versões em segundos entrega a mesma confiança nas duas, e cabe a alguém da equipe saber qual delas vai para produção.

O ponto pesa diretamente sobre quem pensa em carreira. Durante muito tempo, o profissional júnior aprendia escrevendo e ouvindo o veterano apontar o erro na revisão. A escrita agora sai pronta e com boa aparência, e o júnior que só aprendeu a pedir código chega à revisão sem o repertório para avaliá-lo. Aprovar sem ler é o jeito mais rápido de virar coautor de um defeito, e o nome no commit fica lá para sempre.

Ler código de outra pessoa incomoda, e por isso tanta gente empurra a tarefa para o fim da fila. Esse código segue uma lógica que ainda precisamos reconstruir e esconde hipóteses que o autor achou óbvias. Ler o próprio código depois de seis meses traz o mesmo incômodo, com o agravante de reconhecer a letra. A boa notícia é que esse músculo cresce com uso, e o terminal oferece material gratuito em quantidade para o exercício.

Os scripts do próprio sistema servem de academia. Abrir com calma um hook do Git ou um instalador baixado da internet ensina mais sobre Shell que muitas horas de vídeo. O man bash também entra nessa conta, porque ler a documentação do interpretador é ler a especificação do que o código promete. Quem lê o manual entende por que o mkdir resolve o que o [ sozinho deixa escapar.

O kernel, que costuma enxergar essas coisas antes do resto do mundo, resolveu a questão há muito tempo com duas linhas no rodapé de cada patch. A documentação de envio de patches explica que o Signed-off-by: certifica quem participou do desenvolvimento, e que o Reviewed-by: declara que alguém fez uma revisão técnica e considerou a mudança aceitável. O revisor assina com o próprio nome, e essa assinatura fica gravada no histórico do projeto ao lado da do autor.

Essa segunda linha vai valorizar bastante nos próximos anos. Qualquer pessoa com acesso a um modelo de linguagem consegue produzir um Signed-off-by: por semana, e poucas conseguem merecer um Reviewed-by: que os mantenedores levem a sério. Se eu tivesse vinte anos e quisesse construir reputação em software livre, passaria um bom tempo lendo patches dos outros antes de mandar os meus. A escrita continua necessária, e cada patch gerado em segundos agora entra numa fila que espera, sem pressa nenhuma, alguém capaz de lê-lo.

PS: Conte nos comentários qual defeito você só enxergou na segunda leitura, depois de jurar na primeira que estava tudo certo, e encaminhe o texto ao colega que aprova pull request pelo celular durante a reunião. Ele vai ler na diagonal, como de costume, e garantir que leu com atenção.

$ tee # compartilhe este artigo WhatsApp Telegram LinkedIn

$ cat comentarios.log

lendo o log…

$ ./comentar.sh --artigo quem-le-o-codigo

* obrigatório. Todo comentário passa pelo root antes de entrar no log, e o root daqui é humano.

$ cd ~