From 28791f0cb8df075199862b1367e3ed3ede692fd7 Mon Sep 17 00:00:00 2001 From: Dave Gauer Date: Sun, 28 Feb 2021 18:36:38 -0500 Subject: [PATCH] Add ex 50 'no values' (help further address #25) --- build.zig | 5 +- exercises/50_no_value.zig | 84 +++++++++++++++++++++++++++++++ patches/patches/50_no_value.patch | 14 ++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 exercises/50_no_value.zig create mode 100644 patches/patches/50_no_value.patch diff --git a/build.zig b/build.zig index a116b0c..7892117 100644 --- a/build.zig +++ b/build.zig @@ -260,7 +260,10 @@ const exercises = [_]Exercise{ .output = "A B C Cv Bv Av", .hint = "Now you're writting Zig!", }, - // 50 null vs undefined + .{ + .main_file = "50_no_value.zig", + .output = "That is not dead which can eternal lie / And with strange aeons even death may die.", + }, // 51 pass-by-value and const fn params // 52 slices! }; diff --git a/exercises/50_no_value.zig b/exercises/50_no_value.zig new file mode 100644 index 0000000..8708d2d --- /dev/null +++ b/exercises/50_no_value.zig @@ -0,0 +1,84 @@ +// +// "We live on a placid island of ignorance in the midst +// of black seas of infinity, and it was not meant that +// we should voyage far." +// +// from The Call of Cthulhu +// by H. P. Lovecraft +// +// Zig has at least four ways of expressing "no value": +// +// * undefined +// +// var foo: u8 = undefined; +// +// "undefined" should not be thought of as a value, but as a way +// of telling the compiler that you are not assigning a value +// _yet_. Any type may be set to undefined, but attempting +// to read or use that value is _always_ a mistake. +// +// * null +// +// var foo: ?u8 = null; +// +// The "null" primitive value _is_ a value that means "no value". +// This is typically used with optional types as with the ?u8 +// shown above. When foo equals null, that's not a value of type +// u8. It means there is _no value_ of type u8 in foo at all! +// +// * error +// +// var foo: MyError!u8 = BadError; +// +// Errors are _very_ similar to nulls. They _are_ a value, but +// they usually indicate that the "real value" you were looking +// for does not exist. Instead, you have an error. The example +// error union type of MyError!u8 means that foo either holds +// a u8 value OR an error. There is _no value_ of type u8 in foo +// when it's set to an error! +// +// * void +// +// var foo: void = {}; +// +// "void" is a _type_, not a value. It is the most popular of the +// Zero Bit Types (those types which take up absolutely no space +// and have only a semantic value. When compiled to executable +// code, zero bit types generate no code at all. The above example +// shows a variable foo of type void which is assigned the value +// of an empty expression. It's much more common to see void as +// the return type of a function that returns nothing. +// +// Zig has all of these ways of expressing different types of "no value" +// because they each serve a purpose. Briefly: +// +// * undefined - there is no value YET, this cannot be read YET +// * null - there is an explicit value of "no value" +// * errors - there is no value because something went wrong +// * void - there will NEVER be a value stored here +// +// Please use the correct "no value" for each ??? to make this program +// print out a cursed quote from the Necronomicon. ...If you dare. +// +const std = @import("std"); + +const Err = error{Cthulhu}; + +pub fn main() void { + var first_line1: *const [16]u8 = ???; + first_line1 = "That is not dead"; + + var first_line2: Err!*const [21]u8 = ???; + first_line2 = "which can eternal lie"; + + std.debug.print("{s} {s} / ", .{ first_line1, first_line2 }); + + printSecondLine(); +} + +fn printSecondLine() ??? { + var second_line2: ?*const [18]u8 = ???; + second_line2 = "even death may die"; + + std.debug.print("And with strange aeons {s}.\n", .{second_line2.?}); +} diff --git a/patches/patches/50_no_value.patch b/patches/patches/50_no_value.patch new file mode 100644 index 0000000..79db0a3 --- /dev/null +++ b/patches/patches/50_no_value.patch @@ -0,0 +1,14 @@ +68c68 +< var first_line1: *const [16]u8 = ???; +--- +> var first_line1: *const [16]u8 = undefined; +71c71 +< var first_line2: Err!*const [21]u8 = ???; +--- +> var first_line2: Err!*const [21]u8 = Err.Cthulhu; +79,80c79,80 +< fn printSecondLine() ??? { +< var second_line2: ?*const [18]u8 = ???; +--- +> fn printSecondLine() void { +> var second_line2: ?*const [18]u8 = null;