From 9b38f3584b85e9396ebd19d6ca8966b980022a93 Mon Sep 17 00:00:00 2001
From: Chris Boesch <chrboesch@noreply.codeberg.org>
Date: Sat, 11 Feb 2023 11:12:47 +0100
Subject: [PATCH 1/6] first draft for interfaces

---
 exercises/092_interfaces.zig | 88 ++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 exercises/092_interfaces.zig

diff --git a/exercises/092_interfaces.zig b/exercises/092_interfaces.zig
new file mode 100644
index 0000000..f9f9dc3
--- /dev/null
+++ b/exercises/092_interfaces.zig
@@ -0,0 +1,88 @@
+//
+// Remeber excerice xx with tagged unions. That was a lot more better
+// but it's can bee perfect.
+//
+// With tagged unions, it gets EVEN BETTER! If you don't have a
+// need for a separate enum, you can define an inferred enum with
+// your union all in one place. Just use the 'enum' keyword in
+// place of the tag type:
+//
+//     const Foo = union(enum) {
+//         small: u8,
+//         medium: u32,
+//         large: u64,
+//     };
+//
+// Let's convert Insect. Doctor Zoraptera has already deleted the
+// explicit InsectStat enum for you!
+//
+const std = @import("std");
+
+const Ant = struct {
+    still_alive: bool,
+
+    pub fn print(self: Ant) void {
+        std.debug.print("Ant is {s}.\n", .{if (self.still_alive) "alive" else "death"});
+    }
+};
+
+const Bee = struct {
+    flowers_visited: u16,
+
+    pub fn print(self: Bee) void {
+        std.debug.print("Bee visited {} flowers.\n", .{self.flowers_visited});
+    }
+};
+
+const Grasshopper = struct {
+    distance_hopped: u16,
+
+    pub fn print(self: Grasshopper) void {
+        std.debug.print("Grasshopper hopped {} m.\n", .{self.distance_hopped});
+    }
+};
+
+const Insect = union(enum) {
+    ant: Ant,
+    bee: Bee,
+    grasshopper: Grasshopper,
+
+    pub fn print(self: Insect) void {
+        switch (self) {
+            inline else => |case| return case.print(),
+        }
+    }
+};
+
+pub fn main() !void {
+    var my_insects = [_]Insect{ Insect{
+        .ant = Ant{ .still_alive = true },
+    }, Insect{
+        .bee = Bee{ .flowers_visited = 17 },
+    }, Insect{
+        .grasshopper = Grasshopper{ .distance_hopped = 32 },
+    } };
+
+    try dailyReport(&my_insects);
+}
+
+fn dailyReport(insectReport: []Insect) !void {
+    std.debug.print("Daily insect report:\n", .{});
+    for (insectReport) |insect| {
+        insect.print();
+    }
+}
+
+// Inferred enums are neat, representing the tip of the iceberg
+// in the relationship between enums and unions. You can actually
+// coerce a union TO an enum (which gives you the active field
+// from the union as an enum). What's even wilder is that you can
+// coerce an enum to a union! But don't get too excited, that
+// only works when the union type is one of those weird zero-bit
+// types like void!
+//
+// Tagged unions, as with most ideas in computer science, have a
+// long history going back to the 1960s. However, they're only
+// recently becoming mainstream, particularly in system-level
+// programming languages. You might have also seen them called
+// "variants", "sum types", or even "enums"!

From 35c5d6b976edb16c484e278aabc3d750e2880a77 Mon Sep 17 00:00:00 2001
From: Chris Boesch <chrboesch@noreply.codeberg.org>
Date: Sat, 11 Feb 2023 11:43:09 +0100
Subject: [PATCH 2/6] added 092_interfaces to build

---
 build.zig                    |  9 +++++----
 exercises/092_interfaces.zig | 36 ++++++++----------------------------
 2 files changed, 13 insertions(+), 32 deletions(-)

