Sobre Software Durável

Traduções disponíveis:

Eu passo no mínimo, 8h do meu dia escrevendo código. Encarando um editor de texto e diversos terminais. Pensando sobre estruturas de dados, pensando sobre como eficientemente armazenar informações e como ensinar meu computador (ou de outros) a fazer coisas que eu não quero fazer manualmente, porque o computador é mais confiável do que eu para fazer essas coisas. Ele pode calcular mais rápido, lembrar coisas por mais tempo, e se comunicar mais rápido com as pessoas do que eu sequer imaginaria fazer, e por isso eu delego essas funções para ele. Mas eu não consigo confiar nele.

Vivemos em uma era em que confiar em um computador é o normal, e é esperado que eu o faça. É esperado que eu os utilize para verificar o saldo da minha conta bancária, para eu conseguir um transporte para algum lugar, ou para que ele me guie até um lugar desconhecido. É esperado que eu informe os meus dados pessoais e confie que ele guarde em algum lugar seguro. Que ele me entregue a velocidade de internet que eu contratei, que os sensores de alarmes detectem um sinal de fumaça e disparem um aviso a respeito, e assim por vai em todas as formas que um computador existe.

A forma mais direta que nós podemos influenciar esses problemas, é escrevendo software para esses diversos computadores. E, escrevendo software todo o dia nos ultimos seis anos, eu fico boquiaberto quando escuto alguém dizer que confia e deseja que esses softwares controlem ou influênciem mais a vida deles. Pessoas que escrevem o código que você usa podem e fazem errors, deixam portas abertas e deixam bugs entrarem. Eu sei, porque eu faço esses errors e trabalho com pessoas que fazem esses errors, todo os dias.

A máxima de “todo software quebra”, é o status quo. E com certeza, mesmo em ambientes onde o controle de software é maior, seja ele por testes automatizados, code review interno e aberto/público, equipe de qualidade, ainda assim bugs entram em produção. Vulnerabilidades são descobertas diariamente em software e códigos que existem por 15 anos. Não previne que carros “autônomos” atropelem pessoas. Não previne que haja brechas de segurança expondo dados de pessoas, seja essa uma entidade pública ou privada.

Eu mantenho essas reflexões para pensar nos meus próprios projetos. Enquanto escrevo software para terceiros, pouco controle tenho eu a respeito das decisões tomadas. Entretanto eu tento incorporar esses pensamentos na minha vida. Eu escolho software durável por razões óbvias; escolho hardware antigo, mas passível de melhorias/upgrades; escolho bibliotecas estáveis ao invés do novo brilho do momento; escolho banco de dados apropriados para o problema a ser resolvido e não o que veio na oferta de emprego ou que está na hype; linguagens tipadas que podem me pré-avisar dos meus erros. Se meu software funciona, e funciona por um bom tempo, tem que existir um ótimo motivo para eu tocar nele.

Mudanças é parte do ciclo de desenvolvimento de software, e deve ser gerenciada com sabedoria. Eu acredito que nenhuma mudança, pode ser muitas vezes a melhor forma de se gerenciar esse ciclo. E que mudança, demanda razão - é necessário um motivo procativo e real, senão apenas se acumula em uma pilha de novos problemas que eles inevitávelmente trazem consigo.

Uma das origens desses problemas, ao meu ver, é a tentativa de encaixar soluções universais em softwares que deveriam serem de um nicho específico. Complexidade cresce exponencialmente quando um determinado projeto não tem um escopo fixo e limitante, não desenha uma linha na areia de quão mais ele vai se expandir e acomodar cada problema e intenção específica de quem o usa.

O i3, o gerenciador de janelas do meu sistema, alcançou um estado de maturidade da qual aparenta estar estagnado em seu desenvolvimento, mas apenas não quer incluir mais funcionalidades, buscando apenas correções de bugs e eventualmente ganhando mais estabilidade e performance. Caso necessário, você pode combinar com outras ferramentas para alcançar um caso de uso específico.

Outro detalhe que eu observo, é a nossa obsessão de resolver problemas triviais com soluções problemáticas e gigantes. Ao invés de optar pelo caminho mais curto e simples, escolhemos o caminho de super complicar a solução necessária, “encurtar caminho”, fazer otimizações desnecessárias e burras.

A linguagem de programação do Ruby tem uma suite de teste, o minitest, que é um exemplo ótimo disso, porque ele é pequeno e simples. A biblioteca não tenta inventar mágica, não tenta ser mais inteligente que o programador que a utiliza. Para utilizar você só precisa conhecer os conceitos básicos da própria linguagem, como classes, metodos e módulos. Ele só faz o que ele foi feito pra fazer, da forma mais simples e desobstruente possível. Não possui uma DSL, tampouco um ramo diverso de coisas pré-prontas.

Meu editor de texto, vim se comporta da mesma forma há pelo menos uma década, outras derivações do projeto mantem o mesmo comportamento padrão, o que significa que eu posso entrar em qualquer máquina e sei como utilizar. Afinal, tudo o que precisa fazer é mostrar e editar texto numa tela e se eu precisar de algo fora da curva, eu posso customizar da forma que eu achar melhor.

O weechat, o cliente que eu uso para conversar com meus amigos 1 no IRC há pelo menos três anos, funciona perfeitamente, enquanto isso o aplicativo oficial do slack que eu preciso utilizar para conversar com meus colegas do trabalho não consegue passar mais de 1h sem apresentar algum travamento, lag ou consumir boa parte da memória do meu computador, mesmo que o único trabalho dele, na teoria é enviar e receber mensagens em tempo real, um problema solucionado há pelo menos 30 anos.

Então eu escolho software durável: estável, simples, auditável e performático. Mesmo que isso signifique sacrificar funcionalidades ou ser mais “feio”, ou ser mais limitado e precisar combinar outras soluções externas. E incorporar isso na minha vida, enquanto programador, significa olhar sempre com um olhar mais crítico para o que se apresenta como soluções únicas e universais, que brilha demais e se apresenta como soluções “fáceis”, tentando sempre entender o valor de troca, que em geral significa sacrificar estabilidade e performance aos custos de gerar um aumento de manutenção e complexidade.


  1. Inclusive, eu acabei migrando para usar o slack através da integração com o weechat, com o plugin do wee-slack, mas eu não vejo a hora de um dia não precisar mais usar o slack num geral. ↩︎