Repo for https://zig.guide content. Feedback and PRs welcome.
zig build --summary all
Repo for https://zig.guide content. Get up to speed with Zig quickly.
Home Page: https://zig.guide
License: MIT License
Repo for https://zig.guide content. Feedback and PRs welcome.
zig build --summary all
We need to come up with a chapter layout that makes sense.
Perhaps this would make sense:
I installed Zig 0.6 on my Arch Linux box today. When attempting to build the hello world example in this tutorial, I received the following error.
tedm@tedm-arch ~/S/zig_test> zig run main.zig
./main.zig:4:14: error: container 'std.debug' has no member called 'print'
std.debug.print("Hello, {}!\n", .{"World"});
^
Looking at the official website, I notice that their homepage hello world example calls warn
instead of print
and compiles fine. Also, the official documentation's example is quite a bit different, instead writing to stdout.
However, I also see that print
is still listed as a method under debug. Also, the official documentation has an example with the same problem further down called hello_again.zig
.
This tutorial is unreadable because of the poor color contrast. The first line of the first example:
const std = @import("std");
I can only read the =
sign if I use very big fonts since the contrast between red and black is so low.
I know that black is very fashionable as a background but it is useless for reading.
On a side note the instructions for setting the path in Windows don't mention using Control Panel; they should at least mention that possibility since not everyone uses powershell.
inline, noinline, tail calling etc
Chapter 0 says:
This guide does not support the 0.7 build of Zig.
Later it says:
- Verify your install with zig version. The output should be 0.7.0+ followed by some hex digits.
This is not currently obvious for some readers
https://ziglearn.org/chapter-2/#formatting-specifiers
The last example of formatting in chapter 2 is:
{s} outputs zero terminated strings.
test "terminated fmt" {
var b: [6]u8 = undefined;
const hello: [*:0]const u8 = "hello!";
expect(eql(
u8,
try bufPrint(&b, "{}", .{hello}),
"hello!",
));
}
But {s}
is never used.
depends on #9
At the current stage, chapter 1 may be difficult to follow for people without previous low level programming experience.
I think that in the long run, we should provide a small section or chapter on some basics such as:
This would have landed today but it's not implemented for windows as far as I can tell
First of all, thanks for creating this resource. This has been personally useful for me!
In fact, as I was studying some of the snippets (readers/writers, for instance), I realised that this fits in very well with a cookbook style of approach. The canonical example I can give is the wonderful Lisp cookbook.
I know (and agree with the fact) that "cookbook" seems to have a very particular connotation in modern usage, but I feel that that does not detract too much from the overall idea. To illustrate, from the same link, a sample chapter on threads.
Perhaps you could consider this cookbook approach since the chapters themselves already contain very useful (and runnable!) example code. I believe quite strongly that such a resource will become indispensable very soon.
Thanks for writing the site. Excellent.
As an experienced C developer and a Zig newbie I have struggled with the paucity of Zig documention. Members of Discord#zig-help have kindly provided me with answers to questions that search engines couldn't find (Zig is too new).
A chapter on Zig for C Developers would have been helpful. Anecdotes/Cookbook. I can write some content. Currently this would be suggestions on how to implement C preprocessor commands in Zig and using zig translate-c
zig translate-c
is your friendzig translate-c
misses and how to
#error
#ifdef
#else
#endif
usingnamespace if struct{} else struct{}
std
library and support for Tier 2 Tier 3comptime
and why not to worry about apparently extraneous codezig build-obj
andextern
and why it is not neededimport of file outside package path
what's wrong with #include "../../../include/includeme.h"
?#include
usingnamespace
@import
This is more of a long term thing, but ziglearn (as a github project and a website) should ideally support multiple languages. How this should work in terms of organization I'm not sure, I will probably need to come up with a custom solution for generating markdown files for different languages.
Obviously while I would like to prioritise certain languages (maybe russian, chinese, japanese, spanish for example), I don't speak multiple languages, can't fund these translations, and would need to be able to find translators familiar with the programming terms being discussed. So we will take what we can get. If anyone is happy to help out with these things, please tell.
Hey, amazing tutorial! It's already helped me a ton on onboarding (first native language in years tbh).
I've noticed there's no section on iterators. Ziglang has this section at the bottom of this page:
const std = @import("std");
pub fn main() void {
const msg = "hello this is dog";
var it = std.mem.tokenize(msg, " ");
while (it.next()) |item| {
std.debug.print("{}\n", .{item});
}
}
...but that's the only place I've found documentation on it so far.
More advanced usage would be nice to. Like, I'm struggling currently iterating over directory entries. The std.fs.Dir
object emits both error union with an optional, which doesn't play nicely with payload capture without unwrapping the error union with a try first.
const std = @import("std");
pub fn main() void {
const cwd = try std.fs.cwd().openDir("", .{ .iterate = true });
var itr = cwd.iterate();
while (try itr.next()) |ent| {
print("{}", .{ ent.name });
}
}
https://ziglearn.org/chapter-1/#floats
This test only passes because they're comptime known
test "float coercion" {
const a: f16 = 0;
const b: f128 = a;
const c: f32 = b;
expect(c == a);
}
Hi, I'm new to Zig and I think I found a (minor) issue with one of your code examples. :)
Chapter 1, Slices, second example("slices 2") does not compile with neither Zig 0.6.0 nor 0.6.0+d907f574e (master at the time of writing).
Here's the complete code example I used:
const std = @import("std");
const expect = std.testing.expect;
test "slices 2" {
const array = [_]u8{1, 2, 3, 4, 5};
const slice = array[0..3];
expect(@TypeOf(slice) == *[3]u8);
}
And here is the output of Zig 0.6.0+d907f574e (0.6.0 has identical output):
Test [1/1] test "slices 2"...test failure
/home/flandere/local/lib/zig/std/testing.zig:193:14: 0x20448b in std.testing.expect (test)
if (!ok) @panic("test failure");
^
/home/flandere/tmpcode/zig/src/slices.zig:7:11: 0x204aae in test "slices 2" (test)
expect(@TypeOf(slice) == *[3]u8);
^
/home/flandere/local/lib/zig/std/special/test_runner.zig:47:28: 0x22bc0e in std.special.main (test)
} else test_fn.func();
^
/home/flandere/local/lib/zig/std/start.zig:252:37: 0x20550d in std.start.posixCallMainAndExit (test)
const result = root.main() catch |err| {
^
/home/flandere/local/lib/zig/std/start.zig:123:5: 0x20524f in std.start._start (test)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
After some fiddling with it, I found out that it expects *[3]u8
to be const
because array
is const
.
I made a few attempts to compare slice against a const version of *[3]u8
, with little success.
These refuse to compile because const
is invalid in this place:
expect(@TypeOf(slice) == const *[3]u8);
expect(@TypeOf(slice) == @TypeOf(const *[3]u8));
For completeness, the error:
./src/slices.zig:7:30: error: invalid token: 'const'
expect(@TypeOf(slice) == const *[3]u8);
^
Changing the array to be var
allows the code to compile, but I'm not sure if it's possible to compare a const slice against a const *[3]u8
.
Thank you for ziglearn! The first chapter has been a pleasure to read and helps me hit the ground running with learning Zig.
If you look at chapter-1 #integer-rules or #floats
The part explaining you you can use underscores has an example:
In which the colouring of the numbers stops as soon as an underscore is hit.
I assume this is an easy fix, but I have no idea how this site generates it's code highlighting.
I'd love a primer on how to use async/await. Especially coming from TS/JS/C# where the conventions are different and you have builtin functions like Promise.(all|race|etc)
The second code block under "Readers and Writers" contains the line:
try file.reader().readAllArrayList(&list, 16 * 1024);
The std documentation states that the second argument is a u64 for "max append size", but I wasn't sure exactly what this meant or why 16 * 1024 was chosen. Any chance this could be explained? Thanks for the awesome guide!
Need an explanation of array[start...end-1:terminator]
syntax
Zig version: 0.6.0+53c63bdb7
on Linux 5.8.14-arch1-1
https://ziglearn.org/chapter-1/#pointers
For some reason this code doesn't fail as the block about pointers states:
const expect = @import("std").testing.expect;
test "naughty pointer" {
var x: u16 = 0;
var y: *u8 = @intToPtr(*u8, x);
}
$ zig test test.zig
All 1 tests passed.
but after looking closely I noticed that test that fails in the tutorial is named "bad pointer" instead of "naughty pointer",
test "bad pointer"...cast causes pointer to be null
.\tests.zig:241:18: 0x7ff69ebb22bd in test "bad pointer" (test.obj)
var y: *u8 = @intToPtr(*u8, x);
^
so I'm a little bit unsure about what's going on. Is this new compiler feature that allows using zero values for pointers? Or something wrong with my zig installation? Or maybe there is a missing test?
(Constructive feedback, nothing negative here).
This step gave me a lot of problems. In the end you just have to enter the command as one line, but I did not know this. I ended up making a ps1 file. Then I had the problem of running that as administrator.
Then there was this incorrect answer:
https://superuser.com/questions/108207/how-to-run-a-powershell-script-as-administrator
All by all, it would be worth mentioning that you have to enter the command as one line.
Personally I think this is much easier:
press the windows key on your keyboard, type "envi..."
Sure this takes more space, but I think it is more user friendly. Maybe you can collapse things in your webdesign?
My 2 cent
In chapter 1, assignment, https://ziglearn.org/chapter-1/#assignment, there is the following:
Values can be ignored by using _ in place of a variable or const declaration.
_ = 10;
Can someone give me a more practical example. I don't see how this can be used. I tried multiple things but I only get errors.
https://ziglearn.org/chapter-2/#random-numbers
This:
test "random numbers" {
var seed: u64 = undefined;
try std.crypto.randomBytes(std.mem.asBytes(&seed));
var rand = std.rand.DefaultPrng.init(seed);
const a = rand.random.float(f32);
const b = rand.random.boolean();
const c = rand.random.int(u8);
const d = rand.random.intRangeAtMost(u8, 0, 255);
}
Does not work for me. I get:
error: container 'std.crypto' has no member called 'randomBytes'
try std.crypto.randomBytes(std.mem.asBytes(&seed));
I thought maybe it is random.bytes
instead of randomBytes
, but this gives me other errors, it seems closer to the solution do.
Planning on adding this to the C chapter when I get another long look at it
Setting aside the lack of a standard package/module/library manager, it would be nice to have at least minimal docs on
exe.addPackage()
, exe.linkLibC()
, exe.linkSystemLibrary()
.
test "error payload capture" {
var maybe_error: error{}!u32 = 40;
const val = if (maybe_error) |value| value else |err| 0;
}
named blocks and their use in loops..
In this chapter:
https://ziglearn.org/chapter-1/#labelled-blocks
There is this sentence:
"These can be used in anywhere expecting a value."
Which I think sounds odd, but I'm not a native english speaker.
I'm taking zig for a spin, and this explanation and function threw me a bit for a loop, because try
in this case is exactly equivalent to return
as far as I can tell:
try x is a shortcut for x catch |err| return err, and is commonly used in places where handling an error isn't appropriate. Zig's try and catch are unrelated to try-catch in other languages.
fn failFn() error{Oops}!void {
try failingFunction();
}
My suggestion would be to give failFn
a different return type than failingFunction
so that the try
cannot be replicated by a return
. An example I put together would be:
const expect = @import("std").testing.expect;
fn failingFunction() error{Oops}!void {
return error.Oops;
}
test "returning an error" {
failingFunction() catch |err| {
expect(err == error.Oops);
return;
};
}
fn failFn() error{Oops}!i32 {
try failingFunction();
return 12;
}
test "try" {
var v = failFn() catch |err| {
expect(err == error.Oops);
return;
};
expect(v == 12); // will never get reached
}
Anyway, I'm enjoying the book, I find it very helpful; thank you.
Hi!
Thanks for your great effort on documenting zig.
It would be great to have a section explaining how to implement golang like interfaces or rust like traits in zig.
Including examples with / without state (self) and with / without dynamic dispatching.
Based on the requested proposal: #46
I would like to ask, either as an extra chapter or as an extension of the initial proposal, an explanation about the differences and equivalence for modern c++ programmers, emphasizing:
constexpr
x comptime
)maybe more infos about FOR loops and the fact that it can't iterate over integers in contrary of many other languages. and then the fact that the WHILE loop is more close to what we "usually" do with FOR...
In this example: https://ziglearn.org/chapter-1/#comptime
fn addSmallInts(comptime T: type, a: T, b: T) T {
return switch (@typeInfo(T)) {
.ComptimeInt => a + b,
.Int => |info| if (info.bits <= 16)
a + b
else
@compileError("ints too large"),
else => @compileError("only ints accepted"),
};
}
I was wondering, doesn't an indentation like this makes more sense?
fn addSmallInts(comptime T: type, a: T, b: T) T {
return switch (@typeInfo(T)) {
.ComptimeInt => a + b,
.Int => |info|
if (info.bits <= 16)
a + b
else
@compileError("ints too large"),
else => @compileError("only ints accepted"),
};
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.