Menos 2.000 linhas de código
(folklore.org)- No início de 1982, a equipe de software do Lisa estava sob pressão para lançar o produto em seis meses e tentou medir o progresso pelo número de linhas de código semanais por engenheiro
- Bill Atkinson considerava que a contagem de linhas não mostrava corretamente a produtividade e também entrava em conflito com o objetivo de criar programas pequenos e rápidos
- Ao reescrever o mecanismo de cálculo de regiões do QuickDraw com um algoritmo mais simples e geral, as operações de região ficaram quase 6 vezes mais rápidas e o código foi reduzido em cerca de 2.000 linhas
- No primeiro formulário gerencial, no campo que perguntava quantas linhas de código ele havia escrito naquela semana, Bill escreveu
-2000, expondo diretamente a falha desse método de medição - Algumas semanas depois, os gerentes deixaram de exigir esse formulário de Bill, e o episódio mostra como a gestão baseada em linhas de código pode deixar passar melhorias reais
Medição por linhas de código na equipe do Lisa
- No início de 1982, a equipe de software do Lisa queria acelerar o ritmo de trabalho para lançar o software nos seis meses seguintes
- Alguns gerentes tentaram acompanhar o progresso pelo número de linhas de código escritas por cada engenheiro a cada semana
- Os engenheiros receberam um formulário para entregar toda sexta-feira, e nele havia um campo para informar quantas linhas de código haviam sido escritas naquela semana
O -2000 de Bill Atkinson
- Bill Atkinson, autor do QuickDraw e principal designer de interface do usuário, desempenhava um papel importante na implementação do Lisa
- Bill achava que a métrica de linhas de código não media corretamente a produtividade
- Ele acreditava que o objetivo de um bom software era escrever programas o menor e mais rápidos possível
- Uma métrica que incentiva aumentar o número de linhas pode estimular a escrita de código desleixado, inchado e quebrado
- Na época, ele estava otimizando o mecanismo de cálculo de regiões do QuickDraw
- Reescreveu completamente o mecanismo de regiões com um algoritmo mais simples e geral
- Depois do ajuste, as operações de região ficaram quase 6 vezes mais rápidas
- Ao mesmo tempo, o código foi reduzido em cerca de 2.000 linhas
- Ao preencher o primeiro formulário gerencial, olhou por um instante para o campo de linhas de código e escreveu
-2000 - Não se sabe ao certo como os gerentes reagiram, mas algumas semanas depois deixaram de exigir que Bill enviasse o formulário
1 comentários
Opiniões no Hacker News
Isso me lembra o caso do conflito sobre número de linhas de código entre a Microsoft e a IBM
Na série de TV da PBS baseada em Accidental Empires, de Bob Cringely, há uma cena em que Steve Ballmer descreve a experiência de desenvolver o OS/2 em conjunto com a IBM
A Microsoft tinha uma atitude de empresa pequena, focada em fazer o trabalho acontecer, enquanto a IBM se concentrava em métricas internas, especialmente em medir a produtividade dos programadores em KLoC (mil linhas de código)
Ballmer disse que “eles só se importavam com KLoC, KLoC e mais KLoC”, e parece que a IBM olhava mais para a quantidade de código do que para sua qualidade
https://ubiquity.acm.org/article.cfm?id=1022357
Quem conhecia a situação recebeu aquela “comemoração” como se fosse um funeral
Contar linhas de código como métrica de produtividade é realmente uma tolice
Já corrigi com uma única linha de código um bug de 20 anos que ninguém conseguia resolver, e lembro de ter resolvido um bug de 3 anos com um simples
order by. Como medir o impacto de uma única linha de código? Pela minha experiência, programadores ruins escrevem muito mais códigoTambém não dá para esquecer a história[1] de um desenvolvedor da Microsoft que reescreveu um código da IBM de 33 mil caracteres e o reduziu para 220. Como resultado, o volume de trabalho da Microsoft ficou “negativo”, e dizem que isso causou uma guerra
[1] https://archive.org/details/bigbluesunmaking00carr/page/4/mode/2up página 101
Um exemplo atual são empresas que usam “impacto”, isto é, lançar novos produtos, como critério para promoção. Isso facilita o surgimento de um monte de produtos fracassados que ninguém mantém
Entre grandes cientistas da computação e engenheiros, há pessoas que tiveram uma produção enorme de código, e acredito que isso se converte diretamente em impacto de alguma forma. O problema é quando o número de linhas de código se torna a métrica de desempenho
Aí se aplica a lei de Goodhart: “quando uma medida se torna uma meta, ela deixa de ser uma boa medida”
Do ponto de vista de métricas de produtividade, o código é classificado como ativo; mas uma visão mais próxima da realidade é que a funcionalidade é o ativo, e o código em si é a dívida
Este tema aparece com frequência. Discussões anteriores incluem:
https://news.ycombinator.com/item?id=33483165 (2022)
https://news.ycombinator.com/item?id=26387179 (2021)
https://news.ycombinator.com/item?id=10734815 (2015)
https://news.ycombinator.com/item?id=7516671 (2014)
https://news.ycombinator.com/item?id=4040082 (2012)
https://news.ycombinator.com/item?id=1114223 (2010)
https://news.ycombinator.com/item?id=1545452 (2010)
No início da minha carreira, otimizei um programa em C com mais de 10 mil linhas que eu havia herdado, reduzindo-o para menos de 500 linhas. Era um programa em C que fazia chamadas SQL a um banco de dados Sybase
Não foi por algum grande insight, mas por uma suposição simples: era possível que meu antecessor não soubesse usar funções nem parâmetros para inserir dados variáveis em consultas SQL. De fato, a mesma instrução SQL aparecia inline várias vezes, mudando apenas alguns valores
Reescrevi o código das chamadas SQL como chamadas de função e passei as variáveis de bind como parâmetros da função. O código inline repetido foi substituído por um loop que pegava os valores de bind variáveis de um array e chamava a função
O maior impacto às vezes vem de fazer uma pergunta simples como “Como vamos lidar com X?”, impedindo que algo sequer seja construído
Se aquilo nem teria tido a chance de funcionar direito, você economizou o custo total de tentar construí-lo
Esse tipo de coisa não só é impossível de medir com métricas numéricas, como também cria inimigos. Mesmo assim, aplaudo quem tem coragem de fazer isso
Pessoas que veem programação como algo parecido com digitação rápida mostram um paralelo interessante com LLMs. Escrevem todo o código mal pensado, apagam, depois escrevem de novo e apagam de novo
Cerca de metade das solicitações de informação que chegavam ao departamento eram sempre do tipo “é muito importante, precisamos disso agora, e pode render ou economizar muito dinheiro”, mas a resposta óbvia era: “Calculem com as informações que já têm. Vocês têm calculadora e planilha. Querem um lápis?”
É melhor evitar do que fazer o sistema lidar com X. Um caso especial que talvez seja usado uma ou duas vezes infla o sistema, e ninguém sabe que esse caso especial ou programa existe, nem o que ele realmente faz. Mesmo quando a documentação é boa, ninguém gasta tempo aprendendo o que é possível. Por isso, a maioria desses recursos especiais acaba sendo, na prática, desperdício de tempo
Como experimento mental correspondente, dá para pensar na situação oposta. Se um gestor ler este texto e decidir medir simplesmente pelo número de linhas de código removidas, isso melhoraria ou pioraria as coisas?
Esse tipo de medição é quase inútil, no geral, a menos que haja práticas sólidas de revisão de código. Ao contrário do que as pessoas aqui querem acreditar, essas práticas são raras. Mas, se houver boas revisões, elas também pegam baixa performance ou manipulação de métricas, então há menos motivo para introduzir esse tipo de métrica desde o início
Por exemplo, há a velha ideia de eliminar engenheiros de software e todo aquele texto de código obscuro, substituindo-os por gerentes de produto que desenham diagramas ou fluxogramas especiais para gerar resultados “low-code” ou “no-code”
Eu contaria linhas adicionadas e removidas separadamente, de modo que um patch
+50,-150seria calculado como 200 ΔSLOCIsso não é uma boa medida de produtividade, especialmente sozinha. Ainda assim, é uma métrica razoável de conta de guardanapo para estimar aproximadamente o volume de mudanças. Se um desenvolvedor com ΔSLOC alto é mais produtivo do que um colega que fica 1 ou 2 semanas sem nenhum ΔSLOC depende do que esse colega está fazendo, mas é certo que, durante o período medido, o primeiro está alterando mais a base de código
Se o produto estiver “pronto”, talvez fique igual ou até melhor. Caso contrário, mudanças negativas no número de linhas de código não chegariam à produção
Mas a maioria dos produtos continua evoluindo. É por isso que podemos permanecer anos no mesmo projeto, e contribuições que apenas removem coisas acabam não acrescentando nada
A história real é que, quando se começa um projeto, às vezes não se sabe exatamente para onde ele vai
À medida que se avança, entende-se muito melhor o problema e a resposta desejada, e então é possível arrancar grandes blocos e substituí-los por algo menor e melhor
E não se deve esquecer que essas pessoas precisavam colocar tudo dentro de uma ROM de 64 KB, incluindo
-2000linhas de código, e até código assembly. A pressão para tornar tudo menor era enormeTambém não está claro se ele ficava de fato na ROM ou no disquete de boot. Além disso, segundo a Wikipedia, a ROM do Lisa tinha 16 KB
[1] https://computerhistory.org/blog/the-lisa-apples-most-influential-failure/
[2] https://computerhistory.org/blog/macpaint-and-quickdraw-source-code/
É o Bill Atkinson, famoso pelo Atkinson Dither. https://beyondloom.com/blog/dither.html
Nesse processo, ele precisou continuar inventando novas formas de a interface de usuário funcionar e maneiras de escrever software para resolver isso. Ele otimizava ao mesmo tempo para “rodar rápido no hardware do Mac” e “oferecer uma ótima experiência de usuário”, e essa sinergia deixou sua marca em toda a estética dos antigos Macs em preto e branco. Aquele estilo de dithering também é outro exemplo da combinação de genialidade algorítmica com senso estético.
Esse senso também aparece em coisas como a borda de seleção “marching ants” (https://en.wikipedia.org/wiki/Marching_ants). O mesmo vale para muito do feedback da UI clássica do Mac ter sido expresso por inversão de pixels. É o caso da seleção de texto, do destaque de menus, da forma como um botão aparece enquanto o botão do mouse está pressionado, das linhas de contorno ao arrastar uma janela etc.; desenhar por cima em modo XOR era uma maneira muito boa de criar esses efeitos.
A forma como essas ferramentas foram combinadas no QuickDraw levou a famosa conversa sobre retângulos arredondados com Steve Jobs (https://www.folklore.org/Round_Rects_Are_Everywhere.html) a resultar, na prática, em tornar tão fácil desenhar retângulos arredondados no QuickDraw quanto retângulos comuns, fazendo com que eles aparecessem por todo o sistema operacional.
O sucesso da UI do Mac não foi apenas por ela ser bonita. Em grande parte, foi porque Bill Atkinson criou um conjunto pequeno e inteligente de ferramentas que tornava fácil criar coisas bonitas.
Os excelentes ícones de Susan Kare também não teriam sido lembrados com tanto carinho se Bill não tivesse criado ferramentas que facilitavam inserir bitmaps de máscara de 32x32 pixels na UI e invertê-los ao clicar.
A lição é que, mesmo sendo tão inteligente quanto Einstein, no fim você é funcionário, e precisa fazer o que deve fazer como funcionário.
Nunca entendi por que, quando as pessoas falam do número de linhas de código escritas, sempre calculam como “linhas adicionadas - linhas removidas”.
Só porque eu fiz uma corrida de 10 km e voltei ao ponto de partida não quer dizer que corri 0 km.
Por exemplo, transformar algo no formato
if cond { ... return; } ...emif cond { ... return; } else { .... }.Ainda assim, essa explicação não cobre tudo.