mboost-dp1

Zig - nyt systemsprog


Gå til bund
Gravatar #1 - larsp
9. okt. 2023 06:44
https://ziglang.org/learn/overview

Hvem har hørt om det nye sprog Zig? Jeg stødte på det i en oversigt over nye sprog med stærkt stigende interesse på stack overflow. Det er en ganske interessant nytænkning af C med fokus på simplicitet, fravær af overraskelser og med moderne innovationer indenfor sikkerhed og byggemiljø. Dog uden det høje ambitionsniveau som Rust har med hensyn til multithreaded sikkerhed, så vidt jeg kan se.

Binaries behøver ikke slæbe rundt på en gumpetung runtime. Et hello-world program kan bringes til at fylde få kilobytes.

Zig kan direkte interface med C libraries og header filer og bygge C kode, hvis det skal være. Zig er angiveligt bedre end C til at være C allerede pga. det moderne indbyggede build system, indbygget cross-compiling og medfølgende standard libraries, som libc, musl samt zigs eget standard library.

På min Ubuntu kunne jeg med et snuptag bygge et hello world program til Windows:


$ cat hello.zig
const std = @import("std");

pub fn main() void {
std.debug.print("Hello, world!\n", .{});
}

$ zig build-exe hello.zig -O ReleaseSmall -fstrip -fsingle-threaded -target x86_64-windows

$ ll
drwxrwxr-x 3 lars lars 4096 Oct 9 09:36 ./
drwxrwxr-x 31 lars lars 4096 Oct 9 08:34 ../
-rwxrwxr-x 1 lars lars 2560 Oct 9 09:36 hello.exe*
-rw-rw-r-- 1 lars lars 1119 Oct 9 09:36 hello.exe.obj
-rw-rw-r-- 1 lars lars 98 Oct 9 08:35 hello.zig

$ file hello.exe
hello.exe: PE32+ executable (console) x86-64, for MS Windows
Gravatar #2 - arne_v
9. okt. 2023 12:14
Gravatar #3 - arne_v
9. okt. 2023 12:21
Konteksten er vel:
* i mange år væltede det ud med dusinvis af nye sprog til "business computing" mens det blev betragtet som kætteri at bruge andet en C/C++ til low-level programmering (medmindre man skulle ned i assembler)
* så kom Rust og Go - Rust blev populært hos OS udviklere (Linux kernel og Windows), Go blev populært hos container infrastrutur udviklerne
* og nu var ånden ude af flasken - man kunne godt lave nye sprog til low-level programmering - og det gik man så igang med at gøre
* Zig og Hare er de sprog som typisk nævnes
Gravatar #4 - arne_v
9. okt. 2023 12:23
Og det giver vel også en vis mening.

At Rust er bedre end C betyder ikke at Rust er den bedst mulige afløser af C.

Man prøver forskellige muligheder og så ser man hvad der overlever og hvad der ikke gør.
Gravatar #5 - larsp
9. okt. 2023 12:54
Rust har et meget højere ambitionsniveau end Zig hvad angår sikkerhedsgarantier og højere-niveau sprog features. Der er helt klart plads til begge. Jeg har set Zig kaldet afløseren til C og Rust afløseren til C++.

Zig har ikke engang support for OOP og har ikke indbygget memory management. Hvis man vil f.eks. parse JSON stikker man parseren en given Allocator og kan således frit vælge en memory allokerings teknik, som f.eks. en Arena Allocator (genialt).

En Arena Allocator betyder kort fortalt at man skaber en separat arena hvor der kan allokeres uden at bekymre sig om at kalde free. Når man er færdig med opgaven, frigives hele arenaen på én gang.

Zig er generelt altid "unsafe" men har til gengæld så mange tools som muligt for at hjælpe, mens Rust-unsafe virkelig er at svømme på dybt vand.

God tråd: https://www.reddit.com/r/Zig/comments/172kqrw/rust...

Jeg synes det er en ekstrem lækker feature at Zig kan tage over som C compiler og gøre toolchain mere enkel, samtidig med at man gradvis kan introducere Zig kode. Rust kan ikke rigtig træde til på den måde. De to sprog har helt klart forskellige use cases.

Hare har jeg ikke kigget på endnu, men det forekommer mig at der ikke er så meget "hype" om det sprog. Endnu?
Gravatar #6 - arne_v
9. okt. 2023 17:09
Jeg tror faktisk at de 4 sprog er meget forskellige set ud fra selve sprogene.

Men i den historiske kontekst er det 2 generationer af "C/C++ alternativer":
1) Rust og Go, blev populære for en del år siden, er idag næsten mainstream aka bruges af nogle meget seriøse projekter
2) Zig of Hare er de nye

(og hvis Google får snøvlet sig sammen til at gøre Carbon færdig så bliver det 3. generation)

++++

Jeg synes altid at Zig og Hare nævnes sammen, men formentligt har 90% af dem som jeg hører nævne dem sammen skrevet 0 linier i Zig og 0 linier i Hare.

++++

Personligt kan jeg absolut ikke lide Rust. Men det løser et problem: sikker memory management uden GC.

Rust bliver brugt til mange ting. Der er folk som laver web servere og lignende i Rust - hvor man kan sige at Rust har afløst C++. Men de to vel mest kendte brug af Rust - device drivere for Linux kernel og device drivere for Windows - er C erstatning.