diff --git a/build.zig b/build.zig
index 4312fb7..03e83e9 100644
--- a/build.zig
+++ b/build.zig
@@ -460,6 +460,10 @@ const exercises = [_]Exercise{
     //     .output = "ABCDEF",
     //     .@"async" = true,
     // },
+    .{
+        .main_file = "092_interfaces.zig",
+        .output = "Daily insect report:\nAnt is alive.\nBee visited 17 flowers.\nGrasshopper hopped 32 m.",
+    },
     .{
         .main_file = "999_the_end.zig",
         .output = "\nThis is the end for now!\nWe hope you had fun and were able to learn a lot, so visit us again when the next exercises are available.",
@@ -564,10 +568,7 @@ pub fn build(b: *Builder) void {
         const file_path = std.fs.path.join(b.allocator, &[_][]const u8{
             if (use_healed) "patches/healed" else "exercises", ex.main_file,
         }) catch unreachable;
-        const build_step = b.addExecutable(.{
-            .name = base_name,
-            .root_source_file = .{ .path = file_path }
-        });
+        const build_step = b.addExecutable(.{ .name = base_name, .root_source_file = .{ .path = file_path } });
 
         build_step.install();
 
diff --git a/exercises/092_interfaces.zig b/exercises/092_interfaces.zig
index f9f9dc3..45f9d8e 100644
--- a/exercises/092_interfaces.zig
+++ b/exercises/092_interfaces.zig
@@ -1,20 +1,7 @@
 //
-// Remeber excerice xx with tagged unions. That was a lot more better
-// but it's can bee perfect.
+// Remeber excerices 55-57 with tagged unions.
 //
-// With tagged unions, it gets EVEN BETTER! If you don't have a
-// need for a separate enum, you can define an inferred enum with
-// your union all in one place. Just use the 'enum' keyword in
-// place of the tag type:
-//
-//     const Foo = union(enum) {
-//         small: u8,
-//         medium: u32,
-//         large: u64,
-//     };
-//
-// Let's convert Insect. Doctor Zoraptera has already deleted the
-// explicit InsectStat enum for you!
+// (story/explanation from Dave)
 //
 const std = @import("std");
 
@@ -63,9 +50,14 @@ pub fn main() !void {
         .grasshopper = Grasshopper{ .distance_hopped = 32 },
     } };
 
+    // The daily situation report, what's going on in the garden
     try dailyReport(&my_insects);
 }
 
+// Through the interface we can keep a list of various objects
+// (in this case the insects of our garden) and even pass them
+// to a function without having to know the specific properties
+// of each or the object itself. This is really cool!
 fn dailyReport(insectReport: []Insect) !void {
     std.debug.print("Daily insect report:\n", .{});
     for (insectReport) |insect| {
@@ -73,16 +65,4 @@ fn dailyReport(insectReport: []Insect) !void {
     }
 }
 
-// Inferred enums are neat, representing the tip of the iceberg
-// in the relationship between enums and unions. You can actually
-// coerce a union TO an enum (which gives you the active field
-// from the union as an enum). What's even wilder is that you can
-// coerce an enum to a union! But don't get too excited, that
-// only works when the union type is one of those weird zero-bit
-// types like void!
-//
-// Tagged unions, as with most ideas in computer science, have a
-// long history going back to the 1960s. However, they're only
-// recently becoming mainstream, particularly in system-level
-// programming languages. You might have also seen them called
-// "variants", "sum types", or even "enums"!
+// Interfaces... (explanation from Dave)

From bb4b321b0c848a5262d7bd75d70912528be74b0a Mon Sep 17 00:00:00 2001
From: Chris Boesch <chrboesch@noreply.codeberg.org>
Date: Tue, 14 Feb 2023 09:11:46 +0100
Subject: [PATCH 3/6] created an empty patch for testing until the exercise is
 finished

---
 patches/patches/092_interfaces.patch | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 patches/patches/092_interfaces.patch

diff --git a/patches/patches/092_interfaces.patch b/patches/patches/092_interfaces.patch
new file mode 100644
index 0000000..ce3141f
--- /dev/null
+++ b/patches/patches/092_interfaces.patch
@@ -0,0 +1,3 @@
+68a69,70
+> //
+> // just an empty patch

From beaa89fdf570b58c25f33f72715f6fa8ca2cd8a5 Mon Sep 17 00:00:00 2001
From: Chris Boesch <chrboesch@noreply.codeberg.org>
Date: Tue, 14 Feb 2023 12:58:12 +0100
Subject: [PATCH 4/6] inserted a failure and created a patch

---
 exercises/092_interfaces.zig         | 2 +-
 patches/patches/092_interfaces.patch | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/exercises/092_interfaces.zig b/exercises/092_interfaces.zig
index 45f9d8e..5adc9c0 100644
--- a/exercises/092_interfaces.zig
+++ b/exercises/092_interfaces.zig
@@ -51,7 +51,7 @@ pub fn main() !void {
     } };
 
     // The daily situation report, what's going on in the garden
-    try dailyReport(&my_insects);
+    try dailyReport("what is here the right parameter?");
 }
 
 // Through the interface we can keep a list of various objects
