Giter Site home page Giter Site logo

ratfactor / ziglings Goto Github PK

View Code? Open in Web Editor NEW
4.1K 39.0 484.0 612 KB

Learn the Zig programming language by fixing tiny broken programs.

License: MIT License

Zig 98.94% Shell 1.06%
exercises learning-by-doing zig educational beginner-friendly ziglang

ziglings's Introduction

Ziglings

⚠️ Attention! Ziglings has moved to Codeberg!

Check out our handy new URL: https://ziglings.org

Or visit the repo directly at: https://codeberg.org/ziglings/exercises


Welcome to Ziglings! This project contains a series of tiny broken programs (and one nasty surprise). By fixing them, you'll learn how to read and write Zig code.

ziglings

Those broken programs need your help! (You'll also save the planet from evil aliens and help some friendly elephants stick together, which is very sweet of you.)

This project was directly inspired by the brilliant and fun rustlings project for the Rust language. Indirect inspiration comes from Ruby Koans and the Little LISPer/Little Schemer series of books.

Intended Audience

This will probably be difficult if you've never programmed before. But no specific programming experience is required. And in particular, you are not expected to have any prior experience with "systems programming" or a "systems" level language such as C.

Each exercise is self-contained and self-explained. However, you're encouraged to also check out these Zig language resources for more detail:

Also, the Zig community is incredibly friendly and helpful!

Getting Started

Install a development build of the Zig compiler. (See the "master" section of the downloads page.)

Verify the installation and build number of zig like so:

$ zig version
0.11.0-dev.4246+xxxxxxxxx

Clone this repository with Git:

$ git clone https://ziglings.org
$ cd ziglings.org

Then run zig build and follow the instructions to begin!

$ zig build

Note: The output of Ziglings is the unaltered output from the Zig compiler. Part of the purpose of Ziglings is to acclimate you to reading these.

A Note About Versions

The Zig language is under very active development. In order to be current, Ziglings tracks development builds of the Zig compiler rather than versioned release builds. The last stable release was 0.10.1, but Ziglings needs a dev build with pre-release version "0.11.0" and a build number at least as high as that shown in the example version check above.

It is likely that you'll download a build which is greater than the minimum.

(For those who cannot easily update Zig, there are also community-supported branches in this repo. At the moment, there's one for v0.8.1. Older version branches may or may not have all exercises and/or bugfixes.)

Once you have a build of the Zig compiler that works with Ziglings, they'll continue to work together. But keep in mind that if you update one, you may need to also update the other.

Version Changes

Version-0.11.0-dev.4246+71dfce31b

  • 2023-06-26 zig 0.11.0-dev.4246 - changes in compile step (now it can be null)
  • 2023-06-26 zig 0.11.0-dev.3853 - removal of destination type from all cast builtins
  • 2023-06-20 zig 0.11.0-dev.3747 - @enumToInt is now @intFromEnum and @intToFloat is now @floatFromInt
  • 2023-05-25 zig 0.11.0-dev.3295 - std.debug.TTY is now std.io.tty
  • 2023-04-30 zig 0.11.0-dev.2704 - use of the new std.Build.ExecutableOptions.link_libc field
  • 2023-04-12 zig 0.11.0-dev.2560 - changes in std.Build - remove run() and install()
  • 2023-04-07 zig 0.11.0-dev.2401 - fixes of the new build system - see #212
  • 2023-02-21 zig 0.11.0-dev.2157 - changes in build system - new: parallel processing of the build steps
  • 2023-02-21 zig 0.11.0-dev.1711 - changes in for loops - new: Multi-Object For-Loops + Struct-of-Arrays
  • 2023-02-12 zig 0.11.0-dev.1638 - changes in std.Build cache_root now returns a directory struct
  • 2023-02-04 zig 0.11.0-dev.1568 - changes in std.Build (combine std.build and std.build.Builder into std.Build)
  • 2023-01-14 zig 0.11.0-dev.1302 - changes in @addWithOverflow (now returns a tuple) and @typeInfo; temporary disabled async functionality
  • 2022-09-09 zig 0.10.0-dev.3978 - change in NativeTargetInfo.detect in build
  • 2022-09-06 zig 0.10.0-dev.3880 - Ex 074 correctly fails again: comptime array len
  • 2022-08-29 zig 0.10.0-dev.3685 - @typeName() output change, stage1 req. for async
  • 2022-07-31 zig 0.10.0-dev.3385 - std lib string fmt() option changes
  • 2022-03-19 zig 0.10.0-dev.1427 - method for getting sentinel of type changed
  • 2021-12-20 zig 0.9.0-dev.2025 - c_void is now anyopaque
  • 2021-06-14 zig 0.9.0-dev.137 - std.build.Id .Custom is now .custom
  • 2021-04-21 zig 0.8.0-dev.1983 - std.fmt.format() any format string required
  • 2021-02-12 zig 0.8.0-dev.1065 - std.fmt.format() s (string) format string required

Advanced Usage

It can be handy to check just a single exercise:

zig build -Dn=19

You can also run without checking for correctness:

zig build -Dn=19 test

Or skip the build system entirely and interact directly with the compiler if you're into that sort of thing:

zig run exercises/001_hello.zig

Calling all wizards: To prepare an executable for debugging, install it to zig-cache/bin with:

zig build -Dn=19 install

To get a list of all possible options, run:

zig build -Dn=19 -l

  install          Install 019_functions2.zig to prefix path
  uninstall        Uninstall 019_functions2.zig from prefix path
  test             Run 019_functions2.zig without checking output
  ...

What's Covered

The primary goal for Ziglings is to cover the core Zig language.

It would be nice to cover the Standard Library as well, but this is currently challenging because the stdlib is evolving even faster than the core language (and that's saying something!). Not only would stdlib coverage change very rapidly, some exercises might even cease to be relevant entirely.

Having said that, there are some stdlib features that are probably here to stay or are so important to understand that they are worth the extra effort to keep current.

Conspicuously absent from Ziglings are a lot of string manipulation exercises. This is because Zig itself largely avoids dealing with strings. Hopefully there will be an obvious way to address this in the future. The Ziglings crew loves strings!

Zig Core Language

  • Hello world (main needs to be public)
  • Importing standard library
  • Assignment
  • Arrays
  • Strings
  • If
  • While
  • For
  • Functions
  • Errors (error/try/catch/if-else-err)
  • Defer (and errdefer)
  • Switch
  • Unreachable
  • Enums
  • Structs
  • Pointers
  • Optionals
  • Struct methods
  • Slices
  • Many-item pointers
  • Unions
  • Numeric types (integers, floats)
  • Labelled blocks and loops
  • Loops as expressions
  • Builtins
  • Inline loops
  • Comptime
  • Sentinel termination
  • Quoted identifiers @""
  • Anonymous structs/tuples/lists
  • Async <--- ironically awaiting upstream Zig updates
  • Interfaces
  • Bit manipulation
  • Working with C

Zig Standard Library

  • String formatting
  • Testing
  • Tokenization

Contributing

Contributions are very welcome! I'm writing this to teach myself and to create the learning resource I wished for. There will be tons of room for improvement:

  • Wording of explanations
  • Idiomatic usage of Zig
  • Additional exercises

Please see CONTRIBUTING in this repo for the full details.

ziglings's People

Contributors

adamu avatar aedrax avatar airbus5717 avatar arnavion avatar arya-elfren avatar chrboesch avatar g-w1 avatar inkryption avatar jhalmen avatar joburgard avatar joefish avatar josephtlyons avatar jtgoen avatar kimshrier avatar lmbarros avatar lorrding avatar mattnite avatar mz0 avatar nahuakang avatar nchataing avatar otherjl0 avatar palash25 avatar palm404 avatar perillo avatar quexxon avatar ratfactor avatar rofrol avatar spexguy avatar vishalsodani avatar zapanton avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ziglings's Issues

"99 is enough for anybody" (I only zero-padded two digits)

Rather than hem and haw about it in the beginning, I went ahead and started these with two digit padding. But at this rate, I might run out of two-digit numbers before I'm even done with the language itself, let alone the standard library!

01_hello.zig
02_std.zig
...
98_unfragulating.zig
99_unfragulating2.zig

The other problem is inserting new items. Changing the order of items is even worse, but obviously won't ever be needed because this order is objectively perfect as is. 😆

I thought about leaving the exercises un-numbered, which would allow me to change the order or insert new topics easily. But I really like the fact that you can go into the exercises directory and see the order plain as day.

Triple Digit Number Options:

  1. When I hit 100, go ahead and call it 100_foo.zig and it'll alpha-sort between 09 and 11 or
  2. When I hit 100, rename 01-99 to 001-099 and assume there will never be more than 999 ziglings.

If the filenames are to be triple-digit, I'd rather bite the bullet sooner rather than later.

Move/Insertion Options:

  1. If something needs to be inserted, number it with a decimal: 12.1_while2.1.zig or
  2. Renumber everything after the inserted item.

I have a strong aversion to renumbering anything at any time because it will screw up existing written references to specific exercises (in commits and mentions internal or external to the project). In general, I really like the ability to refer to the exercises by absolute number and being able to count on that not changing.

HEY EVERYBODY!

This seems like a better place than the README to let everyone know I'm still alive and well and very much interested in the future of Ziglings. I see the PRs and issues as they come in. I've also had some excellent feedback via email. I know better than to promise any sort of timeline, but I'm ready to dive into this Real Soon. Thank you all for the activity and your patience!

Exercises for Allocators

Hello, first of all thanks for creating this Repo, it's been a great ressource to get used to zig so far.

However, now that i have essentially finished all the exercises, and i wanted to write a simple Brainfuck interpreter in Zig, i came across my first use of allocators, which (coming from C / C++) is a very major thing, which i believe has a great benefit to be also teached in Ziglings.

I am sort of in the middle of learning about allocators in zig and its usage so far, if i would have a better understanding of them yet, i would (or maybe will?) open a PR once i have learned about them in a more clear and detailed manner.

What is your opinion on that, as i have read that you do not want to teach about the standard library, yet i believe this is essentially a core part of Zig.

Cheers.

Ex 003 "i" comment missing

//
// It seems we got a little carried away making everything "const u8"!
//
//     "const" values cannot change.
//     "u"     types are "unsigned" and cannot store negative values.
//     "8"     means the type is 8 bits in size.

we could add

//
// It seems we got a little carried away making everything "const u8"!
//
//     "const" values cannot change.
//     "u"     types are "unsigned" and cannot store negative values.
//=>=> "i"     types are "signed" and can store negative values.
//     "8"     means the type is 8 bits in size.

patch 48 appears to be wrong

patch 48 shows

57c57
<             e = e.???; // Which method do we want here?
---
>             e = e.getTail(); // Which method do we want here?

trying to run this with zig build will give an error

modifying the while on line 52 seems to be the correct answer.
So that the while look is

    while (!e.visited) {
        e.print();
        e.visit();

        // Get the next elephant or stop.
        if (e.hasTail()) {
            e = e.getTail(); // Which method do we want here?
        } else {
            break;
        }
    }

I'm only mentioning this because path 49 appears to be wrong too. You need to modify the while loops and add another statement to make it work.

I'm writing an issue since perhaps, I'm wrong of course.

Zig version 0.8.0 is too old?

I'm using zig version 0.8.0-dev.1059+79730e6f5 for Windows, but I'm running it from a Cygwin bash shell. Attempting to build the ziglings repo and getting the following error:

$ zig build
Error: Your version of zig is too old.  Please download a master build from
https://ziglang.org/download/

The comments from zig.build indicate this should only apply for versions older than 0.5.0 or so. Is this a false positive I can fix easily?

Automated testing

This is mainly a note to self and I plan to implement this ASAP, but certainly anyone is welcome to suggest additional/other ideas.

Testing intentionally broken programs presents an interesting problem. My initial thought was to write a shell script with sed one-liners (or maybe even awk, but I don't think any of the changes would require its mighty power) that would alter each exercise and then test it in turn.

But after sleeping on the problem for a week, I think I've had my eureka moment this morning (which was, "Wait, UNIX already has much better tooling for this!") and my half-formed idea of a solution is:

  1. Create an answers/ dir that is not committed to the repo
  2. Make all initially-working exercises in answers/
  3. Break them and put them in exercises
  4. Do a diff on the two to create a patch, put it in a new patches/ dir that is committed
  5. Write a script in patches/ that
    • creates another dir, test/ (if needed), which is not committed
    • patches the broken exercises with patch and puts the output in test/
    • maybe calls the ziglings build script with the test/ directory as the target?
  6. Put a README in patches/ explaining what it's for and admonishing folks to try not to peek

I'm not concerned about the answers being available. I would rather somebody peeks at an answer now and then rather than give up completely. I think it will also help experts help me by verifying that I truly have a mistake or I'm behind on Zig versions or something.

On the other hand, struggling at least a little bit with these exercises is probably a good thing for learning, so I don't want to call attention to the fact that the answers are in the repo. It helps that diff output is slightly unpleasant to read if you're not used to it. And the directory will be called "patches" rather than "answers".

Beautifying patches.

I've done all your exercises. Those helped me so thank you.

I've read the patches to better grasp the Zigly way of coding. It's, imo, the benefit of having access to them.

Some are not written in a Zigly way like 086_async3.patch.
Others have comments changing like 058_quiz7.patch.

Those little things could help beginners to write better code and not getting confused while reading patches.

Misleading description of ++ operator

Exercise No. 005 (arrays2) contains the following description of the ++ operator:

You can use ++ to concatenate two arrays:

const a = [_]u8{ 1, 2 };
const b = [_]u8{ 3, 4 };
const c = a ++ b ++ [_]u8{ 5 }; // equals 1 2 3 4 5

This is slightly misleading, as it neglects to mention that (for now?) the ++ operator can only be used on arrays whose values are known at compiletime.

I would submit a PR to fix this but I'm honestly not quite sure how it should be amended, since the concept of comptime seems to be introduced somewhere in the 70's.

Resolve minor formatting inconsistencies with `zig fmt`?

Several of the exercises have minor formatting inconsistencies:

// 11_while.zig (line 24)
    while ( ??? ){   // missing space before opening brace

// 13_while3.zig (line 24)
    while (n <= 20) : (n+=1) {   // condition has spaces around operator, continue expression does not

// etc.

Rather than depending on manual scanning to catch/fix these small issues, maybe it would be preferable to run zig fmt on the exercises en masse? It's a slightly more annoying job than it seems at first because most of the exercises have syntax errors as is (so the task requires temporarily fixing, reformatting, then un-fixing the exercises). If this approach seems sensible, I'm happy to undertake the work.

Proposal: Use git tags to make ziglings compatible w/ specific zig versions

Firstly, thank you for this amazing learning resource! 🎉

While I completely understand you'd like to keep the exercises compatible with the current dev version of Zig, it'd be awesome to not force people to remain in lockstep and allow them to also use older versions of the lang (e.g. to avoid having to build from source because there's no prebuilt v0.9+ for 32bit ARM [RPI]). One easy solution to this could be adding tags to your repo before updating any examples to a future dev version... This would allow people to check out a version of the exercises compatible with an older Zig version without having to manually pinpoint (trial & error) a suitable commit from the history. What do you think? Too much effort?

ZIG 0.9 Ambiguous reference error

Problem
In zigling 058 few print()'s defined so new ZIG won't compile.
Possible solution is to change first definition to const print = @import("std") and call standard print() using std.debug.print().
Or just change method name in TripItem union to something else, like printTrip(),
so const print = @import("std").debug.print; still can be demonstrated.

Code
First print() was defined at line 31

const print = @import("std").debug.print;

Another print() was defined at line 183, so next references of print() becoming ambiguous?

fn print(self: TripItem) void {
        switch (self) {
            // Oops! The hermit forgot how to capture the union values
            // in a switch statement. Please capture both values as
            // 'p' so the print statements work!
            .place => |p| print("{s}", .{p.name}),
            .path => |p| print("--{}->", .{p.dist}),
        }
    }

Compilation

Compiling 051_values.zig...
051_values.zig:77:11: error: unused local constant
    const skull_farmer = Character{};
          ^

Ex 034 Quiz has confusing comment

I know what I meant by

// Just don't modify this function. It's "perfect" the way it is. :-)

but I see how it's really misleading and confusing for people trying to solve this quiz! Need to fix to make it clear that what I meant was something like

// This function is obviously weird and non-functional. But you will not be changing it for this quiz.

All I need is probably just "Leave this function alone." I'm already being silly enough in Ziglings.

Exercise 38: The printed "Expected" output and actual answer are inconsistent

Introducing a slight typo into exercise 38 produces this output:

----------- Expected this output -----------
Character 2 - G:10 H:100 XP:20
----------- but found -----------
Character 1 - G:20 H:100 XP:10
Character 2 - G:10 H:100 XP:2

-----------

When, really, the printout should be this based on the expected answer:

----------- Expected this output -----------
Character 1 - G:20 H:100 XP:10
Character 2 - G:10 H:100 XP:20
----------- but found -----------
Character 1 - G:20 H:100 XP:10
Character 2 - G:10 H:100 XP:2

-----------

ZIG 0.9 Unused constant error

New compiler gives error on zigling 51, when demonstrating data segment storage.

Code

// However, this "skull_farmer" character will be put in the
// global immutable data even though it's defined in a function.
// Since it's immutable, all invocations of the function can share
// this one value.

const skull_farmer = Character{};

Result

Compiling 051_values.zig...
051_values.zig:77:11: error: unused local constant
    const skull_farmer = Character{};
          ^

Make FIX ME points clearer (Zig stage 1 compiler not clear enough)

In cases such as Exercise 058, the current Zig compiler errors are downright misleading for newbies, which makes it way too frustrating to solve the expected issue. (Thanks to @alexgenaud for pointing this out specifically.)

I think this is also the source of the trouble with #120 (Exercise 065).

Instead of relying entirely on the compiler to lead Ziglings victims students to the right place to make a fix, these should be consistently pointed out with something like a comment with "FIX ME".

Additionally, consider expanding ??? sections to ??????... to match the exact length of the expected answer to help out.

Maybe we can remove these extra hints when the Zig Stage 2 compiler comes out (since part of the idea of these exercises is to get you comfortable with reading the compiler's error messages)!

Typo's in some tests

36_enums2.zig has a typo at line 36:

Remeber should be Remember.


37_structs.zig has two typos at line 13 and 14:

//     point1 = Point{ .x=3, .y=16, .y=27 };
//     point2 = Point{ .x=7, .y=13, .y=34 };

Should be:

//     point1 = Point{ .x=3, .y=16, .z =27 };
//     point2 = Point{ .x=7, .y=13, .z =34 };

explaining scopes, visibility and usingnamespace

  1. fix all usages of namespace (I think there was only 1),
  2. recap or summary scope visibility and access as (hopefully sufficiently) outlined above.

Creating an issue here, so it does not get lost in chat history.

`zig build` fails with zig 0.10.0-dev.1888

I came to check out ziglings, got the nightly build from 2022-04-20, and saw the following error.

$ zig version
0.10.0-dev.1888+e3cbea934

$ zig build
/home/user/.local/lib/std/compress/deflate.zig:25:56: error: unable to override alignment of packed struct fields
    const LUTEntry = packed struct { symbol: u16 align(4), len: u16 };
                                                       ^
/home/user/.local/lib/std/builtin.zig:252:19: error: expected type expression, found 'anytype'
        sentinel: anytype,
                  ^

Thank you

I just wanted to say thank you. This learning material is great! I'm an old-time C-programmer and after a couple of hours with your material I'm having a great time in Zig!

Thanks for all the hard work coming up with thorough excercises!

Slight inaccuracy in exercise 19

Seems like a very minor issue but maybe worth fixing.

In exercise 19 the last comment states that:
std.math.pow(type, a, b) takes a numeric type and two numbers of that type
but that doesn't seem to be true, setting my_number to a u8 works fine.

Problem 46, is undefined == null?

First of all, thanks for this project, it makes learning zig so much fun!

Problem 46 asks to make tail optional, when I did it, I also changed the default from undefined to null (tail: ?*Elephant = null,) thinking it needs to be null so the check on line 42 (if (e.tail == null) ) works. However I changed it back to undefined later to see if it would break and it didn't!

So far it seems like undefined == null. I also checked with swapping the values around and what I got is:

  • undefined != undefined
  • null != undefined
  • undefined == null

So undefined == null when a value is optional but not the other way around, and no two undefined are the same.

Maybe there could be a note about this in the exercise, or make a new exercise that explains this?

Zigling #33 doesn't compile on newer versions.

Code

var n = numberMaybeFail(num);
if (n) |value| {
    std.debug.print("=4. ", .{});
} else |err| switch (err) {
    MyNumberError.TooBig => std.debug.print(">4. ", .{}),
}

Result

033_iferror.zig:32:17: error: unused capture
        if (n) |value| {

Easy avoidable by using that value in print(), but I think #33 may need some changes to encourage proper use of that technique.

CR/LF Issue

It should be noted somewhere in the readme that using an editor that produces CRLF at end of line will cause at least one of the lessons to fail, even though it generates the correct output.

Focus is good, but...

I've decide to limit Ziglings to the core language and not attempt coverage of the Standard Library. Perhaps you can change my mind?

I don't necessarily want to change your mind, as it's probably a good idea to keep this repo focused. But what about starting a new repo for other people to contribute similar ziglings aimed at the standard library. If everyone who went through your repo contributed one zigling for the standard library, you'd have an extensive collection in short order!

build in linux gives error about missing windows definitions

$ zig version
0.9.0-dev.2025+ecf0050a9

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 21.10
Release:	21.10
Codename:	impish


ziglings$ zig build
/home/andrea/projects/ziglings/build.zig:504:85: error: use of undeclared identifier 'c_void'
                    extern "kernel32" fn GetStdHandle(id: DWORD) callconv(WINAPI) ?*c_void;
                                                                                    ^
/home/andrea/projects/ziglings/build.zig:505:68: error: use of undeclared identifier 'c_void'
                    extern "kernel32" fn GetConsoleMode(console: ?*c_void, out_mode: *DWORD) callconv(WINAPI) u32;
                                                                   ^
/home/andrea/projects/ziglings/build.zig:506:68: error: use of undeclared identifier 'c_void'
                    extern "kernel32" fn SetConsoleMode(console: ?*c_void, mode: DWORD) callconv(WINAPI) u32;

Looks to me that something is misleading in exercise 59.

I'm not sure if it's error in exercise or compiler or maybe it's just me mistaken but..

Exercise 059 claims that integers can be defined using utf-8 code points..
// const a5: u8 = 'A'; // UTF-8 code point literal

So I tried to use spanish letter ñ. but it's not what got printed out.
zig-utf-8

Ex 50 requires '!s' in std.debug.print

_Compiling 050_no_value.zig...
/snap/zig/5567/lib/std/fmt.zig:508:17: error: cannot format error union without a specifier (i.e. {!} or {any})
@CompileError("cannot format error union without a specifier (i.e. {!} or {any})");
^
/snap/zig/5567/lib/std/fmt.zig:183:23: note: called from here
try formatType(
^
/snap/zig/5567/lib/std/io/writer.zig:28:34: note: called from here
return std.fmt.format(self, format, args);
^
/snap/zig/5567/lib/std/debug.zig:93:27: note: called from here
nosuspend stderr.print(fmt, args) catch return;
^
./exercises/050_no_value.zig:74:20: note: called from here
std.debug.print("{s} {Err!s} / ", .{ first_line1, first_line2 });
^
./exercises/050_no_value.zig:67:20: note: called from here
pub fn main() void {
^
050_no_value.zig: The following command exited with error code 1:
/snap/zig/5567/zig build-exe /home/timos/Projects/zg/ziglings/exercises/050_no_value.zig --cache-dir /home/timos/Projects/zg/ziglings/zig-cache --enable-cache

Edit exercises/050_no_value.zig and run this again.
To continue from this zigling, use this command:
zig build 50_

Line 74
std.debug.print("{s} {!s} / ", .{ first_line1, first_line2 });

Fails with nightly build

The test runner caught this:

patching file patches/healed/091_async8.zig (read from exercises/091_async8.zig)
./build.zig:627:44: error: expected error union type, found 'std.child_process.ChildProcess'
        const child = std.ChildProcess.init(&argv, self.builder.allocator) catch unreachable;
                                           ^
Error: Process completed with exit code 1.

Exercise 047 - Need explanation for for loop syntax `*alien`?

In exercise 047, we have this line:

        // Loop through every alien...
        for (aliens) |*alien| {

            // *** Zap the Alien Here! ***
            ???.zap(heat_ray_strength);

And I don't know what *alien represents. I tried using alien and the compiler complains that error: expected type '*Alien', found '*const Alien'. I tried using &alien and the compiler complains that error: expected 'an identifier', found '&'.

But in Ziglings we haven't covered this syntax? Why wouldn't alien or &alien (like Rust's pattern match) work? Thanks :)

Ex. 10 unexpectedly fails due to missing type

Ex. 10 is focused on if expressions. The line we are supposed to be fixing is:

var price = if ???;

My first attempt at fixing this was:

var price = if (discount) 17 else 20;

which resulted in error:

./exercises/10_if2.zig:13:31: error: cannot store runtime value in type 'comptime_int'
    var price = if (discount) 17 else 20;
                              ^

It took me awhile to figure out that I needed to add the type:

var price: u8 = if (discount) 17 else 20;

I'm not sure if that additional challenge was intended. The example in that file gave a good hint that type would be needed, but up to this point in the exercises, the "challenge" was always explicit. The missing type deceleration for price was an implicit challenge and broke the pattern I was expecting up to this point.

IMO, remove the implicit nature of the challenge by adding the type to the line, adding a hint in the comments that some extra troubleshooting will be involved, or another "???" where the type should go.

Thanks.

Reasoning for #10 is wrong.

https://github.com/ratfactor/ziglings/blob/main/exercises/10_if2.zig#L12

Here you say the reason that it fails is that the compiler is not smart enough, but this is not true.
The error is

./main.zig:4:1: error: variable of type 'comptime_int' must be const or comptime
var i = if (true) 1 else 2;
^
./main.zig:2:29: note: referenced here
pub fn main() anyerror!void {
                            ^

The reason is that you cannot have a comptime_int variable in a non comptime scope. The compiler is smart enough to do peer type resolution.
For example, this works:

var b: bool = true;
var x = if (b) null else @as(u32, 5);
if (@TypeOf(x) != ?u32) @panic("OOF");

This example should be fixed and an explanation of peer type resolution should probably be made.

o

Hi,

I just wanted to say that the o editor is a great fit for solving the ziglings exercises.

When editing ie. 03_assignment.zig, it's possible to just press ctrl-space and the cursor will jump to the problematic location, while the error message is displayed at the bottom of the screen. It is intended to help lowering the threshold of getting started with Zig.

The o editor is configuration-free.

I guess this is a feature request for mentioning o in the README, if you should happen to like it.

Thanks for making the ziglings exercises!

Best regards,
Alexander F. Rødseth

Automatic progression is a slight useability issue

Running zig build 0X can produce errors (or not) for the current exercise. When the exercise succeeds however it progresses immediately to the next one and so the screen fills with errors again. I find two issues here:

  1. Although there is some green to indicate success, my initial reaction is that the exercise failed. I have lots of text to parse to work out what happened. In my mind zig build $TARGET is equivalent to make $TARGET which generally only indicates success or not and then stops.
  2. I've asked to build something, but depending on the outcome it ends up also building something else. This is unexpected. I may or may not want to re-edit and play around with the current exercise before moving on.

Perhaps something like (just guessing here) zig build could use auto progression and zig build $TARGET could stop after success? Or at least zig build $TARGET should only run the next compilation after a "SUCCESS! Continue to exercise $TARGET+1? [Y/n]" or similar prompt.

p.s. Thanks for your hard work so far!

typo in comment at 066_comptime.zig:44

    // When we use these identifiers in our program, the VALUES
    // are inserted at compile time into the executable code. The
    // identifiers "my_int" and "my_float" don't really exist in
    // our compiled application and do not refer to any
    // particular areas of memory!
    const const_int = 12345;
    const const_float = 987.654;

The comment should reference const_int and const_float instead of my_int and my_float.

Ex 65 doesn't build

It fails with this error after the other problems have been solved.

Compiling 065_builtins2.zig...
.\exercises\065_builtins2.zig:56:5: error: unable to evaluate constant expression
    var narcissus: Narcissus = Narcissus{};

could you add more hints on "create our own path language"?

sorry to bother you with a question.

this issue comes from the 75th exercise.
i know pyparsing or regex can be used to do this in python world, but i can not find any equivalent in zig. i must missed some thing in the previous exercises. (i tried to ask in zig discord, but had not get any replies)

Unclear why garbage values are what they are in 38

Hey, thanks a lot for the ziglings! They really are helping me get started.

In zigling number 38 you mention

    // Feel free to run this program without adding Zump. What does
    // it do and why?

For me it was unclear why exactly the garbage values are what they are. (2863311530, 170 and 2863311530).

So I went out and looked a bit to discover that they are basically just filled with 0xAAAAAA...

Then someone in the zig matrix room sent me the link to the zig documentation, clarifying why exactly this was the case

According to your contribution guidelines ziglings should be self contained, which this broke for me.

That is unless I missed something in an earlier zigling that explained this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.