diff --git a/notebooks/08_Functors+Lambdas.ipynb b/notebooks/08_Functors+Lambdas.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..2f4d489cc2c5c952c9e980dfee54ad31574efa5b
--- /dev/null
+++ b/notebooks/08_Functors+Lambdas.ipynb
@@ -0,0 +1,338 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "789d7a72",
+   "metadata": {},
+   "source": [
+    "# Functors, Lambdas and std::function"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "43efc656",
+   "metadata": {},
+   "source": [
+    "    \n",
+    "   "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "008aa425",
+   "metadata": {},
+   "source": [
+    "#### Function Pointers\n",
+    "In a previous example we had implemented a function to compare to objects of type ```myPair```."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "96f5ab84",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class myPair;\n",
+    "bool cmp( const myPair& left, const myPair& right );"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ea6fcef6",
+   "metadata": {},
+   "source": [
+    "We needed that function to be able to create a set of ```myPair```'s.\n",
+    "\n",
+    "        std::set< myPair, decltype( cmp )* > pairs ( cmp );\n",
+    "        \n",
+    "What we pass to std::set's constructor is a **function pointer** of type\n",
+    "\n",
+    "        bool (*) ( const myPair&, const myPair& )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "dc79e822",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "- This way to work with functions is something that C++ inherited from C.\n",
+    "- Not only in the STL, but also in scientific programming we often have the case that we implement something, but want to leave some details to the user:  \n",
+    "  - Consider e.g. implementing an algorithm to approximate the integral\n",
+    "$$I = \\int_a^b f(x)\\, dx$$\n",
+    "  - When we code that we would like to leave the details of the integrand to be specified flexibly by the user.  \n",
+    "  - As with std::set we can let the user provide a function that we then call inside our code.\n",
+    "  - This is known as a **callback**.\n",
+    "- The main downside to using function (pointers) in this approach is that a free function is **stateless**. In order to influence its behaviour we have to pass arguments through its interface. That does not work nicely with the callback idea.\n",
+    "  - Note: We can add *state* to a function by making some of its local variables ```static```. See the ```accumulate``` examples.\n",
+    "  - However, a function is a global entity. Thus, there can always only be one state for it."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9ce08962",
+   "metadata": {},
+   "source": [
+    "#### Functors\n",
+    "In C++ we can as one alternative use a **function object**, a.k.a. **functor**. This is an object of a class that overloads the function call operator ```operator()```."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "id": "9bf146ec",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "class greeter{\n",
+    "public:\n",
+    "  void operator() ( const std::string& str ) {\n",
+    "    std::cout << \"Greetings \" << str << std::endl;\n",
+    "  }\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "b13aa200",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int main() {\n",
+    "  greeter hello;\n",
+    "  hello( \"Class\" );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "id": "f7a3701a",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Greetings Class\n"
+     ]
+    }
+   ],
+   "source": [
+    "main();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "58a187c4",
+   "metadata": {},
+   "source": [
+    "***\n",
+    "Now that was a simple functor and did only demonstrate **how** it works and not **why** that approach can be advantageous.\n",
+    "\n",
+    "**Example 2:**  \n",
+    "In our second example we will use a stateful functor that allows to perform different binary operations. The type of operation will be passed via its constructor."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "id": "8c0f30c5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "class BinaryOperator {\n",
+    "\n",
+    "public:\n",
+    "\n",
+    "  typedef enum { ADD, MULT } type;\n",
+    "\n",
+    "  BinaryOperator() = delete;\n",
+    "  BinaryOperator( BinaryOperator::type op ) : whatToDo( op ) {};\n",
+    "\n",
+    "  int operator() ( int a, int b ) {\n",
+    "    switch( whatToDo ) {\n",
+    "    case ADD:\n",
+    "      return a+b;\n",
+    "    case MULT:\n",
+    "      return a*b;\n",
+    "    }\n",
+    "  }\n",
+    "\n",
+    "private:\n",
+    "  type whatToDo;\n",
+    "\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6adaab27",
+   "metadata": {},
+   "source": [
+    "**Example 3:**  \n",
+    "So how would our set example for myPair look like with a functor?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "856ee747",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Writing functor.cpp\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%file functor.cpp\n",
+    "\n",
+    "#include <iostream>\n",
+    "#include <set>\n",
+    "\n",
+    "struct myPair {\n",
+    "  myPair( int fir, int sec ) : fir_( fir ), sec_( sec ) {\n",
+    "    std::cout << \"(\" << fir_ << \",\" << sec_ << \") constructed\" << std::endl;\n",
+    "  };\n",
+    "  int fir_;\n",
+    "  int sec_;\n",
+    "};\n",
+    "\n",
+    "struct myCompare {\n",
+    "  bool operator() ( const myPair& left, const myPair& right ) const {\n",
+    "    int val1 = left.fir_ * left.fir_ + left.sec_ * left.sec_;\n",
+    "    int val2 = right.fir_ * right.fir_ + right.sec_ * right.sec_;\n",
+    "    return val1 < val2;\n",
+    "  }\n",
+    "};\n",
+    "\n",
+    "int main() {\n",
+    "\n",
+    "  myCompare cmp;\n",
+    "  std::set< myPair, myCompare > pairs( cmp );\n",
+    "\n",
+    "  myPair p1( 1, 2 );\n",
+    "  myPair p2( 3, 4 );\n",
+    "\n",
+    "  std::cout << \"p1 < p2 is \" << cmp( p1, p2 ) << std::endl;\n",
+    "  std::cout << \"p2 < p1 is \" << cmp( p2, p1 ) << std::endl;\n",
+    "\n",
+    "  pairs.insert( p1 );\n",
+    "  pairs.insert( p2 );\n",
+    "\n",
+    "  pairs.emplace( 3, 4 );\n",
+    "  pairs.emplace( 5, 6 );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "4adb7f0b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!g++ -Wall -Wextra functor.cpp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "f9bfde7f",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(1,2) constructed\n",
+      "(3,4) constructed\n",
+      "p1 < p2 is 1\n",
+      "p2 < p1 is 0\n",
+      "(3,4) constructed\n",
+      "(5,6) constructed\n"
+     ]
+    }
+   ],
+   "source": [
+    "!./a.out"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "id": "fe907464",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "5\n",
+      "6\n"
+     ]
+    }
+   ],
+   "source": [
+    "int main() {\n",
+    "\n",
+    "  int a = 2;\n",
+    "  int b = 3;\n",
+    "\n",
+    "  BinaryOperator adder( BinaryOperator::ADD );\n",
+    "  BinaryOperator multiplier( BinaryOperator::MULT );\n",
+    "\n",
+    "  std::cout << adder( a, b ) << std::endl;\n",
+    "  std::cout << multiplier( a, b ) << std::endl;\n",
+    "}\n",
+    "\n",
+    "main();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9d2c9715",
+   "metadata": {},
+   "source": [
+    "#### Lambdas\n",
+    "Using *function pointers* or *functors* implies some significant coding overhead.\n",
+    "\n",
+    "C++11 introduced **lambda (functions)**, also known as **closures** as a leight-weight alternative, that can be written inline in the source code."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8729d298",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xcpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}