diff --git a/1-ProceduralProgramming/7-StaticAndConstexpr.ipynb b/1-ProceduralProgramming/7-StaticAndConstexpr.ipynb
index 24bd3c71df17ec4c47ca52b3f272e1f6bf8d7428..a38706a92f64bb0e8ef1aef6ab6f58d3efac11b1 100644
--- a/1-ProceduralProgramming/7-StaticAndConstexpr.ipynb
+++ b/1-ProceduralProgramming/7-StaticAndConstexpr.ipynb
@@ -108,7 +108,7 @@
    "source": [
     "## Constexpr\n",
     "\n",
-    "Let's consider the STL container `std::array`, which is the container of choice to store an array which size is known *at compile time* (containers will be seen more in depth in a [future notebook](./notebooks/5-UsefulConceptsAndSTL/3-Containers.ipynb))."
+    "We've seen the allocation of an array on the stack follows this syntax:"
    ]
   },
   {
@@ -117,15 +117,15 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "#include <array>\n",
-    "\n",
-    "std::array<double, 3ul> my_array;"
+    "int array[5ul];"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
+    "where the size of the array is available at compile time (if not you have to use an array allocated on the heap at runtime).\n",
+    "\n",
     "Now imagine we want to init such an array with a size that results from a computation; let's say a Fibonacci series:"
    ]
   },
@@ -165,8 +165,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "#include <array>\n",
-    "std::array<double, fibonacci(4)> my_fibonacci_4_array; // COMPILATION ERROR!"
+    "double array[fibonacci(5)]; // COMPILATION ERROR!"
    ]
   },
   {
@@ -178,7 +177,7 @@
     "In C++ 03, you had two choices to resolve this\n",
     "\n",
     "- Using a macro...\n",
-    "- Or using [metaprogramming](./4-Templates/4-Metaprogramming.ipynb) which is a tad overkill... (and involves boilerplate code).\n",
+    "- Or using [metaprogramming](../4-Templates/4-Metaprogramming.ipynb) which is a tad overkill... (and involves boilerplate code).\n",
     "\n",
     "C++ introduced the keyword `constexpr`, which indicates something happens at compile time. It might be used for just a variable, or for more complicated construct such as functions or classes. The only requirement is that all the subparts used are themselves `constexpr`."
    ]
@@ -206,9 +205,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "#include <array>\n",
-    "constexpr auto  fibonacci_index = 4ul;\n",
-    "std::array<double, fibonacci_const(fibonacci_index)> my_fibonacci_4_array; "
+    "double array[fibonacci_const(5)]; // Ok!"
    ]
   },
   {
@@ -228,8 +225,7 @@
     "\n",
     "int i = 7;\n",
     "++i; // i is by no stretch a compile time variable!\n",
-    "\n",
-    "std::cout << fibonacci_const(7) << std::endl; // ok!"
+    "std::cout << fibonacci_const(7) << std::endl;"
    ]
   },
   {
@@ -239,7 +235,9 @@
     "`constexpr` becomes increasingly powerful over time:\n",
     "\n",
     "- The function `fibonacci_const` above does not in fact work before C++ 14: this version of the standard introduced the possibility to provide several `return` in a `constexpr` function.\n",
-    "- `constexpr` is added wherever possible in the STL. This is still a work in progress: if you look for instance the [CppReference page](https://en.cppreference.com/w/cpp/algorithm/count) for `std::count` algorithm, you will see this algorithm becomes `constexpr` in C++ 20."
+    "- `constexpr` is added wherever possible in the STL. This is still a work in progress: if you look for instance the [CppReference page](https://en.cppreference.com/w/cpp/algorithm/count) for `std::count` algorithm, you will see this algorithm becomes `constexpr` in C++ 20.\n",
+    "\n",
+    "We will see another use of `constexpr` in a [later notebook](../4-Templates/2-Specialization.ipynb#If-constexpr)."
    ]
   },
   {
diff --git a/4-Templates/4-Metaprogramming.ipynb b/4-Templates/4-Metaprogramming.ipynb
index 5c426acc4df70ea05958e12cd5eceef914f3f01a..6add317dcb177fa222413f775059c3ceaff28793 100644
--- a/4-Templates/4-Metaprogramming.ipynb
+++ b/4-Templates/4-Metaprogramming.ipynb
@@ -209,6 +209,142 @@
     "}"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Bonus: metaprogramming Fibonacci\n",
+    "\n",
+    "In [notebook about constexpr](../1-ProceduralProgramming/7-StaticAndConstexpr.ipynb), I said implementing Fibonacci series before C++ 11 involved metaprogramming; here is an implementation (much more wordy than the `constexpr` one):\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template<std::size_t N>\n",
+    "struct Fibonacci\n",
+    "{\n",
+    " \n",
+    "    static std::size_t Do()\n",
+    "    {\n",
+    "        return Fibonacci<N-1>::Do() + Fibonacci<N-2>::Do();\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Don't forget the specialization for 0 and 1!\n",
+    "\n",
+    "template<>\n",
+    "struct Fibonacci<0ul>\n",
+    "{\n",
+    " \n",
+    "    static std::size_t Do()\n",
+    "    {\n",
+    "        return 0ul;\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "};\n",
+    "\n",
+    "\n",
+    "template<>\n",
+    "struct Fibonacci<1ul>\n",
+    "{\n",
+    " \n",
+    "    static std::size_t Do()\n",
+    "    {\n",
+    "        return 1ul;\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "std::cout << Fibonacci<5ul>::Do() << std::endl;\n",
+    "std::cout << Fibonacci<10ul>::Do() << std::endl;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "And if the syntax doesn't suit you... you could always add an extra level of indirection to remove the `::Do()` part:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template<std::size_t N>\n",
+    "std::size_t FibonacciWrapper()\n",
+    "{\n",
+    "    return Fibonacci<N>::Do();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "std::cout << FibonacciWrapper<5ul>() << std::endl;\n",
+    "std::cout << FibonacciWrapper<10ul>() << std::endl;\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As you can see, in some cases `constexpr` really alleviates some tedious boilerplate... \n",
+    "\n",
+    "It should be noticed that although these computations really occur at compile time, they aren't nonetheless recognized automatically as `constexpr`: "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "constexpr auto fibo_5 = FibonacciWrapper<5ul>(); // COMPILATION ERROR!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To fix that, you need to declare `constexpr`:\n",
+    "- Each of the `Do` static method (`static constexpr std::size_t Do()`)\n",
+    "- The `FibonacciWrapper` function (`template<std::size_t N> constexpr std::size_t FibonacciWrapper()`)\n",
+    "\n",
+    "So in this specific case you should really go with the much less wordy and more expressive expression with `constexpr` given in [aforementioned notebook](../1-ProceduralProgramming/7-StaticAndConstexpr.ipynb)"
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {},