5 pontos por GN⁺ 2025-08-23 | Ainda não há comentários. | Compartilhar no WhatsApp
  • Várias decisões de design da linguagem Go foram tomadas de forma desnecessária ou ignorando experiências já consolidadas
  • O problema de gerenciamento do escopo das variáveis de erro dificulta a legibilidade do código e a identificação de bugs
  • Em vários pontos, como a dualidade do nil, uso de memória e portabilidade do código, aparecem designs pouco intuitivos e desalinhados com a realidade
  • As limitações da instrução defer e a forma como a biblioteca padrão lida com exceções dificultam garantir segurança contra exceções
  • Problemas acumulados, como gestão de memória e tratamento deficiente de UTF-8, estão afetando negativamente a qualidade de codebases em Go no longo prazo

Crítica de longo prazo à linguagem Go

A falta de intuição no escopo das variáveis de erro

  • A sintaxe do Go amplia desnecessariamente o escopo da variável de erro (err), aumentando a possibilidade de falhas
    • No código de exemplo, a variável err permanece viva por toda a função e é reutilizada, o que prejudica a legibilidade e a manutenibilidade do código
    • Desenvolvedores experientes acabam enfrentando mal-entendidos e perda de tempo ao investigar bugs por causa desse problema de escopo
    • A sintaxe não permite limitar adequadamente essas variáveis a um escopo mais local

Duas formas de nil

  • Em Go, existe a confusão de que nil se comporta de forma diferente em tipos interface e tipos ponteiro
    • Como no exemplo abaixo, mesmo que s (ponteiro) e i (interface) recebam nil, s==i pode ser avaliado de forma diferente, mostrando um comportamento inconsistente
    • Isso reproduz um problema que normalmente se quer evitar ao lidar com null, deixando traços de um design feito sem reflexão suficiente

Limites na portabilidade do código

  • O uso de comentários para compilação condicional é claramente ineficiente em termos de manutenção e portabilidade
    • Quem já teve experiência real construindo software portável sabe que essa abordagem é trabalhosa e propensa a erros
    • Experiências históricas acumuladas (portabilidade de código, casos práticos) estão sendo ignoradas
    • Para mais detalhes, veja Go programs are not portable

A falta de clareza sobre a propriedade de append

  • A relação de propriedade entre a função append e slices não é clara, o que dificulta prever o comportamento do código
    • Pelo exemplo, quando uma slice recebe append dentro da função foo, é difícil saber de antemão qual será o impacto real sobre o valor original
    • Os “quirks” da linguagem que é preciso decorar só aumentam, favorecendo erros

Falhas no design da instrução defer

  • Ela não oferece suporte claro à liberação de recursos como no princípio RAII (Resource Acquisition Is Initialization)
    • Em comparação com estruturas de gerenciamento de recursos em Java e Python, em Go não fica claro quais recursos devem ser liberados com defer
    • Como no exemplo com arquivos, até o problema de double-close precisa ser tratado manualmente, e a ordem e a forma corretas de liberação não ficam claras

Tratamento de exceções na biblioteca padrão

  • Go não adota uma estrutura com exceções explícitas (exception), mas situações excepcionais como panic ainda assim acontecem
    • Em alguns casos, panic nem encerra completamente o programa e acaba sendo engolido
    • Existem padrões na biblioteca padrão (fmt.Print, servidor HTTP etc.) que ignoram exceções, o que torna impossível garantir segurança real contra exceções
    • No fim, escrever código seguro contra exceções continua sendo necessário, mas não é possível usar exceções diretamente

Tratamento de UTF-8 e strings

  • Mesmo que se coloque dados binários arbitrários no tipo string, Go continua funcionando sem validação especial
    • É possível enfrentar casos em que nomes de arquivo criados antes da codificação UTF-8 simplesmente desaparecem silenciosamente
    • Isso pode causar perda de dados importantes em backups e reflete uma abordagem simplificada que não considera situações reais de trabalho

Limites da gestão de memória

  • É difícil ter controle direto sobre o uso de RAM, e a confiabilidade do GC (garbage collector) também tem limites
    • O consumo de memória em Go aumenta e, no longo prazo, isso se transforma em custos e problemas de desempenho
    • Em ambientes com múltiplas instâncias e contêineres, problemas reais de custo e escalabilidade acabam surgindo

Conclusão: havia caminhos melhores

  • Mesmo já existindo designs de linguagem comprovadamente eficazes, Go optou por ignorá-los em muitos aspectos
    • Diferentemente dos problemas das primeiras propostas de Java, quando Go foi lançado já existiam abordagens melhores

Materiais de referência

Ainda não há comentários.

Ainda não há comentários.