Como Está Indo Nossa Reescrita de Rust para Zig
Um texto longo sobre a reescrita do compilador da linguagem Roc de Rust para Zig levou a uma análise mais ampla das compensações entre segurança, desempenho e tooling em linguagens de sistemas. Os comentaristas contrastam as fortes garantias estáticas e o ecossistema maduro do Rust com os builds incrementais extremamente rápidos do Zig, o controle fino de memória e a instabilidade pré-1.0, debatendo se adicionar borrow checking no estilo Rust ao Zig é sequer viável. O thread também aprofunda quanto “memory safety” compiladores e runtimes podem realisticamente fornecer, o papel de garbage collection e schedulers em linguagens como Go, e quando é justificável aceitar mais código unsafe em troca de desempenho ou ergonomia.
Rust vs Zig para implementação de compiladores
- Muitos concordam que os builds incrementais do Zig (por exemplo, reconstruções de ~35 ms) são um grande atrativo para trabalho em compiladores; Rust é visto como mais lento, mas em melhora, com um roadmap oficial para builds mais rápidos.
- Alguns observam que, no compilador Roc atual, builds completos ainda podem ser mais lentos em Zig do que em Rust; outros enfatizam que a arquitetura do Zig é otimizada para desempenho futuro.
- Vários argumentam que a escolha da linguagem importa menos do que algoritmos e estruturas de dados, embora outros contestem que o controle de baixo nível sobre memória/layout pode gerar ganhos de uma ordem de grandeza uma vez que os algoritmos estejam fixos.
Segurança de memória, unsafe e borrow checking
- Debate acalorado sobre se adicionar um borrow checker no estilo Rust ao Zig (via análise estática ou ferramentas de IR) é viável:
- Um lado: “impossível” ou muito pouco ergonômico sem design de linguagem ciente de lifetimes, traits, encapsulamento e expressividade restrita.
- Outro lado: cita ferramentas, analisadores customizados e exemplos (Ada/SPARK, projetos tipo Oxide) como evidência de que segurança extra pode ser “acoplada”, embora com custo e falsos positivos.
- Discussão sobre limites fundamentais: análise de aliasing e de segurança temporal torna-se indecidível em geral; Rust resolve isso restringindo a expressividade (ownership afim/linear).
- O modo ReleaseSafe do Zig e allocators de debug fornecem checks de limites, detecção de vazamentos, double-free / alguma detecção de UaF usando endereços não reutilizados, mas não segurança temporal სრული.
- Muitos enfatizam que “memory safe” em Rust é uma garantia específica e limitada; Rust seguro ainda pode ser compilado incorretamente ou ser inseguro por bugs no compilador (por exemplo, CVEs teóricos).
O que “segurança” significa e onde os compiladores entram
- Longo subthread distinguindo:
- Segurança de memória (objetiva, formalizável).
- “Segurança” mais ampla (dependente do contexto: segurança, correção, segurança humana).
- Alguns argumentam que segurança é uma propriedade do sistema, não da linguagem; um compilador seguro ainda pode emitir binários vulneráveis.
- Outros respondem que garantias no nível de componente ainda são valiosas: reduzir a superfície unsafe torna depuração, sandboxing e limites de confiança mais manejáveis.
- Debate sobre se compiladores são “sensíveis à segurança”:
- Uma visão: compiladores não são endurecidos contra entradas maliciosas (por exemplo, o modelo declarado do LLVM); UB em compiladores é “apenas mais um bug.”
- Visão oposta: compiladores são raízes de confiança críticas; explorações de memória neles podem injetar código em todos os binários downstream.
Runtime e escalonamento do Go
- Um comentarista afirma que o scheduler do Go é “o mais sofisticado do mundo” e pode superar Rust em throughput ao trocar memória por concorrência.
- Várias respostas contestam isso como exagerado e inconsistente com experiência e benchmarks, apontando para sistemas de alto desempenho que acabam otimizando memória manualmente de qualquer forma.
- Outros observam runtimes concorrentes (JVM, CLR, Erlang) e que a teoria de escalonamento é profunda; a afirmação é tratada amplamente como sem sustentação.
Tempos de build, caches e tooling
- Builds lentos do Rust e grandes diretórios de artefatos são uma reclamação recorrente; alguns projetos veem builds incrementais de vários minutos devido ao uso pesado de genéricos e macros/codegen (por exemplo, alguns stacks GraphQL).
- Sugestões:
- Usar diretórios de target compartilhados/globais e ferramentas como sccache.
- A equipe do Cargo está redesenhando o layout dos artefatos para permitir garbage collection e melhor gerenciamento de cache.
- A equipe do Zig explica que, para edições pequenas, o custo do rebuild incremental é dominado pela travessia do grafo de dependências e pela detecção de mudanças, não pelo codegen, então o desempenho deve ser semelhante entre arquiteturas.
Maturidade do Zig, breaking changes e “pronto para produção”
- Tensão em torno do status pré-1.0 do Zig:
- Defensores: ele está “pronto para produção” na prática; o rótulo pré-1.0 principalmente preserva a liberdade de fazer breaking changes frequentes. Usuários de produção bem-sucedidos são citados.
- Críticos: mudanças core frequentes e quebradoras (por exemplo, APIs de I/O) fazem com que ele não esteja pronto para a maioria das equipes de produção; defendem semver adequado ou esquemas de edição em vez de quebra aberta.
- Alguns preferem a abordagem do Zig (volatilidade honesta) a linguagens conservadoras e pesadas de acúmulo; outros insistem em estabilidade de longo prazo para implantações sérias.
Escolha de linguagem, GC e desempenho
- Discussão sobre OCaml e outras linguagens gerenciadas/FP para compiladores: historicamente bem-sucedidas, existem compiladores muito rápidos; alguns acham que a suposição de Roc de que “tem que ser uma linguagem de sistemas” é forte demais.
- Contraponto: CPUs modernas e recursos de linguagem (por exemplo, alocação sofisticada de closures) mudam as restrições; controle fino sobre layout e alocação pode importar muito.
- Debate mais amplo sobre GC:
- Alguns argumentam que o sentimento anti-GC é exagerado e que a maioria dos serviços do mundo real toleraria GCs modernos.
- Outros descrevem sistemas de alto throughput / baixa latência em que stalls na escala de µs importam e pausas de GC (mesmo as “de baixa latência”) são inaceitáveis, então GC está fora de questão.
Reações à linguagem Roc e questões em aberto
- Vários comentaristas acham Roc interessante, mas não têm certeza sobre seu nicho e casos de uso (scripting, plugins vs linguagem para apps server/client; competição com WASM, Gleam, Elm).
- Alguns gostam do matching de padrões de Roc e de padrões de strings sem alocação, mas apontam um bug sutil em um exemplo de roteamento e se preocupam com semântica delicada com barras embutidas.
- Feedback de estilo menor: linhas separadas de anotação de tipo parecem estranhas para alguns em comparação com sintaxe estilo F#.
Cultura, reescritas e side threads de IA/Bun
- Alguns veem uma onda emergente de ruído do tipo “reescrever Rust para X” e alertam contra tribalismo de linguagem; outros enfatizam “a ferramenta certa para o trabalho” e aceitam reescritas quando o encaixe com o domínio muda.
- Uma comparação breve com a reescrita de outro projeto de Zig para Rust gera piadas sobre “UNO reverse”, mas também levanta questões sobre a sustentabilidade de longo prazo de ecossistemas pré-1.0.
- Um thread pergunta por que uma grande empresa de IA adquiriu um vendor de runtime JavaScript em vez de simplesmente portar; as respostas focam em risco de falha da startup, controle estratégico e motivações de acquihire.