diff --git a/patches/patches/092_interfaces.patch b/patches/patches/092_interfaces.patch
index ce3141f..67fc443 100644
--- a/patches/patches/092_interfaces.patch
+++ b/patches/patches/092_interfaces.patch
@@ -1,3 +1,4 @@
-68a69,70
-> //
-> // just an empty patch
+54c54
+<     try dailyReport("what is here the right parameter?");
+---
+>     try dailyReport(&my_insects);

From 662086cb898ab96431edc38b969664e60e0d9d96 Mon Sep 17 00:00:00 2001
From: Dave Gauer <dave@ratfactor.com>
Date: Wed, 15 Feb 2023 17:45:10 -0500
Subject: [PATCH 5/6] Added story/explanation to new ex. 092

---
 build.zig                            |   2 +-
 exercises/092_interfaces.zig         | 107 +++++++++++++++++++++------
 patches/patches/092_interfaces.patch |   6 +-
 3 files changed, 87 insertions(+), 28 deletions(-)

diff --git a/build.zig b/build.zig
index 03e83e9..50faf23 100644
--- a/build.zig
+++ b/build.zig
@@ -462,7 +462,7 @@ const exercises = [_]Exercise{
     // },
     .{
         .main_file = "092_interfaces.zig",
-        .output = "Daily insect report:\nAnt is alive.\nBee visited 17 flowers.\nGrasshopper hopped 32 m.",
+        .output = "Daily Insect Report:\nAnt is alive.\nBee visited 17 flowers.\nGrasshopper hopped 32 meters.",
     },
     .{
         .main_file = "999_the_end.zig",
diff --git a/exercises/092_interfaces.zig b/exercises/092_interfaces.zig
index 5adc9c0..43f1119 100644
--- a/exercises/092_interfaces.zig
+++ b/exercises/092_interfaces.zig
@@ -1,7 +1,55 @@
 //
-// Remeber excerices 55-57 with tagged unions.
+// Remember our ant and bee simulator constructed with unions
+// back in exercises 55 and 56? There, we demonstrated that
+// unions allow us to treat different data types in a uniform
+// manner.
 //
-// (story/explanation from Dave)
+// One neat feature was using tagged unions to create a single
+// function to print a status for ants *or* bees by switching:
+//
+//   switch (insect) {
+//      .still_alive => ...      // (print ant stuff)
+//      .flowers_visited => ...  // (print bee stuff)
+//   }
+//
+// Well, that simulation was running just fine until a new insect
+// arrived in the virtual garden, a grasshopper!
+//
+// Doctor Zoraptera started to add grasshopper code to the
+// program, but then she backed away from her keyboard with an
+// angry hissing sound. She had realized that having code for
+// each insect in one place and code to print each insect in
+// another place was going to become unpleasant to maintain when
+// the simulation expanded to hundreds of different insects.
+//
+// Thankfully, Zig has another comptime feature we can use
+// to get out of this dilema called the 'inline else'.
+//
+// We can replace this redundant code:
+//
+//   switch (thing) {
+//       .a => |a| special(a),
+//       .b => |b| normal(b),
+//       .c => |c| normal(c),
+//       .d => |d| normal(d),
+//       .e => |e| normal(e),
+//       ...
+//   }
+//
+// With:
+//
+//   switch (thing) {
+//       .a => |a| special(a),
+//       inline else |t| => normal(t),
+//   }
+//
+// We can have special handling of some cases and then Zig
+// handles the rest of the matches for us.
+//
+// With this feature, you decide to make an Insect union with a
+// single uniform 'print()' function. All of the insects can
+// then be responsible for printing themselves. And Doctor
+// Zoraptera can calm down and stop gnawing on the furniture.
 //
 const std = @import("std");
 
@@ -9,7 +57,7 @@ const Ant = struct {
     still_alive: bool,
 
     pub fn print(self: Ant) void {
-        std.debug.print("Ant is {s}.\n", .{if (self.still_alive) "alive" else "death"});
+        std.debug.print("Ant is {s}.\n", .{if (self.still_alive) "alive" else "dead"});
     }
 };
 
@@ -21,11 +69,13 @@ const Bee = struct {
     }
 };
 
+// Here's the new grasshopper. Notice how we've also added print
+// methods to each insect.
 const Grasshopper = struct {
     distance_hopped: u16,
 
     pub fn print(self: Grasshopper) void {
-        std.debug.print("Grasshopper hopped {} m.\n", .{self.distance_hopped});
+        std.debug.print("Grasshopper hopped {} meters.\n", .{self.distance_hopped});
     }
 };
 
@@ -34,6 +84,10 @@ const Insect = union(enum) {
     bee: Bee,
     grasshopper: Grasshopper,
 
+    // Thanks to 'inline else', we can think of this print() as
+    // being an interface method. Any member of this union with
+    // with a print() method can be treated uniformly by outside
+    // code without needing to know any other details. Cool!
     pub fn print(self: Insect) void {
         switch (self) {
             inline else => |case| return case.print(),
@@ -42,27 +96,32 @@ const Insect = union(enum) {
 };
 
 pub fn main() !void {
-    var my_insects = [_]Insect{ Insect{
-        .ant = Ant{ .still_alive = true },
-    }, Insect{
-        .bee = Bee{ .flowers_visited = 17 },
-    }, Insect{
-        .grasshopper = Grasshopper{ .distance_hopped = 32 },
-    } };
+    var my_insects = [_]Insect{
+        Insect{ .ant = Ant{ .still_alive = true } },
+        Insect{ .bee = Bee{ .flowers_visited = 17 } },
+        Insect{ .grasshopper = Grasshopper{ .distance_hopped = 32 }, },
+    };
 
-    // The daily situation report, what's going on in the garden
-    try dailyReport("what is here the right parameter?");
-}
-
-// Through the interface we can keep a list of various objects
-// (in this case the insects of our garden) and even pass them
-// to a function without having to know the specific properties
-// of each or the object itself. This is really cool!
-fn dailyReport(insectReport: []Insect) !void {
-    std.debug.print("Daily insect report:\n", .{});
-    for (insectReport) |insect| {
-        insect.print();
+    std.debug.print("Daily Insect Report:\n", .{});
+    for (my_insects) |insect| {
+        // Almost done! We want to print() each insect with a
+        // single method call here.
+        ???
     }
 }
 
-// Interfaces... (explanation from Dave)
+// Our print() method in the Insect union above demonstrates
+// something very similar to the object-oriented concept of an
+// abstract data type. That is, the Insect type doesn't contain
+// the underlying data, and the print() function doesn't
+// actually do the printing.
+//
+// The point of an interface is to support generic programming:
+// the ability to treat different things as if they were the
+// same to cut down on clutter and conceptual complexity.
+//
+// The Daily Insect Report doesn't need to worry about *which*
+// insects are in the report - they all print the same way via
+// the interface!
+//
+// Doctor Zoraptera loves it.
diff --git a/patches/patches/092_interfaces.patch b/patches/patches/092_interfaces.patch
index 67fc443..1287e79 100644
--- a/patches/patches/092_interfaces.patch
+++ b/patches/patches/092_interfaces.patch
@@ -1,4 +1,4 @@
-54c54
-<     try dailyReport("what is here the right parameter?");
+109c109
+<         ???
 ---
->     try dailyReport(&my_insects);
+>         insect.print();

From 4a63c43c1f18cf1fb98dc579f3f7bdcc27c3b336 Mon Sep 17 00:00:00 2001
From: Chris Boesch <chrboesch@noreply.codeberg.org>
Date: Thu, 16 Feb 2023 10:35:15 +0100
Subject: [PATCH 6/6] 'Interfaces' check marked

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d355411..85f656c 100644
--- a/README.md
+++ b/README.md
@@ -164,7 +164,7 @@ Core Language
 * [x] Quoted identifiers @""
 * [x] Anonymous structs/tuples/lists
 * [ ] Async <--- IN PROGRESS!
-* [ ] Interfaces <--- IN PROGRESS!
+* [X] Interfaces
 * [ ] Working with C
 
 ## Contributing