Recentemente tive mais tempo para escrever código em Zig, e isso tem feito bem à minha alma. Este texto compartilha ideias sobre abstrações em Zig, incluindo técnicas que o autor considerou úteis, mas raramente empregadas de forma mais ampla.
Muito se escreveu sobre as interfaces de Zig, e com razão. Embora não seja um recurso da linguagem, as interfaces são a forma de fato de implementar polimorfismo em tempo de execução em Zig. Também se falou bastante sobre o comptime de Zig e como ele pode ser aproveitado para evitar os problemas de desempenho do despacho dinâmico e para escrever código elegante e orientado a dados.
O polimorfismo em Zig é convencionalmente obtido de uma de duas maneiras. Interfaces dinâmicas usam ponteiros opacos, tabelas virtuais e despacho dinâmico para alcançar polimorfismo em tempo de execução. O duck typing em tempo de compilação usa reflexão de tipos, instruções switch e monomorfização em tempo de compilação para alcançar polimorfismo estático. Essa situação tem se mostrado eficaz, mas não está isenta de compromissos. As interfaces oferecem contratos de tipo familiares de outras linguagens, mas, por serem modulares em tempo de execução, criam uma barreira rígida para o compilador e, portanto, uma sobrecarga de desempenho. Para código crítico em desempenho, Zig normalmente recorre ao duck typing em tempo de compilação, que detecta violações de interface durante a compilação, mas ainda exige documentação cuidadosa do contrato.
Desenvolvedores vindos dos traits do Rust ou das typeclasses do Haskell podem achar esse arranjo simplista, e Zig de fato busca ser simples. O autor argumenta que, com alguma adaptação, abstrações semelhantes sobre tipos são possíveis no userland de Zig. A proposta é uma nova convenção para definir contratos de tipo em tempo de compilação como Traits, sem exigir bibliotecas ou mecanismos adicionais. Ela é inspirada na programação funcional em geral e no OCaml em particular.
Um Trait é definido como uma struct em tempo de compilação que contém funções relacionadas sobre um determinado tipo. O artigo ilustra isso com um trait Reducer para dobramento, em que um tipo forma um redutor sob um valor vazio e uma operação de combinação. Traits separados de soma e produto para i32 mostram como a mesma lógica genérica de reduce pode ser reutilizada, com o compilador capaz de embutir e desenrolar o laço. O autor conclui que os traits são simplesmente um saco de diversão.
Fonte: Hacker News · Resumido por HeadlinesBriefing