diff --git a/3_Advanced_Data_Types.ipynb b/3_Advanced_Data_Types.ipynb
index bb61f351c2d59a9bcc28a3dfd14bedccae1efebd..8ce0a004709e0bf6864d8b3338e68b70098dbe48 100644
--- a/3_Advanced_Data_Types.ipynb
+++ b/3_Advanced_Data_Types.ipynb
@@ -631,7 +631,7 @@
    "id": "647530cd-480a-414f-a8ec-1375e05a9e1b",
    "metadata": {},
    "source": [
-    "## Structs"
+    "## Objects and structs"
    ]
   },
   {
@@ -814,10 +814,10 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "function printpoint(p)\n",
+    "function print_point(p)\n",
     "    println(\"($(p.x), $(p.y))\")\n",
     "end\n",
-    "printpoint(p)"
+    "print_point(p)"
    ]
   },
   {
@@ -827,13 +827,13 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "function printbook(book)\n",
+    "function print_book(book)\n",
     "    println(\"Title: $(book.title)\")\n",
     "    println(\"Author: $(book.author)\")\n",
     "    available = book.properties[\"available\"]\n",
     "    println(\"Available: $(available)\")\n",
     "end\n",
-    "printbook(book)"
+    "print_book(book)"
    ]
   },
   {
@@ -889,8 +889,16 @@
    "source": [
     "### References and values\n",
     "\n",
-    "Each object (instance of a struct) is stored at some memory address. The operator `===` checks if two variables point to the same memory address of the object. For example\n",
-    "\n",
+    "Each object (instance of a struct) is stored at some memory address. The operator `===` checks if two variables point to the same memory address of the object. For example"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ed713d91-17f4-4010-a7d3-d39826cffc97",
+   "metadata": {},
+   "outputs": [],
+   "source": [
     "book_copy = book\n",
     "@show book_copy === book;"
    ]
@@ -950,17 +958,174 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "import Core\n",
+    "import Base: ==\n",
     "\n",
     "function ==(book1::Book, book2::Book)\n",
     "    return book1.title == book2.title && book1.author == book2.author\n",
-    "end"
+    "end\n",
+    "\n",
+    "@show book_copy == book;\n",
+    "@show book_copy === book;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "87c1e4fb-d4e2-4ada-a97f-61273012146c",
+   "metadata": {},
+   "source": [
+    "With this we can compare if two books are the same, even if they are two distinct instances of the same struct."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9263a1ae-52ee-4afc-9d9f-0f1341b64bc0",
+   "metadata": {},
+   "source": [
+    "## Pure and impure functions"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f638e9b3-9926-46fc-81e0-d49c877a3bbb",
+   "metadata": {},
+   "source": [
+    "We have seen that it is quite convenient to pass objects to functions. So far we have seen functions that print the content or that create a new object. None of these functions are modifying the content of the input objects.\n",
+    "  - A function that does not modify the input it is also said **pure**.\n",
+    "  - A function which modifies the input it is said **impure**. In Julia impure functions are highlighted by adding a `!` as the last character of the name.\n",
+    "\n",
+    "Let's consider a modified version of the book for an example."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7f892e07-a601-4cba-b58d-40be9c8e93ab",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "book = Book(\"Der Hobbit\", \"J.R.R. Tolkien\", Dict(\"available\" => true, \"copies_in_stock\" => 10))\n",
+    "@show book;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "99f4d6c9-2633-4394-b6a0-e0ce0c05e0db",
+   "metadata": {},
+   "source": [
+    "Then we could think of a function which updates the database whenever we order new copies."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "04937488-a556-44ad-97be-98b017f293fd",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function order_book!(book, number_of_copies)\n",
+    "    if number_of_copies <= 0\n",
+    "        return\n",
+    "    end\n",
+    "    book.properties[\"copies_in_stock\"] += number_of_copies\n",
+    "    book.properties[\"available\"] = true\n",
+    "end\n",
+    "\n",
+    "order_book!(book, 5)\n",
+    "@show book;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "93bc2e46-8530-4d1e-b7fa-55a74d1831c8",
+   "metadata": {},
+   "source": [
+    "## Exercise"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b30bd560-5ff3-4706-9f53-e6a5158651e9",
+   "metadata": {},
+   "source": [
+    "Write an inpure function `sell_book!` for updating the book object whenever we sell a single copy. The function should complain if there are no copies available."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6e79fe95-767d-4b3e-af58-623db6dc0712",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5ed4d4e0-0454-4298-9a56-8fb32634aa24",
+   "metadata": {},
+   "source": [
+    "## Further exercises"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8446f1db-d40f-4311-9597-3b3b4d913151",
+   "metadata": {},
+   "source": [
+    "- Create a time struct which stores the time of the day (hour, minute and second). Write a function which takes as input the time object and prints it. Then write a function which sums together two time objects and returns a new time object. If the total is more than 24 hours, it should reset as if it was the next day."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5335e035-62ee-4d0f-acfc-a9e24ac26d99",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "32844b6f-518a-4174-83c6-0d7ebeabe4e4",
+   "metadata": {},
+   "source": [
+    "  - Create a custom version of the `==` function which checks if two time objects are the same."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "966d4db1-c95a-4531-8209-a869519599ea",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "baa7e06f-e183-4ee7-912a-e22255e18e21",
+   "metadata": {},
+   "source": [
+    "  - Create a custom version of the `<` and `<=` functions for time objects."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c9b76667-731b-4ec2-aaf4-e94496f65b1a",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1bdbd748-7482-4f54-99a7-3d6e74b65575",
+   "metadata": {},
+   "source": [
+    "  - Create a custom version of the `<` and `<=` functions for time objects."
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "03594f56-48ee-4152-a42f-8e3588c3ab2e",
+   "id": "7df56050-686e-4a87-aa86-9b7f61315aa2",
    "metadata": {},
    "outputs": [],
    "source": []