Zig (linguagem de programação)

Origem: Wikipédia, a enciclopédia livre.
Saltar para a navegação Saltar para a pesquisa


Zig
Zig programming language logo.svg
Paradigma Imperativo, Procedural, Concorrente, Funcional, Genérica
Surgido em 8 fevereiro 2016; há 4 anos[1]
Última versão 0.7.1 (13 dezembro 2020; há 25 dias[2])
Criado por Andrew Kelley
Estilo de tipagem: Forte, Estática, Inferido, Estrutural, Genérico
Compiladores zig (UNIX like) ou zig.exe (Windows)
Influenciada por C, C++, Rust, Go, LLVM, JavaScript
Plataforma Etapa 1 & 2:

ARM e AARCH64, MIPS32 LE, RISC-V64, x86, x86_64, Wasm32

Etapa 3:

MIPS32 BE e MIPS64, PowerPC e PPC64, RISC-V32, SPARC, S390x, Wasm64

Etapa 4:

AVR, GPU AMD - GCN, GPU Nvidia, Kalimba, MSP430, XCore (XMOS)

Sistema operacional UEFI, UNIX like, Windows
Licença: MIT
Extensão do arquivo: .zig
Página oficial ziglang.org

Zig é uma linguagem de programação de multiparadigma voltado para sistemas e compilável, embora seja de propósito geral, estaticamente tipada, projetada por Andrew Kelley.[3][4] A linguagem é projetada para "robustez, otimização e facilidade de manutenção"[5][6], suportando genéricos em tempo de compilação e reflexão, compilação cruzada e gerenciamento manual de memória.[7] Um dos principais objetivos da linguagem é competir (e melhorar) a linguagem C[8] [9], ao mesmo tempo que se inspira em Rust[10][11], entre outros.

Zig tem muitos recursos para programação de baixo nível, notavelmente como: packed struct (estrutura de variáveis struct com preenchimento de zero entre os campos), inteiros de largura arbitrária[12] e vários tipos de ponteiro.[13]

O compilador é escrito em Zig e C++ (etapa 1), usando LLVM 11[14] como back-end[15][16], suportando muitos de seus alvos nativos.[17] O compilador é um software livre e de código aberto sob a licença MIT[18] . O compilador Zig expõe a capacidade de compilar C e C++, semelhante ao Clang, usando os comandos "zig cc" e "zig c++", respectivamente.[19] A linguagem de programação Nim suporta o uso de zig cc como um compilador C.[20]

Etapas do Compilador[editar | editar código-fonte]

O processo de desenvolvimento do compilador se encontra em 4 etapas, embora apenas 3 sejam aderidos atualmente.

  • Etapa 0: compilado somente em C++ (LLVM)
  • Etapa 1: compilado em C++ (LLVM) e Zig (etapa 0) - versão atual de lançamento
  • Etapa 2: compilado somente em Zig (etapa 1)
  • Etapa 3: compilado somente em Zig (etapa 2)

As demais etapas posteriores ao 1 (um), apresentam instabilidade com a biblioteca padrão, embora suportem mais plataformas e sistemas, quanto ao 0 (zero) serve apenas como base inicial. O objetivo é tornar-se totalmente independente do LLVM, aderindo a Etapa 2 (dois) como padrão, previsto na versão 1.0.

Filosofia[editar | editar código-fonte]

Sem estrutura de controle oculta[editar | editar código-fonte]

Se o código Zig não parece estar pulando para chamar uma função, então não está. Isso significa que você pode ter certeza de que o código a seguir chama apenas foo()e então bar(), e isso é garantido sem a necessidade de saber os tipos de nada:

var a = b + c.d;
foo ();
bar ();

D tem as funções @property, que são métodos que você chama com o que parece ser acesso de campo, portanto, no exemplo acima, c.d pode chamar uma função. Rust tem sobrecarga do operador, então o operador + pode chamar uma função. D tem exceções throw/catch, portanto, foo() pode lançar uma exceção e evitar que bar() seja chamado. (Claro, até mesmo em Zig foo() poderia travar e impedir bar() de ser chamado, mas isso pode acontecer em qualquer linguagem que seja Turing-Completude). O objetivo desta decisão de design é melhorar a legibilidade.

Sem Alocações desnecessárias[editar | editar código-fonte]

De forma mais geral, adote uma abordagem direta quando se trata de alocação de heap. Não há palavra-chave new ou qualquer outro recurso de linguagem que utilize um alocador de heap (por exemplo, operador de concatenação de string, embora haja um operador de concatenação de arranjo (array), mas ele só funciona em tempo de compilação, então ainda não há alocação de heap em tempo de execução com ele). Todo o conceito de heap está estritamente no espaço do usuário. Existem alguns recursos de biblioteca padrão que fornecem e funcionam com alocadores de heap, mas esses são recursos de biblioteca padrão opcionais, não integrados à própria linguagem. Se você nunca inicializar um alocador de heap, pode ter certeza de que seu programa nunca causará alocações de heap.

