diff --git a/chapter_08/examples/2_any/with_header_files/CMakeLists.txt b/chapter_08/examples/2_any/with_header_files/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5e3af96a7ee4723f106b4d0f9ca31e5091243341
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.28)
+
+project(polymorphic_w_any CXX)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set (CMAKE_CXX_STANDARD 23)
+set (CMAKE_CXX_STANDARD_REQUIRED ON)
+set(Headers Point.hh Polygon.hh Triangle.hh Circle.hh)
+add_executable(${PROJECT_NAME} Point.cc Triangle.cc Circle.cc main.cc ${Headers})
+
diff --git a/chapter_08/examples/2_any/with_header_files/Circle.cc b/chapter_08/examples/2_any/with_header_files/Circle.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6ae0fa5582a3385e0d4f1c1480d956797f994e46
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/Circle.cc
@@ -0,0 +1,26 @@
+#include "Circle.hh"
+
+constexpr double pi = 3.141592653589793;
+
+Circle::Circle(double rad, const Point& p)
+    : r{ rad }
+    , c{ p }
+{
+}
+
+double Circle::area() const
+{
+    return pi * r * r;
+}
+
+double Circle::perimeter() const
+{
+    return 2 * pi * r;
+}
+
+void Circle::rotate(double phi) { phi = 0; }
+
+void Circle::translate(Point p)
+{
+    c += p;
+}
diff --git a/chapter_08/examples/2_any/with_header_files/Circle.hh b/chapter_08/examples/2_any/with_header_files/Circle.hh
new file mode 100644
index 0000000000000000000000000000000000000000..adee3d74ca3c027cd74ddd180782fb4aed86fef9
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/Circle.hh
@@ -0,0 +1,26 @@
+#ifndef Circle_HH
+#define Circle_HH
+#include "Point.hh"
+#include <string>
+
+class Circle {
+public:
+    Circle() = default;
+    Circle(double rad, const Point& p);
+    Circle(const Circle& cir) = default;
+    Circle(Circle&& cir) = default;
+    Circle& operator=(const Circle& cir) = default;
+    Circle& operator=(Circle&& cir) = default;
+    std::string name() const { return "Circle"; }
+    void rotate(double phi);
+    void translate(Point p);
+    double area() const;
+    double perimeter() const;
+    inline double circumference() const { return perimeter(); }
+
+private:
+    double r{ 1.0 };
+    Point c{}; // Use default constructor of class Point to create c
+};
+
+#endif
diff --git a/chapter_08/examples/2_any/with_header_files/Point.cc b/chapter_08/examples/2_any/with_header_files/Point.cc
new file mode 100644
index 0000000000000000000000000000000000000000..74ddec6e7e995d547fd04da729d083a8c6ad1bfc
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/Point.cc
@@ -0,0 +1,53 @@
+#include "Point.hh"
+#include <iostream>
+
+Point::Point(double x, double y)
+    : X{ x }
+    , Y{ y }
+{
+}
+
+Point& Point::operator+=(const Point& p)
+{
+    X += p.X;
+    Y += p.Y;
+    return *this;
+}
+
+Point& Point::operator-=(const Point& p)
+{
+    X -= p.X;
+    Y -= p.Y;
+    return *this;
+}
+
+Point Point::operator+(const Point& p) const
+{
+    return { X + p.X, Y + p.Y };
+}
+
+Point Point::operator-(const Point& p) const
+{
+    return { X - p.X, Y - p.Y };
+}
+
+double Point::operator*(const Point& p) const
+{
+    return (X * p.X + Y * p.Y);
+}
+
+Point Point::operator*(double f) const
+{
+    return { f * X, f * Y };
+}
+
+Point operator*(double f, const Point& p)
+{
+    return { f * p.X, f * p.Y };
+}
+
+std::ostream& operator<<(std::ostream& os, const Point& p)
+{
+    os << "(" << p.X << ", " << p.Y << ")";
+    return os;
+}
diff --git a/chapter_08/examples/2_any/with_header_files/Point.hh b/chapter_08/examples/2_any/with_header_files/Point.hh
new file mode 100644
index 0000000000000000000000000000000000000000..009c99a6dcfddc155364e2465cc31da8ec785e0f
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/Point.hh
@@ -0,0 +1,23 @@
+#ifndef Point_HH
+#define Point_HH
+class ostream;
+struct Point {
+    double X = 0, Y = 0;
+    Point() = default;
+    Point(const Point&) = default;
+    Point(Point&&) = default;
+    Point& operator=(const Point& p) = default;
+    Point& operator=(Point&& p) = default;
+    Point(double x, double y);
+    Point& operator+=(const Point& p);
+    Point& operator-=(const Point& p);
+    Point operator+(const Point& p) const;
+    Point operator-(const Point& p) const;
+    double operator*(const Point& p) const;
+    Point operator*(double f) const;
+};
+
+Point operator*(double f, const Point& p);
+ostream& operator<<(ostream& os, const Point& p);
+
+#endif
diff --git a/chapter_08/examples/2_any/with_header_files/Polygon.hh b/chapter_08/examples/2_any/with_header_files/Polygon.hh
new file mode 100644
index 0000000000000000000000000000000000000000..8c71504ae0e64fe47441651b1a339997f1c2676c
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/Polygon.hh
@@ -0,0 +1,53 @@
+#ifndef Polygon_HH
+#define Polygon_HH
+#include "Point.hh"
+#include <array>
+#include <cmath>
+#include <string>
+
+template <unsigned int NV>
+class Polygon {
+    static_assert(NV > 2, "Can't have polygon with less than 3 sides");
+
+public:
+    Polygon() = default;
+    Polygon(const Polygon&) = default;
+    Polygon(Polygon&&) = default;
+    Polygon& operator=(const Polygon& pg) = default;
+    Polygon& operator=(Polygon&&) = default;
+    constexpr auto n_vertexes() const { return NV; }
+    std::string name() const { return "Polygon<" + std::to_string(NV) + ">"; }
+
+    double perimeter() const
+    {
+        double ans = 0;
+        for (size_t i = 1; i < vertex.size(); ++i) {
+            ans += sqrt((vertex[i] - vertex[i - 1]) * (vertex[i] - vertex[i - 1]));
+        }
+        ans += sqrt((vertex.front() - vertex.back()) * (vertex.front() - vertex.back()));
+        return ans;
+    }
+    void translate(Point p)
+    {
+        for (auto& pt : vertex)
+            pt += p;
+    }
+
+    void rotate(double phi)
+    {
+        Point center;
+        for (auto pt : vertex)
+            center += pt;
+        center = (1.0 / NV) * center;
+        double ct = cos(phi), st = sin(phi);
+        for (auto& pt : vertex) {
+            auto rel = pt - center;
+            pt = center + Point(ct * rel.X + st * rel.Y, -st * rel.X + ct * rel.Y);
+        }
+    }
+
+protected:
+    std::array<Point, NV> vertex;
+};
+
+#endif
diff --git a/chapter_08/examples/2_any/with_header_files/Triangle.cc b/chapter_08/examples/2_any/with_header_files/Triangle.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b27b4ae583252f7ad306f65146f668e1f49adbba
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/Triangle.cc
@@ -0,0 +1,22 @@
+#include "Triangle.hh"
+#include <cmath>
+// A "static" function in a source file (not a static member function of a class)
+// is meant to be visible only in the same translation unit, most often just that
+// source file.
+static inline double sqr(Point p) { return p * p; }
+
+Triangle::Triangle(Point p1, Point p2, Point p3)
+{
+    vertex[0] = p1;
+    vertex[1] = p2;
+    vertex[2] = p3;
+}
+
+double Triangle::area() const
+{
+    double s = 0.5 * perimeter();
+    double a = sqrt(sqr(vertex[0] - vertex[1]));
+    double b = sqrt(sqr(vertex[0] - vertex[2]));
+    double c = sqrt(sqr(vertex[1] - vertex[2]));
+    return sqrt(s * (s - a) * (s - b) * (s - c));
+}
diff --git a/chapter_08/examples/2_any/with_header_files/Triangle.hh b/chapter_08/examples/2_any/with_header_files/Triangle.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c360fc50f97a275711454e8fe1eda0c0680b9fbe
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/Triangle.hh
@@ -0,0 +1,9 @@
+#include "Polygon.hh"
+
+class Triangle : public Polygon<3> {
+public:
+    using Polygon<3>::Polygon;
+    using Polygon<3>::operator=;
+    Triangle(Point p1, Point p2, Point p3);
+    double area() const;
+};
diff --git a/chapter_08/examples/2_any/with_header_files/main.cc b/chapter_08/examples/2_any/with_header_files/main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7bbab1e58c41f6d88dbd02fef9b19bb6e0a86efc
--- /dev/null
+++ b/chapter_08/examples/2_any/with_header_files/main.cc
@@ -0,0 +1,91 @@
+#include "Circle.hh"
+#include "Triangle.hh"
+#include <chrono>
+#include <random>
+#include <iostream>
+#include <vector>
+#include <any>
+
+constexpr auto N = 100000ul;
+std::mt19937_64 engine;
+std::discrete_distribution sel{ 0.5, 0.5 };
+std::exponential_distribution length{ 1.0 };
+
+using element_type = std::any;
+
+auto name(const std::vector<element_type>& v, size_t i)
+{
+    if (v[i].type() == typeid(Triangle)) {
+        return std::any_cast<Triangle>(v[i]).name();
+    } else {
+        return std::any_cast<Circle>(v[i]).name();
+    }
+}
+
+auto area(const std::vector<element_type>& v, size_t i)
+{
+    if (v[i].type() == typeid(Triangle)) {
+        return std::any_cast<Triangle>(v[i]).area();
+    } else {
+        return std::any_cast<Circle>(v[i]).area();
+    }
+}
+
+void construct_objects(std::vector<element_type>& v)
+{
+    for (auto i = 0ul; i < N; ++i) {
+        auto isel = sel(engine);
+        switch (isel) {
+        case 0: {
+            auto radius = length(engine);
+            auto centrepos = Point(length(engine), length(engine));
+            v.emplace_back(std::in_place_type_t<Circle>{}, radius, centrepos);
+            break;
+        }
+        case 1: {
+            auto v1 = Point(length(engine), length(engine));
+            auto v2 = Point(length(engine), length(engine));
+            auto v3 = Point(length(engine), length(engine));
+            v.emplace_back(std::in_place_type_t<Triangle>{}, v1, v2, v3);
+            break;
+        }
+        };
+    }
+}
+
+void calc_area_all(const std::vector<element_type>& v)
+{
+    auto max_loc = 0ul;
+    auto max_area = 0.;
+    for (size_t i = 0; i < v.size(); ++i) {
+        auto ar = area(v, i);
+        if (i < 5) {
+            std::cout << i << ": " << name(v, i) << " with area "
+                      << ar << "\n";
+        }
+        if (ar > max_area) {
+            max_loc = i;
+        }
+    }
+
+    std::cout << "Largest object: \n";
+    auto nm = name(v, max_loc);
+    auto ar = area(v, max_loc);
+    std::cout << "Name : " << nm << ", area = " << ar << "\n";
+}
+
+int main()
+{
+    std::vector<element_type> shapes;
+    shapes.reserve(N);
+
+    auto t0 = std::chrono::steady_clock::now();
+    construct_objects(shapes);
+    auto t1 = std::chrono::steady_clock::now();
+    calc_area_all(shapes);
+    auto t2 = std::chrono::steady_clock::now();
+    std::cout << "Object creation time for " << N << " objects, "
+              << std::chrono::duration<double>(t1 - t0).count() << "\n"
+              << "Area evaluation time for " << N << " objects, "
+              << std::chrono::duration<double>(t2 - t1).count() << "\n";
+}
diff --git a/chapter_08/examples/2_any/with_modules/CMakeLists.txt b/chapter_08/examples/2_any/with_modules/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..60572bd768811f0f3b5947266a9513ae1b23d4bd
--- /dev/null
+++ b/chapter_08/examples/2_any/with_modules/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.28)
+
+set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+project(polymorphic_with_any)
+
+add_executable(polyany)
+target_sources(polyany
+    PUBLIC
+    main.cc
+)
+target_sources(polyany
+  PUBLIC
+    FILE_SET geometry_modules TYPE CXX_MODULES FILES
+    Point.ixx
+    Circle.ixx
+    Polygon.ixx
+    Triangle.ixx
+)
+
diff --git a/chapter_08/examples/2_any/with_modules/Circle.ixx b/chapter_08/examples/2_any/with_modules/Circle.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..4793712c1f61e1ffb7d04a53ff039f4025120880
--- /dev/null
+++ b/chapter_08/examples/2_any/with_modules/Circle.ixx
@@ -0,0 +1,51 @@
+module;
+#include <string>
+#include <numbers>
+export module Circle;
+import Point;
+
+using std::numbers::pi;
+
+export class Circle {
+public:
+    Circle() = default;
+    Circle(double rad, const Point& p);
+    Circle(const Circle& cir) = default;
+    Circle(Circle&& cir) = default;
+    Circle& operator=(const Circle& cir) = default;
+    Circle& operator=(Circle&& cir) = default;
+    std::string name() const { return "Circle"; }
+    void rotate(double phi);
+    void translate(Point p);
+    double area() const;
+    double perimeter() const;
+    inline double circumference() const { return perimeter(); }
+
+private:
+    double r{ 1.0 };
+    Point c{}; // Use default constructor of class Point to create c
+};
+
+
+Circle::Circle(double rad, const Point& p)
+    : r{ rad }
+    , c{ p }
+{
+}
+
+double Circle::area() const
+{
+    return pi * r * r;
+}
+
+double Circle::perimeter() const
+{
+    return 2 * pi * r;
+}
+
+void Circle::rotate(double phi) { phi = 0; }
+
+void Circle::translate(Point p)
+{
+    c += p;
+}
diff --git a/chapter_08/examples/2_any/with_modules/Point.ixx b/chapter_08/examples/2_any/with_modules/Point.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..436926852116750d9402f9e9fa808a121cdce786
--- /dev/null
+++ b/chapter_08/examples/2_any/with_modules/Point.ixx
@@ -0,0 +1,73 @@
+export module Point;
+
+export struct Point {
+    double X = 0, Y = 0;
+    Point() = default;
+    Point(const Point&) = default;
+    Point(Point&&) = default;
+    Point& operator=(const Point& p) = default;
+    Point& operator=(Point&& p) = default;
+    Point(double x, double y);
+    Point& operator+=(const Point& p);
+    Point& operator-=(const Point& p);
+    Point operator+(const Point& p) const;
+    Point operator-(const Point& p) const;
+    double operator*(const Point& p) const;
+    Point operator*(double f) const;
+};
+
+export auto operator*(double f, const Point& p) -> Point;
+// export auto operator<<(std::ostream& os, const Point& p) -> std::ostream&;
+
+Point::Point(double x, double y)
+    : X{ x }
+    , Y{ y }
+{
+}
+
+Point& Point::operator+=(const Point& p)
+{
+    X += p.X;
+    Y += p.Y;
+    return *this;
+}
+
+Point& Point::operator-=(const Point& p)
+{
+    X -= p.X;
+    Y -= p.Y;
+    return *this;
+}
+
+Point Point::operator+(const Point& p) const
+{
+    return { X + p.X, Y + p.Y };
+}
+
+Point Point::operator-(const Point& p) const
+{
+    return { X - p.X, Y - p.Y };
+}
+
+double Point::operator*(const Point& p) const
+{
+    return (X * p.X + Y * p.Y);
+}
+
+Point Point::operator*(double f) const
+{
+    return { f * X, f * Y };
+}
+
+Point operator*(double f, const Point& p)
+{
+    return { f * p.X, f * p.Y };
+}
+
+/*
+std::ostream& operator<<(std::ostream& os, const Point& p)
+{
+    os << "(" << p.X << ", " << p.Y << ")";
+    return os;
+}
+*/
diff --git a/chapter_08/examples/2_any/with_modules/Polygon.ixx b/chapter_08/examples/2_any/with_modules/Polygon.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..43ca1acb177bb4ac5ddbe3c5d3de20a21bb7ee6c
--- /dev/null
+++ b/chapter_08/examples/2_any/with_modules/Polygon.ixx
@@ -0,0 +1,52 @@
+module;
+#include <cmath>
+#include <array>
+#include <string>
+export module Polygon;
+import Point;
+
+export template <unsigned int NV>
+class Polygon {
+    static_assert(NV > 2, "Can't have polygon with less than 3 sides");
+
+public:
+    Polygon() = default;
+    Polygon(const Polygon&) = default;
+    Polygon(Polygon&&) = default;
+    Polygon& operator=(const Polygon& pg) = default;
+    Polygon& operator=(Polygon&&) = default;
+    constexpr auto n_vertexes() const { return NV; }
+    inline std::string name() const { return "Polygon<" + std::to_string(NV) + ">"; }
+
+    double perimeter() const
+    {
+        double ans = 0;
+        for (size_t i = 1; i < vertex.size(); ++i) {
+            ans += sqrt((vertex[i] - vertex[i - 1]) * (vertex[i] - vertex[i - 1]));
+        }
+        ans += sqrt((vertex.front() - vertex.back()) * (vertex.front() - vertex.back()));
+        return ans;
+    }
+    void translate(Point p)
+    {
+        for (auto& pt : vertex)
+            pt += p;
+    }
+
+    void rotate(double phi)
+    {
+        Point center;
+        for (auto pt : vertex)
+            center += pt;
+        center = (1.0 / NV) * center;
+        double ct = cos(phi), st = sin(phi);
+        for (auto& pt : vertex) {
+            auto rel = pt - center;
+            pt = center + Point(ct * rel.X + st * rel.Y, -st * rel.X + ct * rel.Y);
+        }
+    }
+
+protected:
+    std::array<Point, NV> vertex;
+};
+
diff --git a/chapter_08/examples/2_any/with_modules/Triangle.ixx b/chapter_08/examples/2_any/with_modules/Triangle.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..94a4b22783e70a43eea42577f21de8d4414b4df0
--- /dev/null
+++ b/chapter_08/examples/2_any/with_modules/Triangle.ixx
@@ -0,0 +1,33 @@
+module;
+#include <array>
+#include <cmath>
+export module Triangle;
+import Polygon;
+import Point;
+
+export class Triangle : public Polygon<3U> {
+public:
+    using Polygon<3U>::Polygon;
+    using Polygon<3U>::operator=;
+    using Polygon<3U>::name;
+    Triangle(Point p1, Point p2, Point p3);
+    double area() const;
+};
+// not exported
+inline double sqr(Point p) { return p * p; }
+
+Triangle::Triangle(Point p1, Point p2, Point p3)
+{
+    vertex[0] = p1;
+    vertex[1] = p2;
+    vertex[2] = p3;
+}
+
+double Triangle::area() const
+{
+    double s = 0.5 * perimeter();
+    double a = sqrt(sqr(vertex[0] - vertex[1]));
+    double b = sqrt(sqr(vertex[0] - vertex[2]));
+    double c = sqrt(sqr(vertex[1] - vertex[2]));
+    return sqrt(s * (s - a) * (s - b) * (s - c));
+}
diff --git a/chapter_08/examples/2_any/with_modules/clean.sh b/chapter_08/examples/2_any/with_modules/clean.sh
new file mode 100755
index 0000000000000000000000000000000000000000..aff1f9ecfd5fea4825d71d4e1af2f0c4ccfe57f6
--- /dev/null
+++ b/chapter_08/examples/2_any/with_modules/clean.sh
@@ -0,0 +1,4 @@
+rm -f *.o *.pcm *.gcm
+rm -rf gcm.cache
+rm -f a.clg a.gcc
+
diff --git a/chapter_08/examples/2_any/with_modules/main.cc b/chapter_08/examples/2_any/with_modules/main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c8860ee6e2fc807705193f05c8517e780ec51b99
--- /dev/null
+++ b/chapter_08/examples/2_any/with_modules/main.cc
@@ -0,0 +1,95 @@
+#include <chrono>
+#include <random>
+#include <iostream>
+#include <vector>
+#include <array>
+#include <any>
+import Point;
+import Polygon;
+import Circle;
+import Triangle;
+
+constexpr auto N = 100000UL;
+std::mt19937_64 engine;
+std::discrete_distribution sel{ 0.5, 0.5 };
+std::exponential_distribution length{ 1.0 };
+
+using element_type = std::any;
+
+auto name(const std::vector<element_type>& v, size_t i)
+{
+    if (v[i].type() == typeid(Triangle)) {
+        return std::any_cast<Triangle>(v[i]).name();
+    } else {
+        return std::any_cast<Circle>(v[i]).name();
+    }
+}
+
+auto area(const std::vector<element_type>& v, size_t i)
+{
+    if (v[i].type() == typeid(Triangle)) {
+        return std::any_cast<Triangle>(v[i]).area();
+    } else {
+        return std::any_cast<Circle>(v[i]).area();
+    }
+}
+
+void construct_objects(std::vector<element_type>& v)
+{
+    for (auto i = 0ul; i < N; ++i) {
+        auto isel = sel(engine);
+        switch (isel) {
+        case 0: {
+            auto radius = length(engine);
+            auto centrepos = Point(length(engine), length(engine));
+            v.emplace_back(std::in_place_type_t<Circle>{}, radius, centrepos);
+            break;
+        }
+        case 1: {
+            auto v1 = Point(length(engine), length(engine));
+            auto v2 = Point(length(engine), length(engine));
+            auto v3 = Point(length(engine), length(engine));
+            v.emplace_back(std::in_place_type_t<Triangle>{}, v1, v2, v3);
+            break;
+        }
+        };
+    }
+}
+
+void calc_area_all(const std::vector<element_type>& v)
+{
+    auto max_loc = 0ul;
+    auto max_area = 0.;
+    for (size_t i = 0; i < v.size(); ++i) {
+        auto ar = area(v, i);
+        if (i < 5) {
+            std::cout << i << ": " << name(v, i) << " with area "
+                      << ar << "\n";
+        }
+        if (ar > max_area) {
+            max_loc = i;
+        }
+    }
+
+    std::cout << "Largest object: \n";
+    auto nm = name(v, max_loc);
+    auto ar = area(v, max_loc);
+    std::cout << "Name : " << nm << ", area = " << ar << "\n";
+}
+
+auto main() -> int
+{
+    std::vector<element_type> shapes;
+    shapes.reserve(N);
+
+    auto t0 = std::chrono::steady_clock::now();
+    construct_objects(shapes);
+    auto t1 = std::chrono::steady_clock::now();
+    calc_area_all(shapes);
+    auto t2 = std::chrono::steady_clock::now();
+    std::cout << "Object creation time for " << N << " objects, "
+              << std::chrono::duration<double>(t1 - t0).count() << "\n"
+              << "Area evaluation time for " << N << " objects, "
+              << std::chrono::duration<double>(t2 - t1).count() << "\n";
+}
+
diff --git a/chapter_08/examples/advent.cc b/chapter_08/examples/advent.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f13cf01b80a5ff80f2dce05c9c756acb11790b0c
--- /dev/null
+++ b/chapter_08/examples/advent.cc
@@ -0,0 +1,34 @@
+/*
+Calculates the date of the last advent in a given
+year. Usage:
+
+(i) advent           # calculate for current year
+(ii) advent 2049     # for 2049
+*/
+
+import <chrono>;
+import <print>;
+auto current_year() -> std::chrono::year
+{
+    using namespace std::chrono;
+    year_month_day date { floor<days>(system_clock::now()) };
+    return date.year();
+}
+
+auto main(int argc, char* argv[]) -> int
+{
+    using namespace std::chrono;
+    using namespace std::chrono_literals;
+    using Date = year_month_day;
+
+    year Y { argc == 1 ? current_year() : year {std::stoi(argv[1]) }};
+
+    Date s4 { Y / December / Sunday[4] };
+    Date s3 { Y / December / Sunday[3] };
+    Date xmas { Y / December / 25d };
+    Date lastadv { s4 >= xmas ? s3 : s4 };
+
+    std::print("The last advent for the year {} falls on {}th of December.\n",
+              static_cast<int>(Y), static_cast<unsigned>(lastadv.day()));
+}
+
diff --git a/chapter_08/examples/darray_module/CMakeLists.txt b/chapter_08/examples/darray_module/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9272b8bcf43e6aa9904c7da892f2f472f3f7af66
--- /dev/null
+++ b/chapter_08/examples/darray_module/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.28)
+
+set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+project(darray_modules)
+
+add_executable(darray_w_modules)
+target_sources(darray_w_modules
+    PUBLIC
+    main.cc
+)
+target_sources(darray_w_modules
+  PUBLIC
+    FILE_SET own_modules TYPE CXX_MODULES FILES
+    mymodule.ixx
+)
+
diff --git a/chapter_08/examples/darray_module/README.md b/chapter_08/examples/darray_module/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8206692c98d06e63334ee0be1e2d0b650b221d1c
--- /dev/null
+++ b/chapter_08/examples/darray_module/README.md
@@ -0,0 +1,5 @@
+clang++ -std=c++23 -stdlib=libc++ -fmodules --precompile -xc++-module mymodule.ixx
+clang++ -std=c++23 -fmodules -c mymodule.pcm
+clang++ -std=c++23 -stdlib=libc++ -fmodules -fprebuilt-module-path=. mymodule.o main.cc
+
+
diff --git a/chapter_08/examples/darray_module/main.cc b/chapter_08/examples/darray_module/main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..29ffc819c827dcff1825e6d37d3445d3e8ddde6d
--- /dev/null
+++ b/chapter_08/examples/darray_module/main.cc
@@ -0,0 +1,21 @@
+#include <string>
+#include <iostream>
+import mymodule;
+
+auto main() -> int
+{
+    darray d1 { 1, 2, 3, 4, 5 }; // CTAD works!
+    //darray<int> d1{1, 2, 3, 4, 5};
+    darray<std::string> d2 { "a", "b", "c" }; 
+    // Explicit type required above, since "a", "b" etc are C-strings, and we want C++ strings
+    auto d3 = d1; //Copy
+    darray<int> d4 { 10 }; // This and the following line have a subtle difference
+    darray<int> d5(10); // This is the only situation where constructor calls with {} and () mean different things.
+    darray<std::string> d6 { std::move(d2) }; // d2 should be empty and d6 must have all data after this.
+    std::cout << "d1 = " << d1 << "\n";
+    std::cout << "d2 = " << d2 << "\n";
+    std::cout << "d3 = " << d3 << "\n";
+    std::cout << "d4 = " << d4 << "\n";
+    std::cout << "d5 = " << d5 << "\n";
+    std::cout << "d6 = " << d6 << "\n";
+}
diff --git a/chapter_08/examples/darray_module/mymodule.ixx b/chapter_08/examples/darray_module/mymodule.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..8c9f3bbab6290aadf88158fbb5395393c1c2c8a5
--- /dev/null
+++ b/chapter_08/examples/darray_module/mymodule.ixx
@@ -0,0 +1,103 @@
+module;
+#include <initializer_list>
+#include <iostream>
+#include <memory>
+export module mymodule;
+
+export template <class T>
+class darray {
+private:
+    // swap function
+    void swap(darray& oth)
+    {
+        std::swap(arr, oth.arr);
+        std::swap(sz, oth.sz);
+    }
+    std::unique_ptr<T[]> arr;
+    size_t sz = 0;
+
+public:
+    // read-only access for array elements
+    auto operator[](size_t i) const -> T { return arr[i]; }
+    // read-write access for array elements
+    auto operator[](size_t i) -> T& { return arr[i]; }
+
+    // This is needed if you want to use range based for loops on your class
+    auto begin() const -> T* { return arr; }
+    // This is needed if you want to use range based for loops on your class
+    auto end() const -> T* { return arr + size(); }
+
+    // returns the size
+    auto size() const -> decltype(sz) { return sz; }
+
+    // Sums up array and returns the result
+    auto sum() const -> T
+    {
+        T a {};
+        for (auto el : (*this)) {
+            a += el;
+        } // Use the range based for loop. //Well, why not!
+        return a;
+    }
+
+    // Default constructor, also defaulted.
+    darray() = default;
+    // Destructor. With storage managed by a unique_ptr, we don't need to delete it.
+    ~darray() = default;
+
+    // Constructor with a given size
+    darray(size_t N)
+    {
+        if (N != 0) {
+            arr = std::make_unique<T[]>(N);
+            sz = N;
+        }
+    }
+
+    // Copy constructor
+    darray(const darray<T>& oth)
+    {
+        if (oth.sz != 0) {
+            sz = oth.sz;
+            arr = std::make_unique<T[]>(sz);
+        }
+        for (size_t i = 0; i < sz; ++i)
+            arr[i] = oth.arr[i];
+    }
+    darray(darray<T>&& oth) noexcept 
+    {
+         swap(oth);
+    }
+    // Initialiser list constructor
+    darray(std::initializer_list<T> l)
+    {
+        arr = std::make_unique<T[]>(l.size());
+        sz = l.size();
+        size_t i = 0;
+        for (auto el : l)
+            arr[i++] = el;
+    }
+    // Assignment operator using the copy and swap idiom
+    auto operator=(darray d) -> darray&
+    {
+        swap(d);
+        return *this;
+    }
+};
+
+// Output operator. No need to make it a friend, since we can use only
+// public functions of the class to do all the work!
+export template <typename T>
+auto operator<<(std::ostream& os, const darray<T>& d) -> std::ostream&
+{
+    os << '[';
+    for (size_t i = 0; i < d.size(); ++i) {
+        os << d[i];
+        if (i != (d.size() - 1))
+            os << ',';
+    }
+    os << ']';
+    return os; // This function returns os so that you can write cout << d1 << " other things\n";
+    // That is interpreted as (cout << d1) << " other things\n";
+}
+
diff --git a/chapter_08/examples/feb.cc b/chapter_08/examples/feb.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1d7641b6df132948a1fea1f96e35f287a8a12457
--- /dev/null
+++ b/chapter_08/examples/feb.cc
@@ -0,0 +1,42 @@
+/*
+Calculates the years in a given interval, in which
+the month of February had 5 Sundays.
+
+Usage:
+(i)   feb      # Start: current year, End: 100 years from now
+(ii)  feb 1975 # Start: 1975, End: current year
+(iii) feb 2075 # Start: current year, End: 2075
+(iv)  feb 1800 2000 # Start 1800, End 2000
+
+Build:
+clang++ -std=c++20 -stdlib=libc++ feb.cc -o feb
+
+*/
+
+import <chrono>;
+import <iostream>;
+
+auto current_year() -> std::chrono::year
+{
+    using namespace std::chrono;
+    year_month_day date { floor<days>(system_clock::now()) };
+    return date.year();
+}
+
+auto main(int argc, char* argv[]) -> int
+{
+    using namespace std::chrono;
+    using namespace std::chrono_literals;
+    auto Y0 { current_year() };
+    auto Y1 = Y0 + years{100};
+    if (argc > 1) Y1 = year{std::stoi(argv[1])};
+    if (argc > 2) Y0 = year{std::stoi(argv[2])};
+    if (Y1 < Y0) std::swap(Y1, Y0);
+
+    for (auto y = Y0; y < Y1; ++y) {
+        auto d = y / February / Sunday[5];
+        if (d.ok())
+            std::cout << static_cast<int>(y) << "\n";
+    }
+}
+
diff --git a/chapter_08/examples/hello_m.cc b/chapter_08/examples/hello_m.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f743015337ce7b049038e5ba97b0fca1e08ae90d
--- /dev/null
+++ b/chapter_08/examples/hello_m.cc
@@ -0,0 +1,7 @@
+import <iostream>;
+
+auto main() -> int
+{
+    std::cout << "Hello, world!\n";
+}
+
diff --git a/chapter_08/examples/saxpy/with_header_files/README.md b/chapter_08/examples/saxpy/with_header_files/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..0160e21ce20f5af2b2cea1bec9871d436d33623f
--- /dev/null
+++ b/chapter_08/examples/saxpy/with_header_files/README.md
@@ -0,0 +1,9 @@
+To compile with clang:
+
+clang++ -std=c++23 -stdlib=libc++ usesaxpy.cc
+
+With gcc:
+
+g++ -std=c++23 usesaxpy.cc
+
+
diff --git a/chapter_08/examples/saxpy/with_header_files/saxpy.hh b/chapter_08/examples/saxpy/with_header_files/saxpy.hh
new file mode 100644
index 0000000000000000000000000000000000000000..b52279919867975fe7df82da673a55b6e071eae5
--- /dev/null
+++ b/chapter_08/examples/saxpy/with_header_files/saxpy.hh
@@ -0,0 +1,21 @@
+#ifndef SAXPY_HH
+#define SAXPY_HH
+#include <algorithm>
+#include <span>
+
+template <class T>
+concept Number = std::floating_point<T>
+              or std::integral<T>;
+template <Number T>
+auto saxpy(T a, std::span<const T> x,
+           std::span<const T> y,
+           std::span<T> z)
+{
+    std::transform(x.begin(), x.end(),
+                   y.begin(), z.begin(),
+        [a](T X, T Y) {
+            return a * X + Y;
+        });
+}
+#endif
+
diff --git a/chapter_08/examples/saxpy/with_header_files/usesaxpy.cc b/chapter_08/examples/saxpy/with_header_files/usesaxpy.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2a5386031e9b5790e757398d286489e9282fb5ed
--- /dev/null
+++ b/chapter_08/examples/saxpy/with_header_files/usesaxpy.cc
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <array>
+#include <vector>
+#include <span>
+#include "saxpy.hh"
+
+auto main() -> int
+{
+    using namespace std;
+    const array inp1 { 1., 2., 3., 4., 5. };
+    const array inp2 { 9., 8., 7., 6., 5. };
+    vector outp(inp1.size(), 0.);
+
+    saxpy(10., {inp1}, {inp2}, {outp});
+    for (auto x : outp) cout << x << "\n";
+    cout << ":::::::::::::::::::::\n";
+}
+
diff --git a/chapter_08/examples/saxpy/with_modules/CMakeLists.txt b/chapter_08/examples/saxpy/with_modules/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d480a51ccd817cf0e1cc8b6494b4dc3aec31080f
--- /dev/null
+++ b/chapter_08/examples/saxpy/with_modules/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.28)
+
+set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+project(use_saxpy-example)
+
+add_executable(use_saxpy)
+target_sources(use_saxpy
+    PUBLIC
+    usesaxpy.cc
+)
+target_sources(use_saxpy
+  PUBLIC
+    FILE_SET saxpy_module TYPE CXX_MODULES FILES
+    saxpy.ixx
+)
+
diff --git a/chapter_08/examples/saxpy/with_modules/README.md b/chapter_08/examples/saxpy/with_modules/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..9841fe5317e832131a2c507f8d31f6fccee81711
--- /dev/null
+++ b/chapter_08/examples/saxpy/with_modules/README.md
@@ -0,0 +1,7 @@
+Compile with clang:
+
+mkdir build
+cd build
+CC=clang CXX=clang++ cmake -DCMAKE_GENERATOR=Ninja ..
+ninja
+
diff --git a/chapter_08/examples/saxpy/with_modules/saxpy.ixx b/chapter_08/examples/saxpy/with_modules/saxpy.ixx
new file mode 100644
index 0000000000000000000000000000000000000000..47a8a348ed4b296b74159d5b4474d57467e32bc3
--- /dev/null
+++ b/chapter_08/examples/saxpy/with_modules/saxpy.ixx
@@ -0,0 +1,29 @@
+/* We are using #includes rather than imports
+to be able to compile with gcc. Clang works
+fine with the imports of STL headers. GCC,
+even after generating header units with
+-xc++-system-header crashes with an internal
+compiler error.
+*/
+
+module;
+#include <algorithm>
+#include <span>
+export module saxpy;
+
+template <class T>
+concept Number = std::floating_point<T>
+              or std::integral<T>;
+
+export template <Number T>
+auto saxpy(T a, std::span<const T> x,
+           std::span<const T> y,
+           std::span<T> z)
+{
+    std::transform(x.begin(), x.end(),
+                   y.begin(), z.begin(),
+        [a](T X, T Y) {
+            return a * X + Y;
+        });
+}
+
diff --git a/chapter_08/examples/saxpy/with_modules/usesaxpy.cc b/chapter_08/examples/saxpy/with_modules/usesaxpy.cc
new file mode 100644
index 0000000000000000000000000000000000000000..54fd6eb5420189b492dac7b557d7441d14455073
--- /dev/null
+++ b/chapter_08/examples/saxpy/with_modules/usesaxpy.cc
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <array>
+#include <vector>
+#include <span>
+import saxpy;
+
+auto main() -> int
+{
+    using namespace std;
+    const array inp1 { 1., 2., 3., 4., 5. };
+    const array inp2 { 9., 8., 7., 6., 5. };
+    vector outp(inp1.size(), 0.);
+
+    saxpy(10., {inp1}, {inp2}, {outp});
+    for (auto x : outp) cout << x << "\n";
+    cout << ":::::::::::::::::::::\n";
+}
+