Por que Zig quando já existe C++, D e Rust?

A filosofia de design do Zig — evitar fluxo de controle oculto, alocações implícitas, sobrecarga de operadores e destrutores no estilo RAII — gera comparações intensas com C++, D, Rust, Go e até Jai. Os defensores argumentam que o tratamento explícito de erros, a passagem de alocadores e uma biblioteca padrão amigável ao freestanding tornam o Zig adequado para sistemas de baixo nível, embedded e como um substituto moderno para C, mesmo que isso sacrifique alguma ergonomia e abstração. Os céticos respondem que esses mesmos traços o tornam menos atraente para código de aplicação de nível mais alto ou código científico, e levantam preocupações sobre estabilidade da linguagem, maturidade do ecossistema e recursos ausentes como traits, payloads de erro mais ricos e sobrecarga de operadores amigável à matemática.

Atualizações do artigo e escopo

  • A página original de comparação com Zig foi atualizada para corrigir pontos desatualizados, notadamente a falta de um gerenciador de pacotes.
  • Alguns comentaristas sentem que a página lista recursos, mas não diz claramente “use Zig se você estiver fazendo X”, o que dificulta decidir para domínios específicos como computação científica.

Fluxo de controle oculto e definição de fluxo de controle

  • Um grande subthread debate o que “fluxo de controle” significa: alguns o restringem a condicionais; outros incluem qualquer mudança na ordem de execução (chamadas de função, exceções, interrupções, gotos).
  • O “sem fluxo de controle oculto” do Zig é interpretado como “sem chamadas de função invisíveis ou saltos baseados em exceções”: você deve ver toda a ramificação e a propagação de erros no ponto de chamada.
  • Críticos argumentam que recursos como defer/try por si só são palavras-chave de fluxo de controle não óbvias e que o termo “oculto” é sobrecarregado.

Alocação de memória e alocadores

  • Passar alocadores explicitamente é defendido como inversão de controle e evita problemas de “cor de função”.
  • Alguns veem os parâmetros extras como uma sobrecarga leve; alocadores globais continuam sendo uma opção.
  • Preocupação: bibliotecas ainda poderiam criar seus próprios alocadores ou chamar o SO diretamente. Os defensores dizem que isso seria anti-idiomático em Zig.
  • Designs baseados em capacidades em outras linguagens são mencionados; os participantes argumentam que isso é difícil/impossível de impor em uma linguagem de sistemas “sem runtime” como Zig.

Tratamento de erros e exceções

  • O try/as uniões de erro do Zig forçam o tratamento ou a propagação explícita no ponto de chamada, em contraste com exceções ocultas em C++/Java e panics em Go/Rust.
  • Alguns veem o tratamento de erros inline como verboso; outros dizem que o try do Zig é leve e mais claro do que exceções verificadas.
  • Debate sobre se o panic/recover de Go conta como exceções; alguns insistem que são “exceções de pobre”.

RAII, destrutores e limpeza de recursos

  • A falta de RAII/destrutores é um grande impeditivo para vários participantes, que veem chamadas explícitas de limpeza como verbosas e propensas a erros.
  • Outros preferem tempos de vida explícitos, defer e padrões com alocadores, argumentando que isso torna os pontos de limpeza mais claros e incentiva designs que não exigem destrutores.
  • O modelo RAII do Rust é citado como um meio-termo atraente.

Sobrecarga de operadores, abstrações e matemática/strings

  • A ausência de sobrecarga de operadores é elogiada por evitar “chamadas ocultas” e DSLs clever demais.
  • Os opositores dizem que isso prejudica código numérico e de álgebra linear e torna concatenação de strings e numerics personalizados mais desajeitados; sintaxe no estilo +/~ em outras linguagens é vista como mais ergonômica.
  • O lado pró-Zig argumenta que abstrações devem ser funções explícitas; críticos respondem que “menos armadilhas” pode ser supervalorizado em comparação com expressividade.

Casos de uso e público-alvo

  • Os defensores destacam a simplicidade do Zig, a biblioteca padrão opcional e o design freestanding como ideais para kernels, embedded, EFI e trabalho de sistemas de baixo nível.
  • Alguns veem potencial para desenvolvimento de jogos e ferramentas (por exemplo, emuladores de terminal, runtimes web); outros duvidam de sua adequação para codebases de alto nível, pesadas em matemática ou estilo corporativo.

Estabilidade, ecossistema e risco de adoção

  • Discussão sobre cronogramas de estabilidade da linguagem e se é sensato apostar em Zig antes da 1.0.
  • Um lado enfatiza que adotantes iniciais correm risco de custos de migração, comparando com a mudança do Rust pré-1.0 e Python 2→3; outro lado observa o uso crescente no mundo real (por exemplo, tooling web, sistemas de trading) como evidência de que Zig é mais do que um brinquedo.
  • Há tensão entre querer interoperabilidade com C e garantias: reutilizar C em excesso enfraquece parte da história de segurança do Zig.

Comparações com D, Rust, Go, Jai, C, etc.

  • Usuários de D relatam bom desempenho e múltiplas estratégias de alocação, e veem pouca razão para mudar com base apenas na página.
  • Rust é elogiado por segurança, mas criticado por complexidade, problemas de tooling e falta de API de alocadores / SIMD portável; alguns usuários de Rust estão “curiosos sobre Zig”.
  • A falta de try/catch em Go é apontada; seus panics raramente são usados como fluxo de controle, mas escondem alocações (por exemplo, defer).
  • Jai é discutido, mas descartado por enquanto por ser fechado/não lançado e por não oferecer suporte a embedded de 32 bits.
  • Alguns argumentam que C ou sucessores semelhantes a C (C3, outros) ainda são mais simples; outros contrapõem que a simplicidade de C esconde uma grande lacuna entre “consegue escrever C” e “consegue escrever C segura e correta”.