porcellis.com

ref: master

content/blog/sobre-software-duravel.md


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
---
title: "Sobre Software Durável"
date: 2021-03-29
draft: false
tags: ["reflexao"]
---

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][codigo-linux]. Não
previne que [carros "autônomos" atropelem pessoas][uber]. Não previne que haja
brechas de segurança expondo dados de pessoas, seja essa uma [entidade
pública][vazamento-cpf] ou [privada][been-pwned].

[uber]: https://www.nbcnews.com/tech/tech-news/self-driving-uber-car-hit-killed-woman-did-not-recognize-n1079281
[codigo-linux]: https://securityaffairs.co/wordpress/115565/security/linux-kernel-flaws.html
[been-pwned]: https://haveibeenpwned.com/
[vazamento-cpf]: https://g1.globo.com/economia/tecnologia/blog/altieres-rohr/post/2021/01/25/vazamentos-de-dados-expoem-informacoes-de-223-milhoes-de-numeros-de-cpf.ghtml

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][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][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]({{< relref "/porque-eu-uso-vim.md" >}} "Porque eu uso
vim, ou uma reflexão sobre complexidade na tecnologia") 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][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][rfc-irc].

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.

[i3]: https://i3wm.org/
[rfc-irc]: https://tools.ietf.org/html/rfc2812
[weechat]: https://weechat.org/
[minitest]: https://github.com/seattlerb/minitest

[^1]: Inclusive, eu acabei migrando para usar o slack através da integração com
  o weechat, com o plugin do
  [wee-slack](https://github.com/wee-slack/wee-slack), mas eu não vejo a hora de
  um dia não precisar mais usar o slack num geral.