++++

Mulighed for gradvis skift af sprog er også ideen i Carbon, altså C++ til Carbon ligesom C tiL Zig.
Gravatar #7 - larsp
10. okt. 2023 13:28
#6 Ja, Zig og Hare er en nyere generation af de "nyere" sprog. Og det gør dem også mere risky at investere tid i.

Men Uber har faktisk taget Zig til sig: https://www.uber.com/en-BG/blog/bootstrapping-uber...

Mit indtryk er at Zig har en del mere opmærksomhed om sig end Hare. Sidstnævnte sprog virker ret dødt. Her er subreddits for de to sprog:

https://www.reddit.com/r/harelang/ 50 members
https://www.reddit.com/r/Zig/ 9.7k Members
Gravatar #8 - larsp
10. okt. 2023 13:31
Her er et lille demoprogram i Zig der demonstrerer nogle basale features, array slices og en hurtig utf-8 test:


const std = @import("std");

pub fn main() void {
var digits = [10]i8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

negateArray(digits[0..5]);
printArray(digits[3..]);

const str = "Æbleøådal";

std.debug.print("str: {s}, len: {}, codepoints: {}\n", .{
str, str.len, std.unicode.utf8CountCodepoints(str) catch 0});

std.debug.print("5 bytes: {s}, 6 bytes: {s}, 7 bytes: {s}\n", .{
str[0..5], str[0..6], str[0..7]});
}

fn negateArray(arr: [] i8) void {
for (arr) |*x| {
x.* = -x.*;
}
}

fn printArray(arr: []const i8) void {
for (arr) |x| {
std.debug.print("{} ", .{x});
}
std.debug.print("\n", .{});
}

Udskriver:

-3 -4 5 6 7 8 9
str: Æbleøådal, len: 12, codepoints: 9
5 bytes: Æble, 6 bytes: Æble�, 7 bytes: Æbleø

Gravatar #9 - arne_v
10. okt. 2023 14:28
Jeg kan allerede nu sige at jeg ikke kan lide sproget.

:-)

Jeg betragter det som en vigtig egenskab ved et sprog at kode skrevet i det ikke kun er læsbart for dem som kender sproget virkeligt godt men også er læsbart for dem som kan programmere men ikke lige i dette sprog.

Zig koden:


fn negateArray(arr: [] i8) void {
for (arr) |*x| {
x.* = -x.*;
}
}

fn printArray(arr: []const i8) void {
for (arr) |x| {
std.debug.print("{} ", .{x});
}
std.debug.print("\n", .{});
}


Gennemsnit sprog 1970-2000:


function void negateArray(i8 arr[]) {
for(int i = 0; i < arr.length; i++) {
arr[i] = -arr[i];
}
}

function void printArray(const i8 arr[]) {
for(int i = 0; i < arr.length; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}


Gennemsnit sprog 2000-2020:


function void negateArray(i8[] arr) {
for(var elm in arr) {
elm = -elm;
}
}

function void printArray(const i8[] arr) {
for(val elm in arr) {
print("{0} ", elm);
}
println();
}


Min påstand er at de fleste vil betragte de to sidste eksempler som mere læsbare end Zig koden på trods af at de ikke kender sproget for de to sidste (det er nemlig to fiktive sprog som jeg har udtænkt baseret på diverse andre sprog fra perioden).

Fordi alle konstruktionerne er så velkendte fra andre sprog, så kan man bare læse det.
Gravatar #10 - larsp
10. okt. 2023 14:51
#9 Ja, det er en pudsig for løkke med en pointer som element. Men det kan gå hen og blive ret smart, hvis man vil gøre noget ved elementerne i en linked-list.


function void negateArray(i8[] arr) {
for(var elm in arr) {
elm = -elm;
}
}

Hmm, jeg tvivler på at dette virker i noget sprog, elm = -elm?

Hvis vi snakker python er man faktisk nød til at iterere med et index for at ændre elementer, mig bekendt. Hvis man ikke vil lave en ny list med en comprehension.

Men man kan også lave en mere normal for i zig:

fn negateArray2(arr: [] i8) void {
for (0..arr.len) |i| {
arr[i] = -arr[i];
}
}

Og så har de fundet på følgende skøre mellemting mellem while og for :o)

fn negateArray3(arr: [] i8) void {
var i: usize = 0;
while (i < arr.len) : (i += 1) {
arr[i] = -arr[i];
}
}


Gravatar #11 - arne_v
10. okt. 2023 15:19
larsp (10) skrev:


function void negateArray(i8[] arr) {
for(var elm in arr) {
elm = -elm;
}
}

Hmm, jeg tvivler på at dette virker i noget sprog, elm = -elm?


Der bruges:

var elm

fremfor:

val elm

så ideen er at det er by reference.

Den præcise syntax eksisterer ikke. Men en "moderne" for løkke med by reference eksisterer.

C++:


#include <iostream>

using namespace std;

int main()
{
int arr[] = { 1, 2, 3 };
for(auto& elm : arr)
{
elm = -elm;
}
for(auto elm : arr)
{
cout << elm << " ";
}
cout << endl;
return 0;
}


auto& fungerer som var og auto fungerer som val.

Men ja de fleste sprog med moderne for løkke har dem kun med val.

Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login