Pular para o conteúdo

Racional · ensaio 11

Ecossistema e tiers

rationale.md · 88 linhas · 4 min de leitura

A redefinição: estabilidade vem da arquitetura. As camadas (tiers) separam o que muda devagar do que muda rápido, e o eixo é quem é dono da promessa, não a idade.

Toda linguagem grande enfrenta a tensão entre “o core precisa ser estável por décadas” e “as bibliotecas precisam evoluir”. A resposta usual é semver em tudo e torcer para o melhor, o que trata “1.0 1.1” como se a versão garantisse a segurança da mudança, o que é uma meia-verdade.

O ecossistema é organizado em tiers de estabilidade, e o eixo que os separa não é idade nem área. É quão livremente se pode mexer no contrato (e, no limite, quem é dono da promessa):

  • Tier 0, core (a linguagem + a stdlib): os padrões que a engenharia não muda há meio século, como IEEE 754, TCP/IP, UTF-8, o que “lista linkada” significa. É add-only: acrescenta-se, jamais se edita o contrato observável (um bugfix que faz a implementação passar a bater com a promessa já feita é permitido; mudar comportamento de que alguém depende, não). A própria linguagem é o bedrock, e editions são o add-only levado à sintaxe.
  • Tier 1, libs oficiais: o que evolui porque é especificação, não padrão eterno. HTTP teve três versões, TLS gira, um motor de regex troca de algoritmo. Cadência própria (semver/changelog), opt-in, peso zero até o use.
  • Tier 2, frameworks (web, a UI): mais opinião, mais giro.
  • Tier 3, terceiros: a promessa de compatibilidade é de outro, e aqui o eixo vira de natureza.

A regra: tiers só dependem para baixo. E há dois cortes finos que o eixo-tempo esconde:

  • Conjunto fechado vs roster aberto. collections (List/Map/Set) é tier 0 porque é um conjunto completo e fechado: nunca haverá uma “quarta coleção fundamental”. containers (B-tree, ART, deque, ring buffer) é tier 1 porque é um roster que cresce, onde cada algoritmo dentro é frozen (conteúdo tier 0), mas a coletânea muda (tier 1). Mesma idade de algoritmo, tiers diferentes.
  • O tier corta por dentro de um conceito. UTF-8 é frozen (tier 0); as tabelas Unicode, que ganham caracteres todo ano, são tier 1. O relógio UTC/offset é tier 0; os nomes de fuso IANA, que mudam com política de país, são tier 1. A parte mecanismo fica no chão; a parte dado mutável sobe um degrau.

E o modelo de módulos que sustenta isso: mk.mod = lib (caixa reutilizável com deps próprias, nunca compilada sozinha), mk.project = bin/compositor (compõe a árvore, produz o artefato), resolução por MVS (Minimal Version Selection).

A pergunta que o tier responde é uma só: quem promete que isto não vai quebrar, e com que liberdade? Idade correlaciona (o que tem contrato intocável tende a durar décadas), mas é só o sintoma; a régua é o contrato. Por isso o corte prevê decisões que já tinham sido tomadas por instinto (UTC no core, IANA opt-in/heavy): quando o modelo prevê o que você já fez por bom senso, é sinal de que ele é real, não imposto. A imutabilidade do tier 0 é a da promessa, não a do binário: o source conserta uma falha de segurança, a promessa não recua. E quando o incompatível é inevitável, o migration tool (o slow-core com escape mecânico) aplica a correção, em vez de a linguagem se bifurcar.

  • Semver como governo de tudo. Trata a versão como se garantisse a segurança da mudança (“1.1 é breaking-safe”). É meia-verdade. Tier + add-only no core é uma promessa honesta sobre o que pode mudar e quem é dono dela.
  • Tier = idade. “Tier 0 porque é velho” é fraco; um B-tree é tão antigo quanto uma lista e mesmo assim vive no tier 1. O que importa é se o contrato muda.
  • Tudo no mesmo nível de estabilidade (Go cedo, Python 3). Sem tiers, quebras silenciosas em patches, ou uma transição dolorosa quando o tier 0 se bifurca. As camadas isolam o giro.
  • “Maior versão compatível” para resolver deps. O MVS escolhe a mínima que satisfaz, evitando o diamond problem e tornando builds reproduzíveis: você não é arrastado para uma versão nova sem pedir.

O ecossistema Go cedo, antes dos módulos, onde um go get podia quebrar seu build do nada. O Python 2 3, uma migração de tier 0 que rachou a comunidade por uma década. A biblioteca que sobe de 1.4 para 1.5 e quebra você, porque o semver prometeu o que não podia cumprir. Cada uma é a falta de uma arquitetura de estabilidade: todo mundo no mesmo nível, sem dono claro da promessa.

A estabilidade vem da arquitetura: o que muda vive mais acima. O core é add-only (o dono da promessa somos nós, e a promessa não recua); cada degrau acima gira mais rápido, até o terceiro, onde a promessa é de outro.

Add-only significa que o core carrega para sempre o que entrou: uma decisão ruim no tier 0 não se remove, só se contorna por adição (daí a régua de só admitir no core o que é genuinamente fechado e fundamental). E o MVS troca “sempre a última versão” por “a mínima que satisfaz”, reprodutibilidade ao custo de você ter que pedir explicitamente para subir. São os preços de uma estabilidade que é promessa, não torcida.

Próximo: 12 · Nomes honestos