A biblioteca padrão do Zig ainda é muito jovem, mas o objetivo é que cada recurso que use um alocador aceite um alocador em tempo de execução, ou possivelmente em tempo de compilação ou tempo de execução.

A motivação para esta filosofia de design é permitir que os usuários escrevam qualquer tipo de estratégia de alocação personalizada que considerem necessária, em vez de forçá-los ou até mesmo incentivá-los a uma estratégia específica que pode não ser adequada às suas necessidades. Por exemplo, Rust[19] parece encorajar uma única estratégia de alocador global, que não é adequada para muitos casos de uso, como desenvolvimento de sistema operacional e desenvolvimento de jogos de alto desempenho. Zig está pegando dicas da postura de Jai sobre alocadores, uma vez que essa linguagem está sendo desenvolvida por um designer de jogos de alto desempenho para o uso de jogos de alto desempenho.

Como afirmado antes, este tópico ainda é um pouco confuso e se tornará mais concreto conforme a biblioteca padrão do Zig amadurece. O importante é que a alocação de heap seja um conceito de espaço do usuário, e não embutido na linguagem.

Nem é preciso dizer que não existe um coletor de lixo embutido como há na linguagem Go.

Autonomia[editar | editar código-fonte]

Zig tem uma biblioteca padrão inteiramente opcional que só é compilada em seu programa se você a utilizar. O mesmo ocorre com a libc, a utilização dela é opcional, exceto em casos de interoperabilidade com linguagem C. O Zig é amigável ao desenvolvimento de sistemas embarcados e bare-metal.

Uma linguagem portátil para bibliotecas[editar | editar código-fonte]

Um dos santo graal da programação é a reutilização de código. Infelizmente, na prática, acabamos reinventando a roda várias vezes. Muitas vezes é justificado.

  • Se um aplicativo tem requisitos de tempo real, qualquer biblioteca que usa coleta de lixo ou qualquer outro comportamento não determinístico é desqualificada como dependência.
  • Se uma linguagem torna muito fácil ignorar erros e, portanto, verificar se uma biblioteca trata corretamente e gera bolhas de erros, pode ser tentador ignorar a biblioteca e implementá-la novamente, sabendo que todos os erros relevantes foram tratados corretamente. O Zig é projetado de forma que a coisa mais preguiçosa que um programador pode fazer é lidar com os erros corretamente e, portanto, pode-se estar razoavelmente confiante de que uma biblioteca irá propagar erros.
  • Atualmente, é pragmaticamente verdade que C é a linguagem mais versátil e portátil. Qualquer linguagem que não tenha a capacidade de interagir com o código C corre o risco de ser obscurecida. O Zig está tentando se tornar a nova linguagem portátil para bibliotecas, tornando-o simultaneamente direto para a conformidade com a C ABI para funções externas e introduzindo segurança e design de linguagem que evita bugs comuns nas implementações.

Simplicidade[editar | editar código-fonte]

C++, Rust e D têm um grande número de recursos e podem desviar a atenção do significado real do aplicativo em que você está trabalhando. Alguém se encontra depurando seu conhecimento da linguagem de programação em vez de depurar o próprio aplicativo.

O Zig não possui macros nem metaprogramação, mas ainda assim é poderoso o suficiente para expressar programas complexos de uma forma clara e não repetitiva. Inclusive o Rust que possui casos especiais de macros format!, implementando-o no próprio compilador. Enquanto isso, no Zig, a função equivalente é implementada na biblioteca padrão sem nenhum código de caso especial no compilador.

Quando você olha para o código Zig, tudo é uma expressão simples ou uma chamada de função. Não há sobrecarga de operador, métodos de propriedade, despacho de tempo de execução, macros ou fluxo de controle oculto. Zig busca toda a bela simplicidade de C, exceto as armadilhas.

Exemplos[editar | editar código-fonte]

Olá Mundo - Concatenação de Strings[editar | editar código-fonte]

const std = @import("std");

const debug = std.debug;
const heap = std.heap;
const mem = std.mem;

// '!' esta sintaxe antes do tipo void indica ao compilador Zig que a função retornará um erro ou um valor.

pub fn main() !void {
    const ola = "Olá,";
    // Qualquer variavel const ou valor literal é de tempo de compilação

    debug.print("\n{}{}\n", .{ ola, " mundo!" });

    // Método 1: concatenação de arranjo (array)
    // Só funciona se os valores forem de tempo de compilação.
    const ola_mundo_at_comptime = ola ++ " mundo!";

    debug.print("{}\n", .{ola_mundo_at_comptime});

    // Método 2: std.mem.concat - Biblioteca padrão
    var buf: [128]u8 = undefined;

    // Alocando um tamanho fixo de memória, equivalente ao tamanho do buf
    const allocator = &heap.FixedBufferAllocator.init(&buf).allocator;

    const ola_mundo_concatenated = try mem.concat(allocator, u8, &[_][]const u8{ ola, " mundo!" });

    debug.print("{}\n", .{ola_mundo_concatenated});

    // Método 3: std.mem.join - Biblioteca padrão
    const ola_mundo_joined = try mem.join(allocator, " ", &[_][]const u8{ ola, "mundo!" });

    debug.print("{}\n", .{ola_mundo_joined});
}

