{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "12e2ce5e-575b-43a8-8215-78db6fa4e7e8",
   "metadata": {},
   "source": [
    "# PLC 2026, Lecture 14, 3 March 2026"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33a508ef-44f1-485c-9725-cfcb2a5b7d43",
   "metadata": {},
   "source": [
    "## Concurrent programming in Rust"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f25693f6-2edb-4523-8471-e9d891689051",
   "metadata": {},
   "source": [
    "### Passing functions\n",
    "- In Haskell, we can pass functions --- e.g. `twice f x = f (f x)`\n",
    "- In Java, we typically pass functions indirectly via an interface --- e.g. an object that implements `Comparable` will support a (customized) comparison function `cmp`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b337199-fc80-4f22-8256-9c56291aba9d",
   "metadata": {},
   "source": [
    "### Closures\n",
    "- Unlike Haskell, functions in Rust have internal variables that could capture the state of the context where they are defined\n",
    "- A **closure** is a function definition with a context"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75507612-5fa3-48b7-b117-5c052997fa8d",
   "metadata": {},
   "source": [
    "### Closures vs functions\n",
    "- The examples below illustrate the syntacit difference between a function definition and a closure\n",
    "- A closure is an anonymous function that can be assigned to a variable (last 3 examples below)\n",
    "- Explicit type declarations are not required if the type can be inferred from context"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b71c8699-fb72-4033-8183-fa2d8f4e2802",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "add_one_v2(7) is 8\n",
      "add_one_v3(17) is 18\n",
      "add_one_v4(27) is 28\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{\n",
    "    fn  add_one_v1   (x: u32) -> u32 { x + 1 }\n",
    "\n",
    "    let add_one_v2 = |x: u32| -> u32 { x + 1 };\n",
    "    println!(\"add_one_v2(7) is {}\",add_one_v2(7));\n",
    "\n",
    "    let add_one_v3 = |x| { x + 1 };\n",
    "    println!(\"add_one_v3(17) is {}\",add_one_v3(17));\n",
    "\n",
    "    let add_one_v4 = |x| x + 1;\n",
    "    println!(\"add_one_v4(27) is {}\",add_one_v4(27));\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49b21dd0-9449-4d1e-a42d-073f1760e096",
   "metadata": {},
   "source": [
    "- The inferred type should be consistent\n",
    "- In the code below, the invocation of `example_closure` fixes the type of `x` as `String`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "164163fc-743e-4d22-9b07-b895f26ca94c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{ \n",
    "    let example_closure = |x| x;\n",
    "    let s = example_closure(String::from(\"hello\"));\n",
    "    println!(\"{}\",s);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "585d864f-d715-46ea-8eb3-8901fc2d10ad",
   "metadata": {},
   "source": [
    "- Here the type of `x` is (some variety) of integer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "23cf2dec-6eb9-4cda-899e-96811ab8299e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{ \n",
    "    let example_closure = |x| x;\n",
    "    let n = example_closure(5);\n",
    "    println!(\"{}\",n);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0af07588-0021-4fe0-b4c4-aed995561b2f",
   "metadata": {},
   "source": [
    "- If we invoke the same closure with two different types, we get an error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9893ab29-2045-4183-807e-7626588ab0f4",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "mismatched types",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0308] Error:\u001b[0m mismatched types",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_5:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m2 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m|\u001b[0m\u001b[38;5;68mx\u001b[0m\u001b[38;5;249m|\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m                            \u001b[38;5;68m┬\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m                            \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m note: closure parameter defined here",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;246m7 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100mx\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;100mm\u001b[0m\u001b[38;5;100mp\u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100m_\u001b[0m\u001b[38;5;100mc\u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100mo\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100mu\u001b[0m\u001b[38;5;100mr\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;54m5\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m             \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m \u001b[38;5;54m┬\u001b[0m\u001b[38;5;37m│\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m                    \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m arguments to this function are incorrect",
      " \u001b[38;5;240m  │\u001b[0m                             \u001b[38;5;54m│\u001b[0m\u001b[38;5;37m│\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m                             \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m expected `String`, found integer",
      " \u001b[38;5;240m  │\u001b[0m                              \u001b[38;5;37m│\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m                              \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m help: try using a conversion method: `.to_string()`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "{ \n",
    "    let example_closure = |x| x;\n",
    "    \n",
    "    let s = example_closure(String::from(\"hello\"));\n",
    "    println!(\"{}\",s);\n",
    "\n",
    "    let n = example_closure(5);\n",
    "    println!(\"{}\",n);\n",
    "    \n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba1d67bd-1a66-4dfd-932b-c3fcb281243e",
   "metadata": {},
   "source": [
    "- This error persists even the contradictory inferences are localized inside blocks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c36c2309-8d24-450a-8f4f-77784b1e8d79",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "mismatched types",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0308] Error:\u001b[0m mismatched types",
      "    \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_6:1:1\u001b[38;5;246m]\u001b[0m",
      "    \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m 2 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m|\u001b[0m\u001b[38;5;68mx\u001b[0m\u001b[38;5;249m|\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                            \u001b[38;5;68m┬\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m                            \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m note: closure parameter defined here",
      " \u001b[38;5;240m   │\u001b[0m ",
      " \u001b[38;5;246m10 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100mx\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;100mm\u001b[0m\u001b[38;5;100mp\u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100m_\u001b[0m\u001b[38;5;100mc\u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100mo\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100mu\u001b[0m\u001b[38;5;100mr\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;54m5\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                 \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m \u001b[38;5;54m┬\u001b[0m\u001b[38;5;37m│\u001b[0m ",
      " \u001b[38;5;240m   │\u001b[0m                        \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m arguments to this function are incorrect",
      " \u001b[38;5;240m   │\u001b[0m                                 \u001b[38;5;54m│\u001b[0m\u001b[38;5;37m│\u001b[0m ",
      " \u001b[38;5;240m   │\u001b[0m                                 \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m expected `String`, found integer",
      " \u001b[38;5;240m   │\u001b[0m                                  \u001b[38;5;37m│\u001b[0m ",
      " \u001b[38;5;240m   │\u001b[0m                                  \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m help: try using a conversion method: `.to_string()`",
      "\u001b[38;5;246m────╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "{ \n",
    "    let example_closure = |x| x;\n",
    "    \n",
    "    {\n",
    "        let s = example_closure(String::from(\"hello\"));\n",
    "        println!(\"{}\",s);\n",
    "    }\n",
    "\n",
    "    {\n",
    "        let n = example_closure(5);\n",
    "        println!(\"{}\",n);\n",
    "    }\n",
    "    \n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcbbb5c0-f465-413f-8db5-ae80a433c568",
   "metadata": {},
   "source": [
    "- In this version, the closure is redefined after the first type inference, so it works"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b5a1b833-e8ef-4b82-8b1b-f65345400a11",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{ \n",
    "    let example_closure = |x| x;\n",
    "    \n",
    "    let s = example_closure(String::from(\"hello\"));\n",
    "    println!(\"{}\",s);\n",
    "\n",
    "    let example_closure = |x| x;\n",
    "\n",
    "    let n = example_closure(5);\n",
    "    println!(\"{}\",n);\n",
    "    \n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c59b325-c089-4a98-9917-cf16dd9dbc93",
   "metadata": {},
   "source": [
    "#### Closures and context\n",
    "- When `cl` is defined, `x` is `8`\n",
    "- Before `cl` is invoked, `x` is redefined s `88`\n",
    "- The closure uses the old value that was in its scope when it was defined"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "be34b01d-01ce-46b3-b93d-e729ba7f7f5e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{\n",
    "    let x = 8;\n",
    "    let cl = |y| {x+y};\n",
    "    let x = 88;\n",
    "    let s = cl(7);\n",
    "    println!(\"{}\",s);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4cee1a9-204b-4513-aa30-ba0611d87750",
   "metadata": {},
   "source": [
    "- Another example\n",
    "- The function `createclosure` returns a closure. We have to specify the return type. The return type is `FnMut()` which we have not seen --- look up the Rust documentation, this is not the main point of this example!\n",
    "- Inside the function, we have a local mutable `counter` which is incremented by each call to the closure\n",
    "- Note that we have to `move` the counter to the closure explicitly, just as we would in a function, for ownership to work correctly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c82f70d2-50e3-44c1-805e-be424955596d",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "`counter` does not live long enough",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0597] Error:\u001b[0m `counter` does not live long enough",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_9:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m2 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;37mm\u001b[0m\u001b[38;5;37mu\u001b[0m\u001b[38;5;37mt\u001b[0m\u001b[38;5;37m \u001b[0m\u001b[38;5;37mc\u001b[0m\u001b[38;5;37mo\u001b[0m\u001b[38;5;37mu\u001b[0m\u001b[38;5;37mn\u001b[0m\u001b[38;5;37mt\u001b[0m\u001b[38;5;37me\u001b[0m\u001b[38;5;37mr\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m0\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m         \u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m┬\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m              \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m binding `counter` declared here",
      " \u001b[38;5;246m3 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;68m|\u001b[0m\u001b[38;5;68m|\u001b[0m\u001b[38;5;97m \u001b[0m\u001b[38;5;97m{\u001b[0m\u001b[38;5;54mc\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mu\u001b[0m\u001b[38;5;54mn\u001b[0m\u001b[38;5;54mt\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;97m \u001b[0m\u001b[38;5;97m=\u001b[0m\u001b[38;5;97m \u001b[0m\u001b[38;5;97mc\u001b[0m\u001b[38;5;97mo\u001b[0m\u001b[38;5;97mu\u001b[0m\u001b[38;5;97mn\u001b[0m\u001b[38;5;97mt\u001b[0m\u001b[38;5;97me\u001b[0m\u001b[38;5;97mr\u001b[0m\u001b[38;5;97m+\u001b[0m\u001b[38;5;97m1\u001b[0m\u001b[38;5;97m;\u001b[0m\u001b[38;5;97m \u001b[0m\u001b[38;5;97mp\u001b[0m\u001b[38;5;97mr\u001b[0m\u001b[38;5;97mi\u001b[0m\u001b[38;5;97mn\u001b[0m\u001b[38;5;97mt\u001b[0m\u001b[38;5;97ml\u001b[0m\u001b[38;5;97mn\u001b[0m\u001b[38;5;97m!\u001b[0m\u001b[38;5;97m(\u001b[0m\u001b[38;5;97m\"\u001b[0m\u001b[38;5;97mc\u001b[0m\u001b[38;5;97mo\u001b[0m\u001b[38;5;97mu\u001b[0m\u001b[38;5;97mn\u001b[0m\u001b[38;5;97mt\u001b[0m\u001b[38;5;97me\u001b[0m\u001b[38;5;97mr\u001b[0m\u001b[38;5;97m \u001b[0m\u001b[38;5;97mi\u001b[0m\u001b[38;5;97ms\u001b[0m\u001b[38;5;97m \u001b[0m\u001b[38;5;97m{\u001b[0m\u001b[38;5;97m}\u001b[0m\u001b[38;5;97m\"\u001b[0m\u001b[38;5;97m,\u001b[0m\u001b[38;5;97mc\u001b[0m\u001b[38;5;97mo\u001b[0m\u001b[38;5;97mu\u001b[0m\u001b[38;5;97mn\u001b[0m\u001b[38;5;97mt\u001b[0m\u001b[38;5;97me\u001b[0m\u001b[38;5;97mr\u001b[0m\u001b[38;5;97m)\u001b[0m\u001b[38;5;97m;\u001b[0m\u001b[38;5;97m}\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m             \u001b[38;5;68m─\u001b[0m\u001b[38;5;68m┬\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m┬\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m              \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m value captured here",
      " \u001b[38;5;240m  │\u001b[0m                    \u001b[38;5;54m│\u001b[0m                      \u001b[38;5;97m│\u001b[0m                               ",
      " \u001b[38;5;240m  │\u001b[0m                    \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m borrowed value does not live long enough",
      " \u001b[38;5;240m  │\u001b[0m                                           \u001b[38;5;97m│\u001b[0m                               ",
      " \u001b[38;5;240m  │\u001b[0m                                           \u001b[38;5;97m╰\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m\u001b[38;5;97m─\u001b[0m assignment requires that `counter` is borrowed for `'static`",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;246m5 │\u001b[0m \u001b[38;5;100m}\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;100m┬\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m `counter` dropped here while still borrowed",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn createclosure() -> impl FnMut() {\n",
    "    let mut counter = 0;\n",
    "    let f = || {counter = counter+1; println!(\"counter is {}\",counter);};\n",
    "    f\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "73d1a928-09fb-4906-9845-7e3b427ca219",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn createclosure() -> impl FnMut() {\n",
    "    let mut counter = 0;\n",
    "    let f = move || {counter = counter+1; println!(\"counter is {}\",counter);};\n",
    "    f\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9dbe375b-d5f8-42c7-88f6-2b90ece71059",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let mut x = createclosure();\n",
    "    for _i in 0..10 { \n",
    "        x();\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d6813dad-c67a-47a4-a02d-9c185ac228df",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "counter is 1\n",
      "counter is 2\n",
      "counter is 3\n",
      "counter is 4\n",
      "counter is 5\n",
      "counter is 6\n",
      "counter is 7\n",
      "counter is 8\n",
      "counter is 9\n",
      "counter is 10\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90da4eaa-95ad-42bd-83eb-5b8a5070e80c",
   "metadata": {},
   "source": [
    "**Exercise:** Implement an iterator using closures"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ddfe8aad-440c-472c-b502-c50102fe9d03",
   "metadata": {},
   "source": [
    "- Closures behave like functions in terms of borrowing heap values"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3904595-45a7-40db-9bb3-e468328a3822",
   "metadata": {},
   "source": [
    "*Example 1:*\n",
    "- Closure only reads the vector `list`, so borrowing suffices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "53576504-2479-4805-9db8-d288fdc86aab",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let list = vec![1, 2, 3];\n",
    "    println!(\"Before defining closure: {:?}\", list);\n",
    "\n",
    "    let only_borrows = || println!(\"From closure: {:?}\", list);\n",
    "\n",
    "    println!(\"Before calling closure: {:?}\", list);\n",
    "    only_borrows();\n",
    "    println!(\"After calling closure: {:?}\", list);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "c0b18139-5ed2-497d-b816-0050907f3adf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Before defining closure: [1, 2, 3]\n",
      "Before calling closure: [1, 2, 3]\n",
      "From closure: [1, 2, 3]\n",
      "After calling closure: [1, 2, 3]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d87fc681-7312-4829-95f2-d26a9a4b725c",
   "metadata": {},
   "source": [
    "*Example 2:* \n",
    "- If the closure changes the mutable variable, borrowing is not enough"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "386f0dfc-509a-43f6-aff1-7012aa5a5104",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot borrow `borrows_mutably` as mutable, as it is not declared as mutable",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0596] Error:\u001b[0m cannot borrow `borrows_mutably` as mutable, as it is not declared as mutable",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_15:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m5 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mb\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mb\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249my\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m|\u001b[0m\u001b[38;5;249m|\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100mi\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100mt\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m7\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m         \u001b[38;5;68m│\u001b[0m                    \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m         \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m help: consider changing this to be mutable: `mut `",
      " \u001b[38;5;240m  │\u001b[0m                                \u001b[38;5;100m│\u001b[0m   ",
      " \u001b[38;5;240m  │\u001b[0m                                \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m calling `borrows_mutably` requires mutable binding due to mutable borrow of `list`",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;246m7 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mb\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mw\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54m_\u001b[0m\u001b[38;5;54mm\u001b[0m\u001b[38;5;54mu\u001b[0m\u001b[38;5;54mt\u001b[0m\u001b[38;5;54ma\u001b[0m\u001b[38;5;54mb\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54my\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m     \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m            \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m cannot borrow as mutable",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;115mNote\u001b[0m: You can change an existing variable to mutable like: `let mut x = x;`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn main() {\n",
    "    let mut list = vec![1, 2, 3];\n",
    "    println!(\"Before defining closure: {:?}\", list);\n",
    "\n",
    "    let borrows_mutably = || list.push(7);\n",
    "\n",
    "    borrows_mutably();\n",
    "    println!(\"After calling closure: {:?}\", list);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c009efe9-7ea5-4fb1-b265-be0b89d9ada6",
   "metadata": {},
   "source": [
    "*Example 3:* \n",
    "- If we only update, we can declare the closure to be mutable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d4f92de2-dba6-48a3-a149-640384b2ec05",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let mut list = vec![1, 2, 3];\n",
    "    println!(\"Before defining closure: {:?}\", list);\n",
    "\n",
    "    let mut borrows_mutably = || list.push(7);\n",
    "\n",
    "    borrows_mutably();\n",
    "    println!(\"After calling closure: {:?}\", list);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "72ef13bb-c273-4157-aecc-a3d065ddead1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Before defining closure: [1, 2, 3]\n",
      "After calling closure: [1, 2, 3, 7]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97d6ed0e-a618-46f4-b676-efafc2818c10",
   "metadata": {},
   "source": [
    "*Example 4:*\n",
    "- In the example above, the final `println!` comes after the closure is used, so the mutable reference is no longer needed by the closure and `list` can be borrowed by `println!`\n",
    "- Adding a `println!` between the definition of the closure and its invocation violates Rust's ownership rules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76fb1f24-fac0-43ed-89d0-fc55d6b307f0",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot borrow `list` as immutable because it is also borrowed as mutable",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0502] Error:\u001b[0m cannot borrow `list` as immutable because it is also borrowed as mutable",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_18:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m5 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mb\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mb\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249my\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100m|\u001b[0m\u001b[38;5;100m|\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;68ml\u001b[0m\u001b[38;5;68mi\u001b[0m\u001b[38;5;68ms\u001b[0m\u001b[38;5;68mt\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m7\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m                               \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m \u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m┬\u001b[0m\u001b[38;5;68m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m                                \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m mutable borrow occurs here",
      " \u001b[38;5;240m  │\u001b[0m                                    \u001b[38;5;68m│\u001b[0m   ",
      " \u001b[38;5;240m  │\u001b[0m                                    \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m first borrow occurs due to use of `list` in closure",
      " \u001b[38;5;246m6 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m!\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mA\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m?\u001b[0m\u001b[38;5;249m}\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54mt\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m                                              \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m                                                \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m immutable borrow occurs here",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;246m8 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;37mb\u001b[0m\u001b[38;5;37mo\u001b[0m\u001b[38;5;37mr\u001b[0m\u001b[38;5;37mr\u001b[0m\u001b[38;5;37mo\u001b[0m\u001b[38;5;37mw\u001b[0m\u001b[38;5;37ms\u001b[0m\u001b[38;5;37m_\u001b[0m\u001b[38;5;37mm\u001b[0m\u001b[38;5;37mu\u001b[0m\u001b[38;5;37mt\u001b[0m\u001b[38;5;37ma\u001b[0m\u001b[38;5;37mb\u001b[0m\u001b[38;5;37ml\u001b[0m\u001b[38;5;37my\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m     \u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m┬\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m            \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m mutable borrow later used here",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn main() {\n",
    "    let mut list = vec![1, 2, 3];\n",
    "    println!(\"Before defining closure: {:?}\", list);\n",
    "\n",
    "    let mut borrows_mutably = || list.push(7);\n",
    "    println!(\"After defining closure: {:?}\", list);\n",
    "    \n",
    "    borrows_mutably();\n",
    "    println!(\"After calling closure: {:?}\", list);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0760a460-57d9-4f3f-9dfc-db55bcdc35bf",
   "metadata": {},
   "source": [
    "### Defining threads\n",
    "- In Java, threads are created using the `Thread` class and calling `start()`, which implicitly invokes `run()` (which must be defined because of the structure of `Thread`)\n",
    "- In Rust, we *spawn* a thread by passing a closure\n",
    "- There are functions to sleep etc, as usual"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "8772d76a-ba1a-4425-9fb3-7946abdf971a",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::thread;\n",
    "use std::time::Duration;\n",
    "\n",
    "fn main() {\n",
    "    thread::spawn(|| {\n",
    "        for i in 1..10 {\n",
    "            println!(\"hi number {} from the spawned thread!\", i);\n",
    "            thread::sleep(Duration::from_millis(1));\n",
    "        }\n",
    "    });\n",
    "\n",
    "    for i in 1..5 {\n",
    "        println!(\"hi number {} from the main thread!\", i);\n",
    "        thread::sleep(Duration::from_millis(1));\n",
    "    }\n",
    "}\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "3b70aea3-0326-422f-aab5-d810d44342ce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi number 1 from the main thread!\n",
      "hi number 1 from the spawned thread!\n",
      "hi number 2 from the main thread!\n",
      "hi number 2 from the spawned thread!\n",
      "hi number 3 from the main thread!\n",
      "hi number 3 from the spawned thread!\n",
      "hi number 4 from the main thread!\n",
      "hi number 4 from the spawned thread!\n",
      "hi number 5 from the spawned thread!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4db0fa6-01f2-410c-9321-26db4e72b12a",
   "metadata": {},
   "source": [
    "- Note that the spawned thread prematurely exited when the main function terminated\n",
    "- We can wait for the thread to end using `join()`\n",
    "    - The return value of `spawn` is stored in a variable, which is used to invoke `join()`\n",
    "    - Note: You may have to restart the kernel to see the output show below"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "331d02f8-a1f3-4a9b-aa24-9cc1e2eaf991",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi number 6 from the spawned thread!\n",
      "hi number 7 from the spawned thread!\n",
      "hi number 8 from the spawned thread!\n",
      "hi number 9 from the spawned thread!\n"
     ]
    }
   ],
   "source": [
    "use std::thread;\n",
    "use std::time::Duration;\n",
    "\n",
    "fn main() {\n",
    "    let handle = thread::spawn(|| {\n",
    "        for i in 1..10 {\n",
    "            println!(\"hi number {} from the spawned thread!\", i);\n",
    "            thread::sleep(Duration::from_millis(1));\n",
    "        }\n",
    "    });\n",
    "\n",
    "    for i in 1..5 {\n",
    "        println!(\"hi number {} from the main thread!\", i);\n",
    "        thread::sleep(Duration::from_millis(1));\n",
    "    }\n",
    "\n",
    "    handle.join().unwrap();\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "f3f89a32-ba24-4fc8-b5ea-8ace3fc32ad8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi number 1 from the main thread!\n",
      "hi number 1 from the spawned thread!\n",
      "hi number 2 from the main thread!\n",
      "hi number 2 from the spawned thread!\n",
      "hi number 3 from the main thread!\n",
      "hi number 3 from the spawned thread!\n",
      "hi number 4 from the main thread!\n",
      "hi number 4 from the spawned thread!\n",
      "hi number 5 from the spawned thread!\n",
      "hi number 6 from the spawned thread!\n",
      "hi number 7 from the spawned thread!\n",
      "hi number 8 from the spawned thread!\n",
      "hi number 9 from the spawned thread!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85e661d1-ed67-4dc6-b946-5e2a3eaec43b",
   "metadata": {},
   "source": [
    "- Wherever the `join()` occurs, the concurrent execution blocks\n",
    "- The example below waits for the spawned thread to complete before executing the main thread"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "d09385c5-3eb2-4d5f-92ac-4d0c202b1869",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::thread;\n",
    "use std::time::Duration;\n",
    "\n",
    "fn main() {\n",
    "    let handle = thread::spawn(|| {\n",
    "        for i in 1..10 {\n",
    "            println!(\"hi number {} from the spawned thread!\", i);\n",
    "            thread::sleep(Duration::from_millis(1));\n",
    "        }\n",
    "    });\n",
    "\n",
    "    handle.join().unwrap();\n",
    "\n",
    "    for i in 1..5 {\n",
    "        println!(\"hi number {} from the main thread!\", i);\n",
    "        thread::sleep(Duration::from_millis(1));\n",
    "    }\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "2bcc381a-ddc4-4a48-a8fa-87c516b04925",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi number 1 from the spawned thread!\n",
      "hi number 2 from the spawned thread!\n",
      "hi number 3 from the spawned thread!\n",
      "hi number 4 from the spawned thread!\n",
      "hi number 5 from the spawned thread!\n",
      "hi number 6 from the spawned thread!\n",
      "hi number 7 from the spawned thread!\n",
      "hi number 8 from the spawned thread!\n",
      "hi number 9 from the spawned thread!\n",
      "hi number 1 from the main thread!\n",
      "hi number 2 from the main thread!\n",
      "hi number 3 from the main thread!\n",
      "hi number 4 from the main thread!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "053bde1d-9e74-46d3-a316-66fdbd7f9fa8",
   "metadata": {},
   "source": [
    "- We have to be careful about lifetimes, as with normal functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "99bbcfe8-5252-4e30-af51-c10e0d2da647",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "closure may outlive the current function, but it borrows `v`, which is owned by the current function",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0373] Error:\u001b[0m closure may outlive the current function, but it borrows `v`, which is owned by the current function",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_25:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m6 │\u001b[0m \u001b[38;5;68m╭\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m▶\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;68mt\u001b[0m\u001b[38;5;68mh\u001b[0m\u001b[38;5;68mr\u001b[0m\u001b[38;5;68me\u001b[0m\u001b[38;5;68ma\u001b[0m\u001b[38;5;68md\u001b[0m\u001b[38;5;68m:\u001b[0m\u001b[38;5;68m:\u001b[0m\u001b[38;5;68ms\u001b[0m\u001b[38;5;68mp\u001b[0m\u001b[38;5;68ma\u001b[0m\u001b[38;5;68mw\u001b[0m\u001b[38;5;68mn\u001b[0m\u001b[38;5;68m(\u001b[0m\u001b[38;5;100m|\u001b[0m\u001b[38;5;100m|\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m{\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m│\u001b[0m                                  \u001b[38;5;37m┬\u001b[0m\u001b[38;5;100m┬\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m│\u001b[0m                                  \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword: `move `",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m│\u001b[0m                                   \u001b[38;5;100m│\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m│\u001b[0m                                   \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m may outlive borrowed value `v`",
      " \u001b[38;5;246m7 │\u001b[0m \u001b[38;5;68m│\u001b[0m   \u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68mp\u001b[0m\u001b[38;5;68mr\u001b[0m\u001b[38;5;68mi\u001b[0m\u001b[38;5;68mn\u001b[0m\u001b[38;5;68mt\u001b[0m\u001b[38;5;68ml\u001b[0m\u001b[38;5;68mn\u001b[0m\u001b[38;5;68m!\u001b[0m\u001b[38;5;68m(\u001b[0m\u001b[38;5;68m\"\u001b[0m\u001b[38;5;68mH\u001b[0m\u001b[38;5;68me\u001b[0m\u001b[38;5;68mr\u001b[0m\u001b[38;5;68me\u001b[0m\u001b[38;5;68m'\u001b[0m\u001b[38;5;68ms\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68ma\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68mv\u001b[0m\u001b[38;5;68me\u001b[0m\u001b[38;5;68mc\u001b[0m\u001b[38;5;68mt\u001b[0m\u001b[38;5;68mo\u001b[0m\u001b[38;5;68mr\u001b[0m\u001b[38;5;68m:\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m{\u001b[0m\u001b[38;5;68m:\u001b[0m\u001b[38;5;68m?\u001b[0m\u001b[38;5;68m}\u001b[0m\u001b[38;5;68m\"\u001b[0m\u001b[38;5;68m,\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;54mv\u001b[0m\u001b[38;5;68m)\u001b[0m\u001b[38;5;68m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m│\u001b[0m                                             \u001b[38;5;54m┬\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m│\u001b[0m                                             \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m `v` is borrowed here",
      " \u001b[38;5;246m8 │\u001b[0m \u001b[38;5;68m├\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m▶\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68m}\u001b[0m\u001b[38;5;68m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m│\u001b[0m             ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m note: function requires argument type to outlive `'static`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let v = vec![1, 2, 3];\n",
    "\n",
    "    let handle = thread::spawn(|| {\n",
    "        println!(\"Here's a vector: {:?}\", v);\n",
    "    });\n",
    "\n",
    "    handle.join().unwrap();\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8552f481-9c3c-4081-adfd-df7e7ee97436",
   "metadata": {},
   "source": [
    "- For instance, the main thread could have \"unset\" the value of `v` using `drop(v)`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c97c9952-290a-401e-8ffa-299b3a387771",
   "metadata": {},
   "source": [
    "```\n",
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let v = vec![1, 2, 3];\n",
    "\n",
    "    let handle = thread::spawn(|| {\n",
    "        println!(\"Here's a vector: {:?}\", v);\n",
    "    });\n",
    "\n",
    "    drop(v); // oh no!\n",
    "\n",
    "    handle.join().unwrap();\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c74bb15-03dd-40f2-9b32-6992f5c4211c",
   "metadata": {},
   "source": [
    "- One solution is to `move` the vector to the closure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "68eefdfd-accb-461a-80aa-dfe1fd745952",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let v = vec![1, 2, 3];\n",
    "\n",
    "    let handle = thread::spawn(move || {\n",
    "        println!(\"Here's a vector: {:?}\", v);\n",
    "    });\n",
    "\n",
    "    handle.join().unwrap();\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "8dd88fca-9d6c-4aad-902b-33afbf3d7847",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Here's a vector: [1, 2, 3]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85a34d18-931d-48b4-8f1e-8b50481568c4",
   "metadata": {},
   "source": [
    "### Coordinating threads"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0644337b-c67a-4ee6-9f60-ed30602daedf",
   "metadata": {},
   "source": [
    "#### Message passing"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0034427-fa00-421b-83f2-2ff5d590838a",
   "metadata": {},
   "source": [
    "- *\"Do not communicate by sharing variables, instead share variables by communicating\"*\n",
    "- Send values via a channel\n",
    "- By convention, *producer* sends messages on the channel and *consumer* receives them\n",
    "- `mpsc` stands for *multiple producer, single consumer*\n",
    "    - Many threads can write to the same channel, only one thread can read it"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07fb68f9-3a14-41fe-a4db-f14feb36e4aa",
   "metadata": {},
   "source": [
    "- Creating a channel returns a pair, handles to transmit (`tx`, below) and receive (`rx`, below)\n",
    "- In this example, the spawned thread sends on `tx`, the main thread receives on `rx`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "c93e378e-1362-4916-825c-a1c84239c896",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::sync::mpsc;\n",
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let (tx, rx) = mpsc::channel();\n",
    "\n",
    "    thread::spawn(move || {\n",
    "        let val = String::from(\"hi\");\n",
    "        tx.send(val).unwrap();\n",
    "    });\n",
    "\n",
    "    let received = rx.recv().unwrap();\n",
    "    println!(\"Got: {}\", received);\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "417efa8d-534d-4a3e-8b9a-648e7690420a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Got: hi\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ef60013-49c9-49c8-8a7d-0293bea07c3d",
   "metadata": {},
   "source": [
    "- Sending a value `move`s it to the receiver\n",
    "- In the example below, the spawned thread cannot refer to `val` after sending it to the main thread"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d430275-3ea5-487b-909e-4c0b8084a234",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "borrow of moved value: `val`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0382] Error:\u001b[0m borrow of moved value: `val`",
      "    \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_30:1:1\u001b[38;5;246m]\u001b[0m",
      "    \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m 8 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;68mv\u001b[0m\u001b[38;5;68ma\u001b[0m\u001b[38;5;68ml\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mS\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m             \u001b[38;5;68m─\u001b[0m\u001b[38;5;68m┬\u001b[0m\u001b[38;5;68m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m              \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m move occurs because `val` has type `String`, which does not implement the `Copy` trait",
      " \u001b[38;5;246m 9 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;54mv\u001b[0m\u001b[38;5;54ma\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                 \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m                  \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m value moved here",
      " \u001b[38;5;246m10 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m!\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mS\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m\u001b[38;5;249m}\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100mv\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                              \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m                               \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m value borrowed here after move",
      "\u001b[38;5;246m────╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "use std::sync::mpsc;\n",
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let (tx, rx) = mpsc::channel();\n",
    "\n",
    "    thread::spawn(move || {\n",
    "        let val = String::from(\"hi\");\n",
    "        tx.send(val).unwrap();\n",
    "        println!(\"Sent: {}\", val);\n",
    "    });\n",
    "\n",
    "    let received = rx.recv().unwrap();\n",
    "    println!(\"Got: {}\", received);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b46723b-39fd-40b5-b13d-03cfb69f1143",
   "metadata": {},
   "source": [
    "- It is permissible to print `val` before sending it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "fb4ddcef-af5f-4bf8-80c9-919a1f09f965",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::sync::mpsc;\n",
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let (tx, rx) = mpsc::channel();\n",
    "\n",
    "    thread::spawn(move || {\n",
    "        let val = String::from(\"hi\");\n",
    "        println!(\"Going to send: {}\", val);\n",
    "        tx.send(val).unwrap();\n",
    "    });\n",
    "\n",
    "    let received = rx.recv().unwrap();\n",
    "    println!(\"Got: {}\", received);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "0b2b81ee-bc8a-46b7-b663-89ed024a14cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Going to send: hi\n",
      "Got: hi\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be45d7b3-4ba5-447e-95b9-2a6788e65037",
   "metadata": {},
   "source": [
    "- A channel can have multiple senders (producers)\n",
    "- Here we clone `tx` and pass `tx` to first spawned thread and `tx1` to second spawned thread\n",
    "- The contents are received as some arbitrary interleaving"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "2b7f9a37-c5e1-41bb-975a-22c437e79ab3",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::sync::mpsc;\n",
    "use std::thread;\n",
    "use std::time::Duration;\n",
    "\n",
    "fn main() {\n",
    "\n",
    "    let (tx, rx) = mpsc::channel();\n",
    "\n",
    "    let tx1 = tx.clone();\n",
    "    \n",
    "    thread::spawn(move || {\n",
    "        let vals = vec![\n",
    "            String::from(\"hi\"),\n",
    "            String::from(\"from\"),\n",
    "            String::from(\"the\"),\n",
    "            String::from(\"thread\"),\n",
    "        ];\n",
    "\n",
    "        for val in vals {\n",
    "            tx.send(val).unwrap();\n",
    "            thread::sleep(Duration::from_secs(1));\n",
    "        }\n",
    "    });\n",
    "\n",
    "    thread::spawn(move || {\n",
    "        let vals = vec![\n",
    "            String::from(\"more\"),\n",
    "            String::from(\"messages\"),\n",
    "            String::from(\"for\"),\n",
    "            String::from(\"you\"),\n",
    "        ];\n",
    "\n",
    "        for val in vals {\n",
    "            tx1.send(val).unwrap();\n",
    "            thread::sleep(Duration::from_secs(1));\n",
    "        }\n",
    "    });\n",
    "\n",
    "    for received in rx {\n",
    "        println!(\"Got: {}\", received);\n",
    "    }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "88eca57a-39e1-43d9-8351-bfbdd9ae16f4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Got: hi\n",
      "Got: more\n",
      "Got: from\n",
      "Got: messages\n",
      "Got: for\n",
      "Got: the\n",
      "Got: thread\n",
      "Got: you\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a56aac81-547f-4951-afd3-49d4789051d9",
   "metadata": {},
   "source": [
    "- We cannot clone the receive handle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b74d8273-3cf6-4a9d-8c73-4a829d4bc567",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "no method named `clone` found for struct `std::sync::mpsc::Receiver<T>` in the current scope",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0599] Error:\u001b[0m no method named `clone` found for struct `std::sync::mpsc::Receiver<T>` in the current scope",
      "    \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_35:1:1\u001b[38;5;246m]\u001b[0m",
      "    \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m10 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249m1\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;54mc\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mn\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                  \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m                    \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m method not found in `std::sync::mpsc::Receiver<_>`",
      "\u001b[38;5;246m────╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "use std::sync::mpsc;\n",
    "use std::thread;\n",
    "use std::time::Duration;\n",
    "\n",
    "fn main() {\n",
    "\n",
    "    let (tx, rx) = mpsc::channel();\n",
    "\n",
    "    let tx1 = tx.clone();\n",
    "    let rx1 = rx.clone();\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "902e94cc-ff10-4732-b4c4-6884b8f20e03",
   "metadata": {},
   "source": [
    "### Shared variables\n",
    "- This is the \"normal\" way to communicate in Java etc\n",
    "- Recall that we have to have a mechanism to avoid race conditions\n",
    "- Rust provides `Mutex` for this\n",
    "    - To share a variable \"safely\", wrap it a `Mutex`\n",
    "    - Each `Mutex` is equipped with a lock\n",
    "    - To access the variable, need to acquire the lock -- wait if it is not available\n",
    "    - There is no `unlock()`! The lock is automatically released when the lock goes out of scope\n",
    "    - Avoid typical pitfalls with forgetting to unlock, unlocking something that is not locked etc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "7f5cad8c-3a56-4f9f-8ec4-8d2573580ebc",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::sync::Mutex;\n",
    "\n",
    "fn main() {\n",
    "    let m = Mutex::new(5);\n",
    "\n",
    "    {\n",
    "        let mut num = m.lock().unwrap();\n",
    "        *num = 6;\n",
    "    }\n",
    "\n",
    "    println!(\"m = {:?}\", m);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "57eceacd-1327-4be0-ad6e-467032f141f9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "m = Mutex { data: 6, poisoned: false, .. }\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79438e00-0903-440d-816a-9c77b179af95",
   "metadata": {},
   "source": [
    "- Note that printing a `Mutex` gives extra information\n",
    "- `poisoned` is a flag that is set if thread holding mutex crashes"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d38170e8-8448-42ee-84fc-1e217887832d",
   "metadata": {},
   "source": [
    "- `Mutex<T>`, can hold any type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "423f5675-7ff8-417a-9b1a-6698138fc52a",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::sync::Mutex;\n",
    "\n",
    "fn main() {\n",
    "    let m = Mutex::new(String::from(\"Hello\"));\n",
    "\n",
    "    {\n",
    "        let mut msg = m.lock().unwrap();\n",
    "        *msg = String::from(\"World\");\n",
    "    }\n",
    "\n",
    "    println!(\"m = {:?}\", m);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "8a136528-c083-413a-88d7-f2408e3a26c0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "m = Mutex { data: \"World\", poisoned: false, .. }\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58e8e751-940e-42e8-9939-852f807b8fdb",
   "metadata": {},
   "source": [
    "- In the example above, the `lock()` was in an inner block\n",
    "- In the example below, the lock is released when `main()` exits\n",
    "- When we print `m`, it is still reported as `locked`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "72816334-c440-4ad6-9b42-6b07ac591772",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "fn main() {\n",
    "    let m = Mutex::new(5);\n",
    "\n",
    "    let mut num = m.lock().unwrap();\n",
    "    *num = 6;\n",
    "    \n",
    "    println!(\"m = {:?}\", m);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "ff83d6bf-0746-4370-9929-2f72ba2fca48",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "m = Mutex { data: \"<locked>\", poisoned: false, .. }\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "497f49b8-0120-41b1-b73e-1ead48c8b292",
   "metadata": {},
   "source": [
    "- How can we share a `Mutex` across threads?\n",
    "- Ownership problem: can have only one owner for a `Mutex`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6089af08-9ef3-46b7-8cad-7f3b8e8a6888",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot borrow `num` as mutable, as it is not declared as mutable",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0596] Error:\u001b[0m cannot borrow `num` as mutable, as it is not declared as mutable",
      "    \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_42:1:1\u001b[38;5;246m]\u001b[0m",
      "    \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m10 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249mk\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                 \u001b[38;5;100m│\u001b[0m ",
      " \u001b[38;5;240m   │\u001b[0m                 \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m help: consider changing this to be mutable: `mut `",
      " \u001b[38;5;240m   │\u001b[0m ",
      " \u001b[38;5;246m12 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m*\u001b[0m\u001b[38;5;54mn\u001b[0m\u001b[38;5;54mu\u001b[0m\u001b[38;5;54mm\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m+\u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m1\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m              \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m               \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m cannot borrow as mutable",
      " \u001b[38;5;240m   │\u001b[0m ",
      " \u001b[38;5;240m   │\u001b[0m \u001b[38;5;115mNote\u001b[0m: You can change an existing variable to mutable like: `let mut x = x;`",
      "\u001b[38;5;246m────╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "borrow of moved value: `counter`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0382] Error:\u001b[0m borrow of moved value: `counter`",
      "    \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_42:1:1\u001b[38;5;246m]\u001b[0m",
      "    \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m 5 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;37mc\u001b[0m\u001b[38;5;37mo\u001b[0m\u001b[38;5;37mu\u001b[0m\u001b[38;5;37mn\u001b[0m\u001b[38;5;37mt\u001b[0m\u001b[38;5;37me\u001b[0m\u001b[38;5;37mr\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mM\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m0\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m         \u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m┬\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m            \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m move occurs because `counter` has type `std::sync::Mutex<i32>`, which does not implement the `Copy` trait",
      " \u001b[38;5;240m   │\u001b[0m ",
      " \u001b[38;5;246m 8 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mf\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m_\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54mn\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m0\u001b[0m\u001b[38;5;54m.\u001b[0m\u001b[38;5;54m.\u001b[0m\u001b[38;5;54m1\u001b[0m\u001b[38;5;54m0\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m     \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m            \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m inside of this loop",
      " \u001b[38;5;246m 9 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;100mm\u001b[0m\u001b[38;5;100mo\u001b[0m\u001b[38;5;100mv\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100m \u001b[0m\u001b[38;5;100m|\u001b[0m\u001b[38;5;100m|\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                                    \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m                                       \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m value moved into closure here, in previous iteration of loop",
      " \u001b[38;5;240m   │\u001b[0m ",
      " \u001b[38;5;246m21 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m!\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mR\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m\u001b[38;5;249m}\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m*\u001b[0m\u001b[38;5;68mc\u001b[0m\u001b[38;5;68mo\u001b[0m\u001b[38;5;68mu\u001b[0m\u001b[38;5;68mn\u001b[0m\u001b[38;5;68mt\u001b[0m\u001b[38;5;68me\u001b[0m\u001b[38;5;68mr\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249mk\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m   │\u001b[0m                             \u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m┬\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m  ",
      " \u001b[38;5;240m   │\u001b[0m                                \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m value borrowed here after move",
      "\u001b[38;5;246m────╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "use std::sync::Mutex;\n",
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let counter = Mutex::new(0);\n",
    "    let mut handles = vec![];\n",
    "\n",
    "    for _ in 0..10 {\n",
    "        let handle = thread::spawn(move || {\n",
    "            let num = counter.lock().unwrap();\n",
    "\n",
    "            *num += 1;\n",
    "        });\n",
    "        handles.push(handle);\n",
    "    }\n",
    "\n",
    "    for handle in handles {\n",
    "        handle.join().unwrap();\n",
    "    }\n",
    "\n",
    "    println!(\"Result: {}\", *counter.lock().unwrap());\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "273effe2-34fc-454e-b2ed-a3c428acac8a",
   "metadata": {},
   "source": [
    "#### Reference counting\n",
    "- Main motivation for single ownership is to avoid problems when heap storage is released\n",
    "- If `l1` and `l2` both refer to the same list and we \"drop\" `l2`, the value `l1` becomes undefined\n",
    "- One way to deal with this is **reference counting**\n",
    "    - When we assign a variable to point to a chunk of heap storage, set reference count to one\n",
    "    - When we add a new reference to same storage, increment reference count\n",
    "    - When we \"drop\" a reference, decrement reference count\n",
    "    - Release storage only when reference count becomes 0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fc71cde-44b9-4f85-992f-63499907c0df",
   "metadata": {},
   "source": [
    "- Rust allows us to explicitly use reference counting\n",
    "- Simplest version in concurrent programming context is to wrap the value in `Arc`\n",
    "    - `Arc` stands for *Atomic reference counter*\n",
    "    - Combines reference counting with atomic updates, making the contents safe to share across threads\n",
    "- Below, we wrap clone `Mutex` within an `Arc` and create cloned `Arc` references within each thread"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "df0616e6-b71d-46fc-ad16-d6ad0213339e",
   "metadata": {},
   "outputs": [],
   "source": [
    "use std::sync::{Arc, Mutex};\n",
    "use std::thread;\n",
    "\n",
    "fn main() {\n",
    "    let counter = Arc::new(Mutex::new(0));\n",
    "    let mut handles = vec![];\n",
    "\n",
    "    for _ in 0..10 {\n",
    "        let counter = Arc::clone(&counter);\n",
    "        let handle = thread::spawn(move || {\n",
    "            let mut num = counter.lock().unwrap();\n",
    "\n",
    "            *num += 1;\n",
    "        });\n",
    "        handles.push(handle);\n",
    "    }\n",
    "\n",
    "    for handle in handles {\n",
    "        handle.join().unwrap();\n",
    "    }\n",
    "\n",
    "    println!(\"Result: {}\", *counter.lock().unwrap());\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "9968e248-4b8f-482f-94a7-06319eb00cf1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Result: 10\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4feb53c8-b974-4043-afe6-7c69bd1a8209",
   "metadata": {},
   "source": [
    "### Race conditions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26c77648-1881-4d5c-b277-4725281aacd6",
   "metadata": {},
   "source": [
    "- Rust is designed to *prohibit* race conditions in normal code\n",
    "- Ownership, lifetimes etc ensure this"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Rust",
   "language": "rust",
   "name": "rust"
  },
  "language_info": {
   "codemirror_mode": "rust",
   "file_extension": ".rs",
   "mimetype": "text/rust",
   "name": "Rust",
   "pygment_lexer": "rust",
   "version": ""
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
