{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e170df5a-7f85-4133-972c-4cb137eb4460",
   "metadata": {},
   "source": [
    "# PLC 2026, Lecture 10, 12 February 2026"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f6b0831-5e20-4945-8714-94b8a16860c3",
   "metadata": {},
   "source": [
    "### Tuples\n",
    "- Similar to other languages\n",
    "- Can deconstruct by assigning to a tuple of variables\n",
    "- Index by position using `t.0`, `t.1`, ..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a2d8a869-bde3-4cc5-8043-9dc62d865066",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let tup = (500, 6.4, 1);\n",
    "    let (x, y, z) = tup;\n",
    "    println!(\"The value of y is: {y}\");\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "01a948b9-9eb1-440b-9996-e6932bbc5277",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The value of y is: 6.4\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "33b59758-f01c-4162-a067-3d0561225fe0",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let x: (i32, f64, u8) = (500, 6.4, 1);\n",
    "\n",
    "    let five_hundred = x.0;\n",
    "    let six_point_four = x.1;\n",
    "    let one = x.2;\n",
    "\n",
    "    println!(\"x.0 = {}, x.1 = {}, x.2 = {}\", five_hundred, six_point_four,one);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f567ce7f-b5a0-4c7e-a322-77417cd8df07",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x.0 = 500, x.1 = 6.4, x.2 = 1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "097a08f3-b8be-456e-869f-a9dce6e19239",
   "metadata": {},
   "source": [
    "### Arrays\n",
    "- Notation, indexing are as usual"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "754fd3f8-e98f-4475-9770-fda4096282cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let a = [1, 2, 3, 4, 5];\n",
    "\n",
    "    let first = a[0];\n",
    "    let second = a[1];\n",
    "    println!(\"first is {}, second is {}\", first, second);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c43faf5d-1a54-4d1d-9f77-81ee55d08ed9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "first is 1, second is 2\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "5b57cb70-91d0-43a7-9cbc-a9e0b751b0d1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "let a = [1,2,3,4,5];\n",
    "println!(\"{}\",a.len());"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "443dec23-764a-44aa-9665-219a0f5a5343",
   "metadata": {},
   "source": [
    "- Type of an array includes its length!\n",
    "    - Functions can only work on arrays of a fixed length"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe468ace-ca03-480d-b41a-ad085e0ff36a",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "the size for values of type `[i32]` cannot be known at compilation time",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0277] Error:\u001b[0m the size for values of type `[i32]` cannot be known at compilation time",
      "   \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;246m1 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;54m[\u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54m3\u001b[0m\u001b[38;5;54m2\u001b[0m\u001b[38;5;54m]\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;249mi\u001b[0m\u001b[38;5;249m3\u001b[0m\u001b[38;5;249m2\u001b[0m\u001b[38;5;249m{\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m               \u001b[38;5;100m┬\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;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 help: function arguments must have a statically known size, borrowed slices always have a known size: `&`",
      " \u001b[38;5;240m  │\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 doesn't have a size known at compile-time",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn lastelem(a:[i32]) -> i32{\n",
    "    let l = a.len();\n",
    "    a[l-1]\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4359af0a-8b05-4dfb-9434-fbe4026145ba",
   "metadata": {},
   "source": [
    "- Trick: Explicitly type with wrong type to reveal type of a value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f0d45f9d-03f6-44a2-94b4-bfaffa86ddca",
   "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_10:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m1 │\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;249ma\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;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54m[\u001b[0m\u001b[38;5;54m1\u001b[0m\u001b[38;5;54m,\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m2\u001b[0m\u001b[38;5;54m,\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m3\u001b[0m\u001b[38;5;54m,\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m4\u001b[0m\u001b[38;5;54m,\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m5\u001b[0m\u001b[38;5;54m]\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;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;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;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 expected due to this",
      " \u001b[38;5;240m  │\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 expected `()`, found `[{integer}; 5]`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "let a:() = [1, 2, 3, 4, 5];"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "8ba8eec6-df06-44ae-8143-f911243a666e",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn lastelem(a:[i32;5]) -> i32{\n",
    "    let l = a.len();\n",
    "    a[l-1]\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "b569194d-f8bc-4326-8e01-9f90d8dcd741",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5,5\n"
     ]
    }
   ],
   "source": [
    "let b = [1,2,3,4,5];\n",
    "let n = lastelem(b);\n",
    "println!(\"{},{}\",n,b.len());"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a5291fd9-0194-4323-955e-f68e8a52533a",
   "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_13:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m2 │\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;100ml\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100mt\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100mm\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;54mb\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;54m┬\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 arguments to this function are incorrect",
      " \u001b[38;5;240m  │\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 expected an array with a size of 5, found one with a size of 6",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "let b = [1,2,3,4,5,6];\n",
    "let n = lastelem(b);\n",
    "println!(\"{},{}\",n,b.len());"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3b05450-e7a3-4d95-ab47-9ee16421e414",
   "metadata": {},
   "source": [
    "- How do we write a function that operates on variable length arrays?\n",
    "- Instead of passing an array, pass a reference via a slice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a2ab6ab4-9858-4e38-b445-797d70624054",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn lastelem(a:&[i32]) -> i32{\n",
    "    let l = a.len();\n",
    "    a[l-1]\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "bad92486-ca3a-4c01-91c0-8e67b7352c98",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n"
     ]
    }
   ],
   "source": [
    "let b = [1,2,3,4,5,7];\n",
    "let n = lastelem(&b[..]);\n",
    "println!(\"{}\",n);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "db33266a-3f8c-4476-9be5-ad082c122bfa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "let b = [1,2,3,4,5,7];\n",
    "let n = lastelem(&b[1..4]);\n",
    "println!(\"{}\",n);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75909408-1f9a-48e7-9276-2fa002ca199b",
   "metadata": {},
   "source": [
    "### Structs\n",
    "- Like a tuple with named components\n",
    "- Instance variables of a class"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "507df2c6-8637-4531-a782-7e3c602a7e2b",
   "metadata": {},
   "source": [
    "- Define a class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "d7068d84-db68-4145-b7d7-f85775a009c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct User {\n",
    "    active: bool,\n",
    "    username: String,\n",
    "    email: String,\n",
    "    sign_in_count: u64,\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09d1f1ff-bac9-4da4-9c2c-5e4a7b33d62a",
   "metadata": {},
   "source": [
    "- Create an instance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "9b6d637f-7625-4387-bc3d-f3f28568c0c5",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let user1 = User {\n",
    "        active: true,\n",
    "        username: String::from(\"someusername123\"),\n",
    "        email: String::from(\"someone@example.com\"),\n",
    "        sign_in_count: 1,\n",
    "    };\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c123205-0a42-412f-8eab-67d92fec0812",
   "metadata": {},
   "source": [
    "- No notion of `private`\n",
    "- Can always update a component directly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "7b880a61-6e98-4e98-9dfc-8e281de2544f",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let mut user1 = User {\n",
    "        active: true,\n",
    "        username: String::from(\"someusername123\"),\n",
    "        email: String::from(\"someone@example.com\"),\n",
    "        sign_in_count: 1,\n",
    "    };\n",
    "\n",
    "    user1.email = String::from(\"anotheremail@example.com\");\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e80c2a5-0cb5-4085-822c-5a1d80215b8a",
   "metadata": {},
   "source": [
    "- Can have a `struct` with unnamed components\n",
    "- A tuple is an unnamed `struct` with unnamed components"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "0f33d3f2-da01-4b44-922b-a5faa559ac78",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Color(i32, i32, i32);\n",
    "struct Point(i32, i32, i32);\n",
    "\n",
    "fn main() {\n",
    "    let black = Color(0, 0, 0);\n",
    "    let origin = Point(0, 0, 0);\n",
    "    let black_R = black.0;\n",
    "    let origin_z = origin.2;\n",
    "    println!(\"Black Red = {}, Origin Z = {}\", black_R, origin_z);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c53d0d6-4273-4059-840a-534e587f24ee",
   "metadata": {},
   "source": [
    "- `Color` and `Point` are distinct types, though they have the same structure `(i32, i32, i32)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee4c3173-5008-44d1-bbf5-c58439dedb14",
   "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_21:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m9 │\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;249me\u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;100mC\u001b[0m\u001b[38;5;100mo\u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100mo\u001b[0m\u001b[38;5;100mr\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54mg\u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54mn\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;249my\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249mh\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;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;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 expected due to this",
      " \u001b[38;5;240m  │\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 expected `Color`, found `Point`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "struct Color(i32, i32, i32);\n",
    "struct Point(i32, i32, i32);\n",
    "\n",
    "fn main() {\n",
    "    let black = Color(0, 0, 0);\n",
    "    let origin = Point(0, 0, 0);\n",
    "    let black_R = black.0;\n",
    "    let origin_z = origin.2;\n",
    "    let red:Color = origin; // Type mismatch\n",
    "    println!(\"Black Red = {}, Origin Z = {}\", black_R, origin_z);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d950f1b-8a6d-4914-bbe1-8a35672cc9c2",
   "metadata": {},
   "source": [
    "- The following works without any problem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "93848a28-173f-43d8-9fed-6a461c931343",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Color(i32, i32, i32);\n",
    "struct Point(i32, i32, i32);\n",
    "\n",
    "fn main() {\n",
    "    let black = Color(0, 0, 0);\n",
    "    let origin = Point(0, 0, 0);\n",
    "    let black_R = black.0;\n",
    "    let origin_z = origin.2;\n",
    "    let red:Color = black; // No problem\n",
    "    println!(\"Black Red = {}, Origin Z = {}\", black_R, origin_z);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "97b0b526-1565-47b9-9acf-3a2e56463571",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Black Red = 0, Origin Z = 0\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e32f1fb-d009-4c76-81a0-cb6b4dc3e1ef",
   "metadata": {},
   "source": [
    "- Can pass structs to functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "fd50fd27-72f4-4fd3-ae14-a850855b833e",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Rectangle {\n",
    "    width: u32,\n",
    "    height: u32,\n",
    "}\n",
    "\n",
    "fn area(rectangle: &Rectangle) -> u32 {\n",
    "    rectangle.width * rectangle.height\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let rect1 = Rectangle {\n",
    "        width: 30,\n",
    "        height: 50,\n",
    "    };\n",
    "\n",
    "    println!(\n",
    "        \"The area of the rectangle is {} square pixels.\",\n",
    "        area(&rect1)\n",
    "    );\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e27d3349-95a4-47de-8b75-c3d0bd4c0bb3",
   "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_25:1:1\u001b[38;5;246m]\u001b[0m",
      "    \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m18 │\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;100ma\u001b[0m\u001b[38;5;100mr\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54mc\u001b[0m\u001b[38;5;54mt\u001b[0m\u001b[38;5;54m1\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;68m┬\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;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;68m│\u001b[0m \u001b[38;5;54m│\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 help: consider borrowing here: `&`",
      " \u001b[38;5;240m   │\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 expected `&Rectangle`, found `Rectangle`",
      "\u001b[38;5;246m────╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "struct Rectangle {\n",
    "    width: u32,\n",
    "    height: u32,\n",
    "}\n",
    "\n",
    "fn area(rectangle: &Rectangle) -> u32 {\n",
    "    rectangle.width * rectangle.height\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let rect1 = Rectangle {\n",
    "        width: 30,\n",
    "        height: 50,\n",
    "    };\n",
    "\n",
    "    println!(\n",
    "        \"The area of the rectangle is {} square pixels.\",\n",
    "        area(rect1)\n",
    "    );\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "dc4e91ce-4e42-4943-9023-320d73cfb19a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The area of the rectangle is 1500 square pixels.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0021aea-9a10-49ef-a00a-79007399cbb5",
   "metadata": {},
   "source": [
    "- Attach functions to structs --- **methods**\n",
    "- First parameter of a method is always `&self` (shades of Python)\n",
    "    - Type of `&self` is fixed by the fact that `impl` refers to the `struct`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "c7839989-91e8-4247-9c43-86506d0b48ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Rectangle {\n",
    "    width: u32,\n",
    "    height: u32,\n",
    "}\n",
    "\n",
    "impl Rectangle {\n",
    "    fn area(&self) -> u32 {\n",
    "        self.width * self.height\n",
    "    }\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let rect1 = Rectangle {\n",
    "        width: 30,\n",
    "        height: 50,\n",
    "    };\n",
    "\n",
    "    println!(\n",
    "        \"The area of the rectangle is {} square pixels.\",\n",
    "        rect1.area()  // Should be (&rect1).area()\n",
    "    );\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "3da01161-e937-431a-92c4-48f45e639323",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The area of the rectangle is 1500 square pixels.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8bc9bda-a7d4-447b-b76d-9eb16e849f52",
   "metadata": {},
   "source": [
    "- Side note: Rust automatically references and dereferences\n",
    "    - We wrote `rect.area`, which is a short form for `(&rect).area`\n",
    "    - Inside the function, `self.width` and `self.length` instead of `(*self).width` and `(*self).length`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00367193-0386-4537-a567-260a99628daa",
   "metadata": {},
   "source": [
    "- Can define methods with parameters other than `self`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "d566fa73-d832-449c-a605-e267fdbbd105",
   "metadata": {},
   "outputs": [],
   "source": [
    "impl Rectangle {\n",
    "    fn can_hold(&self, other: &Rectangle) -> bool {\n",
    "        self.width > other.width && self.height > other.height\n",
    "    }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "1cb5f878-aec7-4297-8be1-c5dfe481f73e",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let rect1 = Rectangle {\n",
    "        width: 30,\n",
    "        height: 50,\n",
    "    };\n",
    "    let rect2 = Rectangle {\n",
    "        width: 10,\n",
    "        height: 40,\n",
    "    };\n",
    "    let rect3 = Rectangle {\n",
    "        width: 60,\n",
    "        height: 45,\n",
    "    };\n",
    "\n",
    "    println!(\"Can rect1 hold rect2? {}\", rect1.can_hold(&rect2));\n",
    "    println!(\"Can rect1 hold rect3? {}\", rect1.can_hold(&rect3));\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "84680760-b4c3-48d9-afef-08e8509753e1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Can rect1 hold rect2? true\n",
      "Can rect1 hold rect3? false\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc73a80a-8bdd-44b0-b9ae-83e07d4e69d4",
   "metadata": {},
   "source": [
    "### Generics"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "804e2dd7-4ff0-4ab2-8a83-4f60e0a31347",
   "metadata": {},
   "source": [
    "- Two functions to find the largest element in an array\n",
    "- Same code, except for the base type of the array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "69b3a399-22a6-4c3c-8e73-d8de1fbef595",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn largest_i32(list: &[i32]) -> &i32 {\n",
    "    let mut largest = &list[0];\n",
    "\n",
    "    for item in list {\n",
    "        if item > largest {\n",
    "            largest = item;\n",
    "        }\n",
    "    }\n",
    "\n",
    "    largest\n",
    "}\n",
    "\n",
    "fn largest_char(list: &[char]) -> &char {\n",
    "    let mut largest = &list[0];\n",
    "\n",
    "    for item in list {\n",
    "        if item > largest {\n",
    "            largest = item;\n",
    "        }\n",
    "    }\n",
    "\n",
    "    largest\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "4137d71b-e8b0-490d-9ec9-00e47f78fbbe",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let number_array = [34, 50, 25, 100, 65];\n",
    "    let number_list = &number_array[..];\n",
    "\n",
    "    let result = largest_i32(&number_list);\n",
    "    println!(\"The largest number is {}\", result);\n",
    "\n",
    "    let char_array = ['y', 'm', 'a', 'q'];\n",
    "    let char_list = &char_array[..];\n",
    "\n",
    "    let result = largest_char(&char_list);\n",
    "    println!(\"The largest char is {}\", result);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "ebcead18-3db2-45f6-997e-729b7713fcbe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The largest number is 100\n",
      "The largest char is y\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36c2915f-0aff-4a32-ab4b-1b6007dc6124",
   "metadata": {},
   "source": [
    "- Create a generic version of the function using a type variable, like Java\n",
    "- How to specify that the type `T` supports comparison of values?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ccf3edeb-b87f-4483-b728-a2ad1e5e468a",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "binary operation `>` cannot be applied to type `&T`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0369] Error:\u001b[0m binary operation `>` cannot be applied to type `&T`",
      "   \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;246m1 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m<\u001b[0m\u001b[38;5;249mT\u001b[0m\u001b[38;5;249m>\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249ms\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;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;249mT\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;240m  │\u001b[0m             \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m help: consider restricting type parameter `T` with trait `PartialOrd`: `: std::cmp::PartialOrd`",
      " \u001b[38;5;240m  │\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;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54mt\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54mm\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;68m>\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100ml\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;100mr\u001b[0m\u001b[38;5;100mg\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100mt\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;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;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\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 &T",
      " \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;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 error: binary operation `>` cannot be applied to type `&T`",
      " \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\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m &T",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn largest<T>(list: &[T]) -> &T {\n",
    "    let mut largest = &list[0];\n",
    "\n",
    "    for item in list {\n",
    "        if item > largest {\n",
    "            largest = item;\n",
    "        }\n",
    "    }\n",
    "\n",
    "    largest\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59cc7429-d6dd-44de-bfcc-0525a0d4afc6",
   "metadata": {},
   "source": [
    "- Generic structs and generic methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "2b499573-0a6f-4e21-8120-f67eb940c8cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Point<T> {\n",
    "    x: T,\n",
    "    y: T,\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let integer = Point { x: 5, y: 10 };\n",
    "    let float = Point { x: 1.0, y: 4.0 };\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "6b91931f-51a9-4cf0-accb-44de11f0da72",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Point<T> {\n",
    "    x: T,\n",
    "    y: T,\n",
    "}\n",
    "\n",
    "impl<T> Point<T> {\n",
    "    fn x(&self) -> &T {\n",
    "        &self.x\n",
    "    }\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let p = Point { x: 5, y: 10 };\n",
    "\n",
    "    println!(\"p.x = {}\", p.x());\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "da195a13-4dcd-4091-b545-03b818e166f8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "p.x = 5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "037922fb-ef37-47e7-b854-e34fc656ea46",
   "metadata": {},
   "source": [
    "- As usual, different type variables denote (possibly) different types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "fb329dde-127c-4091-988c-1518197c766a",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Point<T, U> {\n",
    "    x: T,\n",
    "    y: U,\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let both_integer = Point { x: 5, y: 10 };\n",
    "    let both_float = Point { x: 1.0, y: 4.0 };\n",
    "    let integer_and_float = Point { x: 5, y: 4.0 };\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5399656a-424e-4ba2-ae22-0b37289f8d84",
   "metadata": {},
   "source": [
    "- An example of a generic function with two type variables\n",
    "- Note that arguments to `mixup()` are `self` and `Point`, not `&self` and `&Point`\n",
    "- The call `p1.mixup(p2)` transfers ownership of `p1` and `p2` to `mixup()`. Accessing `p1` or `p2` after the call generates an error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "0c913f78-cfeb-48ad-a45d-ec46aad93cc7",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Point<X1, Y1> {\n",
    "    x: X1,\n",
    "    y: Y1,\n",
    "}\n",
    "\n",
    "impl<X1, Y1> Point<X1, Y1> {\n",
    "    fn mixup<X2, Y2>(self, other: Point<X2, Y2>) -> Point<X1, Y2> {\n",
    "        Point {\n",
    "            x: self.x,\n",
    "            y: other.y,\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let p1 = Point { x: 5, y: 10.4 };\n",
    "    let p2 = Point { x: \"Hello\", y: 'c' };\n",
    "\n",
    "    let p3 = p1.mixup(p2);\n",
    "\n",
    "    println!(\"p3.x = {}, p3.y = {}\", p3.x, p3.y);\n",
    "    // println!(\"p1.x = {}, p2.y = {}\", p1.x, p2.y); // Generates error, because ownership of p1,p2 transferred to mixup()\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "44f73a51-332f-4ef7-b762-0e29b2793cb6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "p3.x = 5, p3.y = c\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f041b77e-270b-44e8-8e6a-52fb11ec1a24",
   "metadata": {},
   "source": [
    "- Naively trying to make `mixup()` take references fails. Need `Copy` trait"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dbcaadfd-b808-45cc-b6b3-af5fd7c27e67",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot move out of `self.x` which is behind a shared reference",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0507] Error:\u001b[0m cannot move out of `self.x` which is behind a shared reference",
      "   \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;246m9 │\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;249mx\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54mf\u001b[0m\u001b[38;5;54m.\u001b[0m\u001b[38;5;54mx\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;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 move occurs because `self.x` has type `X1`, which does not implement the `Copy` trait",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "cannot move out of `other.y` which is behind a shared reference",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0507] Error:\u001b[0m cannot move out of `other.y` which is behind a shared reference",
      "    \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;249my\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mt\u001b[0m\u001b[38;5;54mh\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54m.\u001b[0m\u001b[38;5;54my\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;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 move occurs because `other.y` has type `Y2`, which does not implement the `Copy` trait",
      "\u001b[38;5;246m────╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "struct Point<X1, Y1> {\n",
    "    x: X1,\n",
    "    y: Y1,\n",
    "}\n",
    "\n",
    "impl<X1, Y1> Point<X1, Y1> {\n",
    "    fn mixup<X2, Y2>(&self, other: &Point<X2, Y2>) -> Point<X1, Y2> {\n",
    "        Point {\n",
    "            x: self.x,\n",
    "            y: other.y,\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let p1 = Point { x: 5, y: 10.4 };\n",
    "    let p2 = Point { x: \"Hello\", y: 'c' };\n",
    "\n",
    "    let p3 = p1.mixup(&p2);\n",
    "\n",
    "    println!(\"p3.x = {}, p3.y = {}\", p3.x, p3.y);\n",
    "    println!(\"p1.x = {}, p2.y = {}\", p1.x, p2.y);\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c06d5e3e-f7a8-4ff8-b61c-028d085e4aef",
   "metadata": {},
   "source": [
    "### Traits\n",
    "- Specify common properties across types\n",
    "    - Via required functions, as headers\n",
    "- Like Haskell type classes, Java interfaces"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "cf7406c6-ce1a-409c-b2eb-8794b3c5d78e",
   "metadata": {},
   "outputs": [],
   "source": [
    "trait Summary {\n",
    "    fn summarize(&self) -> String; // No body\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbe97ecb-3309-4595-bf32-5f1648b0897f",
   "metadata": {},
   "source": [
    "- Specify that a type implements a trait and provide an implementation of the required function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "809be870-4fe8-446d-b731-48d6e0c8bbcb",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct NewsArticle {\n",
    "    pub headline: String,\n",
    "    pub location: String,\n",
    "    pub author: String,\n",
    "    pub content: String,\n",
    "}\n",
    "\n",
    "impl Summary for NewsArticle {\n",
    "    fn summarize(&self) -> String {\n",
    "        format!(\"{}, by {} ({})\", self.headline, self.author, self.location)\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "a2f42162-fe77-45a3-a7ea-12744b200d6e",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Tweet {\n",
    "    pub username: String,\n",
    "    pub content: String,\n",
    "    pub reply: bool,\n",
    "    pub retweet: bool,\n",
    "}\n",
    "\n",
    "impl Summary for Tweet {\n",
    "    fn summarize(&self) -> String {\n",
    "        format!(\"{}: {}\", self.username, self.content)\n",
    "    }\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "03b658c6-984e-4ce6-a14f-326864338f36",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let tweet = Tweet {\n",
    "        username: String::from(\"horse_ebooks\"),\n",
    "        content: String::from(\n",
    "            \"of course, as you probably already know, people\",\n",
    "        ),\n",
    "        reply: false,\n",
    "        retweet: false,\n",
    "    };\n",
    "\n",
    "    println!(\"1 new tweet: {}\", tweet.summarize());\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "290c6494-01a9-41c9-8f83-99b2484005b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 new tweet: horse_ebooks: of course, as you probably already know, people\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b8428c5-f421-415c-a47e-2c622d2b9594",
   "metadata": {},
   "source": [
    "- Can provide a default implementation in a `trait` definition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "4f0c5421-cd2f-4888-a3e7-067b4f889599",
   "metadata": {},
   "outputs": [],
   "source": [
    "trait Summary {\n",
    "    fn summarize(&self) -> String {\n",
    "        String::from(\"(Read more...)\")\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5065444a-d3ac-4e96-b097-5ba4546bcea5",
   "metadata": {},
   "source": [
    "- To use default implementation, implement a trait without providing a function definition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "16f4fb13-10d3-4260-9d5c-7c7a59c31183",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct NewsArticle {\n",
    "    pub headline: String,\n",
    "    pub location: String,\n",
    "    pub author: String,\n",
    "    pub content: String,\n",
    "}\n",
    "\n",
    "impl Summary for NewsArticle {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "f067969e-c978-4a36-ad6f-a4addae8fe7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main(){\n",
    "    let article = NewsArticle {\n",
    "            headline: String::from(\"Penguins win the Stanley Cup Championship!\"),\n",
    "            location: String::from(\"Pittsburgh, PA, USA\"),\n",
    "            author: String::from(\"Iceburgh\"),\n",
    "            content: String::from(\n",
    "                \"The Pittsburgh Penguins once again are the best \\\n",
    "                 hockey team in the NHL.\",\n",
    "            ),\n",
    "        };\n",
    "\n",
    "    println!(\"New article available! {}\", article.summarize());\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "99296124-730d-47fe-8b2e-85a28a5baccf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "New article available! (Read more...)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76938502-7153-4439-9da7-e65f0604029a",
   "metadata": {},
   "source": [
    "- Can qualify a type parameter with a trait to limit its scope"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "5210be5e-ba0f-494f-b73e-98f64ab8a3d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn notify<T: Summary>(item: &T) {\n",
    "    println!(\"Breaking news! {}\", item.summarize());\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a187fdf6-e7bc-472c-bc5f-aff983f1d2f2",
   "metadata": {},
   "source": [
    "- Combine multiple trait constraints using `+` (note that `+` stands for *and*)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d1681c0f-0690-4c6f-9b9c-1241db5e7405",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot find trait `Display` in this scope",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0405] Error:\u001b[0m cannot find trait `Display` in this scope",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_53:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m1 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249my\u001b[0m\u001b[38;5;249m<\u001b[0m\u001b[38;5;249mT\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mS\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mr\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;54mD\u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54mp\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54ma\u001b[0m\u001b[38;5;54my\u001b[0m\u001b[38;5;249m>\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\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;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;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;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 not found in this scope",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;115mNote\u001b[0m: help: consider importing this trait: `use std::fmt::Display;",
      "",
      "`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn notify<T: Summary + Display>(item: &T) {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b3c1294c-a22c-47f3-a32c-66d2855ffb39",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot find trait `Display` in this scope",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0405] Error:\u001b[0m cannot find trait `Display` in this scope",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_54:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m1 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m<\u001b[0m\u001b[38;5;249mT\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mD\u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54mp\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54ma\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;249mC\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mU\u001b[0m\u001b[38;5;249m:\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;249mn\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;249mD\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mb\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249m>\u001b[0m\u001b[38;5;249m(\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;249mT\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mu\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;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;249mi\u001b[0m\u001b[38;5;249m3\u001b[0m\u001b[38;5;249m2\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;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 not found in this scope",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;115mNote\u001b[0m: help: consider importing this trait: `use std::fmt::Display;",
      "",
      "`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "expected trait, found derive macro `Debug`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0404] Error:\u001b[0m expected trait, found derive macro `Debug`",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_54:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m1 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m<\u001b[0m\u001b[38;5;249mT\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mD\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249ma\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;249mC\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mU\u001b[0m\u001b[38;5;249m:\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;249mn\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;54mD\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54mb\u001b[0m\u001b[38;5;54mu\u001b[0m\u001b[38;5;54mg\u001b[0m\u001b[38;5;249m>\u001b[0m\u001b[38;5;249m(\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;249mT\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mu\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;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;249mi\u001b[0m\u001b[38;5;249m3\u001b[0m\u001b[38;5;249m2\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 not a trait",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;115mNote\u001b[0m: help: consider importing this trait instead: `use std::fmt::Debug;",
      "",
      "`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn some_function<T: Display + Clone, U: Clone + Debug>(t: &T, u: &U) -> i32 {}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ac375ac-ccee-4043-87f2-e4e7e159a783",
   "metadata": {},
   "source": [
    "- Syntactic sugar for type constraints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a10b28e5-df95-42b2-8981-4ae0015c9aaf",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot find trait `Display` in this scope",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0405] Error:\u001b[0m cannot find trait `Display` in this scope",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_55:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \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;249mT\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mD\u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54mp\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54ma\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;249mC\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249me\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;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 not found in this scope",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;115mNote\u001b[0m: help: consider importing this trait: `use std::fmt::Display;",
      "",
      "`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "expected trait, found derive macro `Debug`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0404] Error:\u001b[0m expected trait, found derive macro `Debug`",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_55:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m4 │\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;249mU\u001b[0m\u001b[38;5;249m:\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;249mn\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;54mD\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54mb\u001b[0m\u001b[38;5;54mu\u001b[0m\u001b[38;5;54mg\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 not a trait",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m \u001b[38;5;115mNote\u001b[0m: help: consider importing this trait instead: `use std::fmt::Debug;",
      "",
      "`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn some_function<T, U>(t: &T, u: &U) -> i32\n",
    "where\n",
    "    T: Display + Clone,\n",
    "    U: Clone + Debug,\n",
    "{}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e24669d8-9d5a-4d56-9794-c98a8f817449",
   "metadata": {},
   "source": [
    "- Can use a trait directly as a type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "953fd9df-c2f6-4089-8a49-6b86974f1e79",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn returns_summarizable() -> impl Summary {\n",
    "    Tweet {\n",
    "        username: String::from(\"horse_ebooks\"),\n",
    "        content: String::from(\n",
    "            \"of course, as you probably already know, people\",\n",
    "        ),\n",
    "        reply: false,\n",
    "        retweet: false,\n",
    "    }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "890c0e9a-afa6-4504-964e-9992be92ac81",
   "metadata": {},
   "source": [
    "- Now we can fix our original example of a generic function for the largest element in an array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "ee171f00-6c85-4ca8-9116-b831fce44233",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn largest<T:PartialOrd>(list: &[T]) -> &T {\n",
    "    let mut largest = &list[0];\n",
    "\n",
    "    for item in list {\n",
    "        if item > largest {\n",
    "            largest = item;\n",
    "        }\n",
    "    }\n",
    "\n",
    "    largest\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "ca2155a4-b7a3-4539-8612-95a8a560a857",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let number_array = [34, 50, 25, 100, 65];\n",
    "    let number_list = &number_array[..];\n",
    "\n",
    "    let result = largest(&number_list);\n",
    "    println!(\"The largest number is {}\", result);\n",
    "\n",
    "    let char_array = ['y', 'm', 'a', 'q'];\n",
    "    let char_list = &char_array[..];\n",
    "\n",
    "    let result = largest(&char_list);\n",
    "    println!(\"The largest char is {}\", result);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "ac0a6f9b-822f-494c-bd9d-9a1cbfed4e40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The largest number is 100\n",
      "The largest char is y\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79166373-254d-4dc8-9863-b40d567c34d2",
   "metadata": {},
   "source": [
    "- And here is the correct version of `mixup()` for points with heterogenous components"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "be076b8d-aaed-42bb-abea-c68109300367",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Point<X1:Copy, Y1:Copy> {\n",
    "    x: X1,\n",
    "    y: Y1,\n",
    "}\n",
    "\n",
    "impl<X1:Copy, Y1:Copy> Point<X1, Y1> {\n",
    "    fn mixup<X2:Copy, Y2:Copy>(&self, other: &Point<X2, Y2>) -> Point<X1, Y2> {\n",
    "        Point {\n",
    "            x: self.x,\n",
    "            y: other.y,\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "fn main() {\n",
    "    let p1 = Point { x: 5, y: 10.4 };\n",
    "    let p2 = Point { x: \"Hello\", y: 'c' };\n",
    "\n",
    "    let p3 = p1.mixup(&p2);\n",
    "\n",
    "    println!(\"p3.x = {}, p3.y = {}\", p3.x, p3.y);\n",
    "    println!(\"p1.x = {}, p2.y = {}\", p1.x, p2.y);\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "7fa672dc-7aa1-404d-93d8-12a3eee05b42",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "p3.x = 5, p3.y = c\n",
      "p1.x = 5, p2.y = c\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ab950ca-bc52-4d8e-9665-2858c173d69e",
   "metadata": {},
   "source": [
    "### Lifetimes\n",
    "- Recall example last time where Rust caught a dangling reference\n",
    "- In general, a reference cannot outlive the lifetime of the item it refers to"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d023402f-45ad-4389-aedf-cb2d810b25b1",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "`x` does not live long enough",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0597] Error:\u001b[0m `x` does not live long enough",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_62: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;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;68mx\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m5\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 binding `x` declared here",
      " \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;249m \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;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54m&\u001b[0m\u001b[38;5;54mx\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;240m  │\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;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;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 `x` dropped here while still borrowed",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;246m9 │\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;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;37mr\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;240m  │\u001b[0m                       \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m borrow later used here",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn main() {\n",
    "    let r;\n",
    "\n",
    "    {\n",
    "        let x = 5;\n",
    "        r = &x;\n",
    "    }\n",
    "\n",
    "    println!(\"r: {}\", r);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3f48971c-de1c-4d1b-846d-8991758949c1",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "`x` does not live long enough",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0597] Error:\u001b[0m `x` does not live long enough",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_63: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;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;68mx\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m5\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;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;249mb\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;240m  │\u001b[0m             \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m binding `x` declared here",
      " \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;249m \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;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54m&\u001b[0m\u001b[38;5;54mx\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;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;240m  │\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 borrowed value does not live long enough",
      " \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;100m}\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;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;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;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 `x` dropped here while still borrowed",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;246m9 │\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;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;37mr\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;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;240m  │\u001b[0m                       \u001b[38;5;37m╰\u001b[0m\u001b[38;5;37m─\u001b[0m\u001b[38;5;37m─\u001b[0m borrow later used here",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn main() {\n",
    "    let r;                // ---------+-- 'a\n",
    "                          //          |\n",
    "    {                     //          |\n",
    "        let x = 5;        // -+-- 'b  |\n",
    "        r = &x;           //  |       |\n",
    "    }                     // -+       |\n",
    "                          //          |\n",
    "    println!(\"r: {}\", r); //          |\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7910858f-5139-4dc4-a3c0-f1f0606a3ca5",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot assign twice to immutable variable `r`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0384] Error:\u001b[0m cannot assign twice to immutable variable `r`",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_64: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;249mr\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;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;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;249ma\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 help: consider making this binding mutable: `mut `",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \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;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \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;54m&\u001b[0m\u001b[38;5;54mx\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;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 first assignment to `r`",
      " \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;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100mr\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;100my\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;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;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 cannot assign twice to immutable variable",
      " \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": "variable `r` is assigned to, but never used",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_variables] Error:\u001b[0m variable `r` is assigned to, but never used",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_64: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;54mr\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;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;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;249ma\u001b[0m",
      " \u001b[38;5;240m  │\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 warning: variable `r` is assigned to, but never used",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "value assigned to `r` is never read",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_assignments] Error:\u001b[0m value assigned to `r` is never read",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_64:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \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;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \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;54m&\u001b[0m\u001b[38;5;54mx\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;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 warning: value assigned to `r` is never read",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "value assigned to `r` is never read",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_assignments] Error:\u001b[0m value assigned to `r` is never read",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_64:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\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;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \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;54m&\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;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;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;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 warning: value assigned to `r` is never read",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn main() {\n",
    "    let r;                // ---------+-- 'a\n",
    "                          //          |\n",
    "    {                     //          |\n",
    "        let x = 5;        // -+-- 'b  |\n",
    "        r = &x; \n",
    "        let y = 7;\n",
    "        r = &y; //  |       |\n",
    "    }                     // -+       |\n",
    "                          //          |\n",
    "    //println!(\"r: {}\", r); //          |\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b11090e1-0ff2-43e1-b98b-4edf1a36b1de",
   "metadata": {},
   "source": [
    "- In the following example, what does the return value refer to?\n",
    "- From the code, it either tracks `x` or `y`, but which one?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "59264000-4d5f-42a3-96e0-5f005d6d969a",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "missing lifetime specifier",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0106] Error:\u001b[0m missing lifetime specifier",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_65:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m1 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249mx\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;249m,\u001b[0m\u001b[38;5;249m \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;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\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;54m&\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\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;240m  │\u001b[0m                                 \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m expected named lifetime parameter",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn longest(x: &str, y: &str) -> &str {\n",
    "    if x.len() > y.len() {\n",
    "        x\n",
    "    } else {\n",
    "        y\n",
    "    }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c3627bf-106b-4288-8413-8a797c2a9d2e",
   "metadata": {},
   "source": [
    "- Can use variables to tag lifetimes\n",
    "- Like type variables, but preceded by a `'`\n",
    "- Convention is to use lowercase for lifetime variables, uppercase for type variables\n",
    "- This does not change the lifetime, merely tells Rust what to check\n",
    "    - In the example below, the return value must share a lifetime with both `x` and `y`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "28942242-605b-47ba-914e-28df44432d63",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n",
    "    if x.len() > y.len() {\n",
    "        x\n",
    "    } else {\n",
    "        y\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe74d275-9bfa-4d14-91e9-78c2b96f3c7d",
   "metadata": {},
   "source": [
    "- Now the following code works\n",
    "    - `string1.as_str()` is same as `&string1[..]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "825c1a28-4a71-42d7-8d5c-be546159bdc4",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let string1 = String::from(\"long string is long\");\n",
    "    let string2 = String::from(\"xyz\");\n",
    "    let result = longest(string1.as_str(), string2.as_str());\n",
    "    println!(\"The longest string is {}\", result);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "15b6ae3a-26c9-493c-be41-267286bd0311",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The longest string is long string is long\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9a56179-4e0a-4fe4-8545-a78d73fc338e",
   "metadata": {},
   "source": [
    "- This also works, though the lifetime of `string2` is less than `string1`\n",
    "- When the function runs, both arguments are valid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "24190a0a-e796-41c6-bbe5-f7df13a1188e",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let string1 = String::from(\"long string is long\");\n",
    "\n",
    "    {\n",
    "        let string2 = String::from(\"xyz\");\n",
    "        let result = longest(string1.as_str(), string2.as_str());\n",
    "        println!(\"The longest string is {}\", result);\n",
    "    }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "94336b84-ed71-44e4-8023-c7c7f93769ee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The longest string is long string is long\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1108d40d-fb7f-4b32-8a24-22358b663905",
   "metadata": {},
   "source": [
    "- However, if we refer to `result` outside the lifetime of `string2`, the compiler complains"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "4cca113a-eedd-4630-b01e-7ac2fa2b1b07",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main() {\n",
    "    let string1 = String::from(\"long string is long\");\n",
    "    let result;\n",
    "\n",
    "    {\n",
    "        let string2 = String::from(\"xyz\");\n",
    "        result = longest(string1.as_str(), string2.as_str());    \n",
    "    }\n",
    "    \n",
    "    //println!(\"The longest string is {}\", result);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f10f536d-cfaf-42ca-ba82-a6ea5264dd9b",
   "metadata": {},
   "source": [
    "- If we know that only one argument matters, we need not tag the other with a lifetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "285947c2-9e5f-46f3-a40b-b27f50d5eaf6",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn longest<'a>(x: &'a str, y: &str) -> &'a str {\n",
    "    x\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c10492a-0490-4fb1-b742-403dd8491a40",
   "metadata": {},
   "source": [
    "- However, no lifetime tagging does not work here either"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c48ad4c3-2393-4b3c-b97e-827cb3a9b9d5",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "missing lifetime specifier",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0106] Error:\u001b[0m missing lifetime specifier",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_73:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m1 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249mx\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;249m,\u001b[0m\u001b[38;5;249m \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;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\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;54m&\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\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;240m  │\u001b[0m                                 \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m expected named lifetime parameter",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn longest(x: &str, y: &str) -> &str {\n",
    "    x\n",
    "}"
   ]
  }
 ],
 "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
}