Interoperabilidade com C[editar | editar código-fonte]

const std = @import("std").c;
const c = @cImport({
    // Veja em: https://github.com/ziglang/zig/issues/515
    // @cDefine("_NO_CRT_STDIO_INLINE", "1");
    @cInclude("stdio.h");
});

pub fn main() void {
    _ = std.printf("Método 1: Código C em Zig!\n"); // Requer libc (nativo do sistema)
    _ = c.printf("Método 2: Código C em Zig!\n"); // Requer libc (nativo do sistema)
}

// Compilação: zig build-exe ffi.zig -lc

Fibonacci[editar | editar código-fonte]

const expect = @import("std").testing.expect;

fn fibonacci(index: u32) u32 {
    if (index < 2) return index;
    return fibonacci(index - 1) + fibonacci(index - 2);
}

test "fibonacci" {
    // testando a função de fibonacci em tempo de execução
    expect(fibonacci(7) == 13);

    // testando a função de fibonacci em tempo de compilação
    comptime {
        expect(fibonacci(7) == 13);
    }
}

// Saída:

// $ zig test test.zig
// 1/1 test "fibonacci"... OK
// All 1 tests passed.

Lista encadeada genérica[editar | editar código-fonte]

fn LinkedList(comptime T: type) type {
    return struct {
        pub const Node = struct {
            prev: ?*Node,
            next: ?*Node,
            data: T,
        };

        first: ?*Node,
        last:  ?*Node,
        len:   usize,
    };
}

pub fn main() void {
    var node = LinkedList(i32).Node {
        .prev = null,
        .next = null,
        .data = 1234,
    };

    var list = LinkedList(i32) {
        .first = &node,
        .last = &node,
        .len = 1,
    };
}

Veja também[editar | editar código-fonte]

Portal A Wikipédia tem os portais:
  • Free and open-source software
  • Computer programming

Referências[editar | editar código-fonte]

  1. Kelley, Andrew. «Introduction to the Zig Programming Language». andrewkelley.me. Consultado em 8 November 2020  Verifique data em: |acessodata= (ajuda)
  2. https://github.com/ziglang/zig/releases
  3. «Zig has all the elegant simplicity of C, minus all the ways to shoot yourself in the foot». JAXenter (em inglês). 31 de outubro de 2017. Consultado em 11 de fevereiro de 2020 
  4. «Tired of C? New programming language Zig aims to be more pragmatic and readable» (em inglês). 19 de outubro de 2017. Consultado em 22 de abril de 2020 
  5. Yegulalp, Serdar (29 de agosto de 2016). «New challenger joins Rust to topple C language». InfoWorld (em inglês). Consultado em 11 de fevereiro de 2020 
  6. «Zig language and C». Sina Corp. 12 de julho de 2020. Consultado em 12 de agosto de 2020 
  7. «The Zig Programming Language». ziglang.org. Consultado em 11 de fevereiro de 2020 
  8. «Mozilla's Observatory, the Zig programming language, and uSens' VR/AR SDK—SD Times news digest: Aug. 29, 2016». SD Times (em inglês). 29 de agosto de 2016. Consultado em 11 de fevereiro de 2020 
  9. «The Zig Programming Language». ziglang.org. Consultado em 11 de fevereiro de 2020 
  10. Company, Sudo Null. «Sudo Null - IT News for you». SudoNull (em inglês). Consultado em 11 de fevereiro de 2020 
  11. Kelley, Andrew. «Unsafe Zig is Safer Than Unsafe Rust». andrewkelley.me. Consultado em 11 de fevereiro de 2020 
  12. Tim Anderson 24 Apr 2020 at 09:50. «Keen to go _ExtInt? LLVM Clang compiler adds support for custom width integers». www.theregister.co.uk (em inglês). Consultado em 24 de abril de 2020 
  13. «Documentation - The Zig Programming Language». ziglang.org. Consultado em 24 de abril de 2020 
  14. «SD Times news digest: C++20 concepts in Visual Studio 2010 version 16.3, Bootstrap to drop IE support, and Zig 0.60 released». SD Times (em inglês). 14 de abril de 2020. Consultado em 19 de abril de 2020 
  15. «A Reply to _The Road to Zig 1.0_». www.gingerbill.org (em inglês). 13 de maio de 2019. Consultado em 11 de fevereiro de 2020 
  16. ziglang/zig, Zig Programming Language, 11 de fevereiro de 2020, consultado em 11 de fevereiro de 2020 
  17. «The Zig Programming Language». ziglang.org. Consultado em 11 de fevereiro de 2020 
  18. «ziglang/zig». GitHub (em inglês). Consultado em 11 de fevereiro de 2020 
  19. «0.6.0 Release Notes · The Zig Programming Language». ziglang.org. Consultado em 19 de abril de 2020 
  20. «Add support for 'zig cc' as C compiler. by hessammehr · Pull Request #13757 · nim-lang/Nim». GitHub (em inglês). Consultado em 19 de abril de 2020 

links externos[editar | editar código-fonte]