{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e9e769f4-6300-44e1-932c-33ed90197469",
   "metadata": {},
   "source": [
    "# PLC2026 Lecture 07, 29 Jan 2026"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "025c8646-d118-4728-ae2d-fb608bb4e970",
   "metadata": {},
   "source": [
    "### Rust\n",
    "- Rust resources: <https://www.rust-lang.org/>\n",
    "- Installing Rust: <https://www.rust-lang.org/tools/install>\n",
    "- Documentation: <https://www.rust-lang.org/learn>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26e98d67-edec-4562-97fd-e248fdbb20db",
   "metadata": {},
   "source": [
    "### Typing\n",
    "- Static (Java, Haskell) vs dynamic (Python)\n",
    "    - Ideally, type errors should be caught at compile-time (static)\n",
    "    - Dynamic --- type is determined by current value, type of a variable can change over time\n",
    "- Implicit (Haskell, Python) vs explicit (Java declarations)\n",
    "    - Implicit + static $\\Longrightarrow$ type inference\n",
    "- Degrees of strictness\n",
    "    - Is mixed mode arithmetic allowed? e.g., `x = 1.5 + 3`\n",
    "    - Can numbers be intepreted as booleans? `if len(l) { ... }`\n",
    "- Rust types\n",
    "    - Static\n",
    "    - Mostly implicit, but *must* declare types for function signatures\n",
    "    - **Very** strict!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1de6dfb3-dfe2-43c7-9657-f804d1bb1ddb",
   "metadata": {},
   "source": [
    "### Rust program\n",
    "- **Not** object oriented\n",
    "- Program is a collection of functions\n",
    "- Execution begins with `main()`\n",
    "- Read documentation about how to compile\n",
    "- `cargo` to build Rust projects"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd4f613d-981f-491d-b067-1cb793324f94",
   "metadata": {},
   "source": [
    "### Hello world!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b3625b88-45f3-4567-b209-cbc495dcba1d",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn main(){\n",
    "    println!(\"Hello world\");\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0018ae7e-40fd-44f6-9943-9960a3742755",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "daff7b9f-e4a5-4aa5-8f8b-73a398c1dfc6",
   "metadata": {},
   "source": [
    "- `!` after `println` signifies it is a macro, not a function --- will worry about this later\n",
    "- This function returns nothing, so return value is `()`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd0a61cc-d736-405c-9fa1-0b228a1256e1",
   "metadata": {},
   "source": [
    "### Variables\n",
    "- Declare variables using `let` and assign a value\n",
    "- Value implicitly fixes type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7be3fe3f-2bca-4257-bd92-1b207b75619b",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn var1(){\n",
    "    let x = 55;\n",
    "    println!(\"Value of x is {x}\"); // Insert value in string, Version 1\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b0ee0bff-a3c3-4a3b-b995-5345a9329501",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of x is 55\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var1()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "004e4257-e464-491e-ace1-ea8949f6a0a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn var2(){\n",
    "    let x = 55;\n",
    "    println!(\"Value of x is {}\",x); // Insert value in string, Version 2\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d76ba21a-4f8a-4fbe-9a2b-488f63c8f369",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of x is 55\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var2()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0f24b2a-afb5-4571-bf0b-da958f0bdf1a",
   "metadata": {},
   "source": [
    "- What if we try to update the value of `x`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abced5a0-40da-4eae-907c-97844f565fd4",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot assign twice to immutable variable `x`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0384] Error:\u001b[0m cannot assign twice to immutable variable `x`",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_8: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;54mx\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;249m5\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 first assignment to `x`",
      " \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 help: consider making this binding mutable: `mut `",
      " \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;100mx\u001b[0m\u001b[38;5;100m \u001b[0m\u001b[38;5;100m=\u001b[0m\u001b[38;5;100m \u001b[0m\u001b[38;5;100m6\u001b[0m\u001b[38;5;100m6\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": "value assigned to `x` is never read",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_assignments] Error:\u001b[0m value assigned to `x` is never read",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_8: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;249mx\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54m5\u001b[0m\u001b[38;5;54m5\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 warning: value assigned to `x` is never read",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "fn var3(){\n",
    "    let x = 55;\n",
    "    x = 66;\n",
    "    println!(\"Value of x is {}\",x); // Insert value in string, Version 2\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b390d673-bb49-45b0-afb2-2321178eeab5",
   "metadata": {},
   "source": [
    "- Rust variables are **immutable** by default\n",
    "     - Like variables in mathematics\n",
    "     - Let $x = 4$ ... means $x$ is an arbitrary but fixed value\n",
    "- Need to add a qualifier `mut` to say that a variable is mutable\n",
    "     - Notice the useful error message, suggesting that we add the qualifier `mut`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "54fac294-d3c1-4215-8faa-709f037b7826",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn var4(){\n",
    "    let mut x = 55;\n",
    "    x = 66;\n",
    "    println!(\"Value of x is {}\",x); // Insert value in string, Version 2\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "616bf90d-c1c0-43a6-a796-4bb35a976b1e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of x is 66\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var4()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e723511-9521-4bdd-8b76-e86f43957349",
   "metadata": {},
   "source": [
    "### Constants\n",
    "- Immutable variables are not the same as constants\n",
    "- Declare constants explicitly\n",
    "    - So far we have used implicit typing\n",
    "    - Constants need to be typed explicitly -- Rust uses older Algol/Pascal style `var: type` notation for typing rather than C/Java style `type var`\n",
    "    - Will describe Rust types shortly\n",
    "- Constants can have *global* scope, declared outside all functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "0ebf9ab5-5085-4f25-b461-fd9aeca2f313",
   "metadata": {},
   "outputs": [],
   "source": [
    "let x = 55;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "3ff995e2-b950-4942-ad8b-967882326074",
   "metadata": {},
   "outputs": [],
   "source": [
    "const PI_APPROX: f32 = 3.1415927;\n",
    "fn const1(){    \n",
    "    println!(\"Value of pi is approximately {}\",PI_APPROX);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "096d814f-9b9c-4b89-b0da-7e83da651478",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of pi is approximately 3.1415927\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "const1()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9439d554-c0f2-4848-a212-04a3d2e98649",
   "metadata": {},
   "source": [
    "### Shadowing\n",
    "- Redeclaring a variable *shadows* the earlier definition\n",
    "- Can change the type with each fresh declaration (but why?)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "9e13b1e8-98a7-4df9-9f2b-b44069f19452",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "value of x is 5\n"
     ]
    }
   ],
   "source": [
    "let x = 0.0;\n",
    "let x = 5;\n",
    "println!(\"value of x is {}\",x);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "375134e6-de13-4827-8ecc-04187f67828b",
   "metadata": {},
   "source": [
    "- But cannot change the type of a mutable variable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d6e5773-ccde-4d5d-965b-e4add35ae9d3",
   "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_39: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;249mm\u001b[0m\u001b[38;5;249mu\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;100m0\u001b[0m\u001b[38;5;100m.\u001b[0m\u001b[38;5;100m0\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m             \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m  ",
      " \u001b[38;5;240m  │\u001b[0m              \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m expected due to this value",
      " \u001b[38;5;246m2 │\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;54m5\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 floating-point number, found integer",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "value assigned to `x` is never read",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_assignments] Error:\u001b[0m value assigned to `x` is never read"
     ]
    }
   ],
   "source": [
    "let mut x = 0.0;\n",
    "x = 5;\n",
    "println!(\"value of x is {}\",x);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a1bb0f7-dcbf-41f9-8ae4-c62d491ba484",
   "metadata": {},
   "source": [
    "### Scalar types\n",
    "- Signed integers: `i8`, `i32`, `i64`, `isize` -- explicitly specify number of bits, last version uses the underlying architecture default\n",
    "- Unsigned integers: `u8`, `u32`, `u64`, `usize`\n",
    "- Floats: `f32`, `f64`\n",
    "- Boolean: `bool` --- values are `true` and `false`\n",
    "- Charactre: `char` --- write with single quote, `'a'`, uses UTF-8, upto 4 bytes per character"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a5d3fc3-c724-4d3b-b7b7-6f4501ac1d08",
   "metadata": {},
   "source": [
    "- Implicit vs explicit typing\n",
    "    - Normally Rust deduces type from value assigned in `let`\n",
    "    - Can also explicitly annotate type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "af408ba9-0956-4570-a082-58dce48a5246",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of y is 12\n"
     ]
    }
   ],
   "source": [
    "let mut y = 5.0;\n",
    "let z = 7f32;\n",
    "let y = y + z;\n",
    "println!(\"Value of y is {}\",y);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9be89643-3339-4354-a00c-b950bf605269",
   "metadata": {},
   "source": [
    "- Strict typing\n",
    "    - Cannot have mixed int/float expressions --- use `as type` to \"recast\" a type\n",
    "    - Arithmetic expressions cannot replace boolean expressions -- convention that `0` is `false`, non-zero is `true` etc does not work"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "900cdf84-a219-4cfa-b07e-fd707ff2f95c",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "cannot multiply `{float}` by `{integer}`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0277] Error:\u001b[0m cannot multiply `{float}` by `{integer}`",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_41:1:1\u001b[38;5;246m]\u001b[0m",
      "   \u001b[38;5;246m│\u001b[0m",
      " \u001b[38;5;246m2 │\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;249mx\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54m*\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m7\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 no implementation for `{float} * {integer}`",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "value assigned to `x` is never read",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_assignments] Error:\u001b[0m value assigned to `x` is never read"
     ]
    }
   ],
   "source": [
    "let mut x = 5.8;\n",
    "x = x * 7;\n",
    "println!(\"Value of x is {}\",x);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "b809f458-11cf-41a2-bc1a-742e44f6ddea",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of x is 40.600002\n"
     ]
    }
   ],
   "source": [
    "let mut x = 5.8;\n",
    "x = x * 7 as f32;\n",
    "println!(\"Value of x is {}\",x);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "847d31ea-7a95-4a49-b2fd-f3dbbef076a3",
   "metadata": {},
   "source": [
    "### Defining functions\n",
    "- Functions are defined using `fn`\n",
    "- Need to provide explicit types for arguments and return value\n",
    "- Notation for return value uses `->` like Haskell"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "bf07448b-97ad-49cf-a582-9c7d31dfdd8d",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn addtwo(x : i32, y: i32) -> i32 {\n",
    "    return x + y;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "17ddd4f6-2d4e-4237-a2ba-a97803a7a70a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of a is 59\n"
     ]
    }
   ],
   "source": [
    "let a = addtwo(17,42);\n",
    "println!(\"Value of a is {}\",a);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc3d236d-ff7f-443e-8423-3d50a271c39c",
   "metadata": {},
   "source": [
    "### Expressions\n",
    "- Functions implicitly return last *expression* evaluated\n",
    "- Can rewrite our function as below"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "56a53e80-3cec-42fc-b6ed-9ccb7c6ad3f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn addtwoexpr(x : i32, y: i32) -> i32 {\n",
    "    x + y\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "99b23a31-44dd-480c-8e48-2ca37e8a3c27",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value of a is 59\n"
     ]
    }
   ],
   "source": [
    "let a = addtwoexpr(17,42);\n",
    "println!(\"Value of a is {}\",a);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20121836-394d-458d-bf77-d2fedf170f5c",
   "metadata": {},
   "source": [
    "- An expression should not have a semicolon at the end\n",
    "- Semicolon turns the expression into a *statement*\n",
    "    - Note again the helpful compiler error message"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "31bedd86-be9a-40d9-ba35-901f91b1cc8f",
   "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_62: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;100ma\u001b[0m\u001b[38;5;100md\u001b[0m\u001b[38;5;100md\u001b[0m\u001b[38;5;100mt\u001b[0m\u001b[38;5;100mw\u001b[0m\u001b[38;5;100mo\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100mm\u001b[0m\u001b[38;5;100mi\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;100mn\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;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;249my\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;249m>\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mi\u001b[0m\u001b[38;5;54m3\u001b[0m\u001b[38;5;54m2\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m    \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m                     \u001b[38;5;54m─\u001b[0m\u001b[38;5;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\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 implicitly returns `()` as its body has no tail or `return` expression",
      " \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 expected `i32`, found `()`",
      " \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;249mx\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;68m;\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 help: remove this semicolon to return this value: ``",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    },
    {
     "ename": "Error",
     "evalue": "value assigned to `x` is never read",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_assignments] Error:\u001b[0m value assigned to `x` is never read"
     ]
    }
   ],
   "source": [
    "fn addtwosemicolon(x : i32, y: i32) -> i32 {\n",
    "    x + y;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "077e3de7-1495-4e74-bd38-ca7c0ce04bba",
   "metadata": {},
   "source": [
    "### Control flow\n",
    "- `if` boolean-expression `{ ... } else {....}`\n",
    "- loops: `while` boolean-expression `{...}`, `loop {...}`, `for`\n",
    "- `loop` requires a `break`, else infinite\n",
    "- `for` runs over elements from an iterator --- later"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "4f8ea2e8-984c-42ec-9560-9cc6b15a0af6",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn signum1(x: i32) -> i32{\n",
    "    if x < 0 {return -1;}\n",
    "    else if x == 0 {return 0;}\n",
    "    else {return 1;}\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "46979d5b-db05-484f-9fd5-b8d86e238fe2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "signum1(-7)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6aaa7dce-a169-490c-97b1-3faf1778a603",
   "metadata": {},
   "source": [
    "- `if` is itself an expression, so can do a conditional assignment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "0002033c-930b-441f-8316-5b865e8121da",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn signum2(y: i32) -> i32{\n",
    "    let x = if y < 0 {-1} else if y == 0 {0} else {1};\n",
    "    return x;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "abf3dce2-281b-42c3-b77f-a4e9054a1807",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "signum2(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8162a392-f0f6-48d6-b570-685f9a11a435",
   "metadata": {},
   "source": [
    "- This cryptic `if` expression suffices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "eef88e5b-07c7-4558-be12-6c70842b50cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "fn signum3(y: i32) -> i32{\n",
    "    if y < 0 {-1} else if y == 0 {0} else {1}\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "c716c08c-ef36-4923-a9a8-6ee1c17cddd3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "signum3(77)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "032bbecc-d0f1-4176-b3dd-4ba2c5cce098",
   "metadata": {},
   "source": [
    "### Copying values\n",
    "- `x = y` for values stored on the stack copies the value\n",
    "- `x = y` for values stored on the heap creates an *alias* -- both `x` and `y` refer to the same value on the heap\n",
    "    - Useful to avoid copying large values, and to pass heap objects to a function\n",
    "    - However, leads to subtle errors because updating `y` indirectly updates `x`\n",
    "    - Also, releasing memory through `y` results in a *dangling pointer* at `x`\n",
    "- Rust introduces a concept called **ownership** to address these issues"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74ed093b-e17f-40bd-b42b-71cfb3b25898",
   "metadata": {},
   "source": [
    "### Strings\n",
    "- Stored on the heap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "83190f61-a6ac-49bf-bfa8-e310fcde0775",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello, world!\n",
      "Again hello, world!\n"
     ]
    }
   ],
   "source": [
    "let mut s = String::from(\"hello\"); // allocates heap space for new String and initializes\n",
    "s.push_str(\", world!\"); // push_str() appends a literal to a String\n",
    "println!(\"{}\", s); // This will print `hello, world!`\n",
    "println!(\"Again {}\",s);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84b6d417-3f57-42b1-9754-53801e9c7390",
   "metadata": {},
   "source": [
    "### Copying values, stack\n",
    "- Value is copied"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "70980753-b77b-48aa-9e43-6e6d212a43ed",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = 7, y = 77\n"
     ]
    }
   ],
   "source": [
    "let mut x = 7;\n",
    "let mut y = x;\n",
    "y = 77;\n",
    "println!(\"x = {}, y = {}\",x,y);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "217225f8-96c1-47e3-bf80-785319dd516e",
   "metadata": {},
   "source": [
    "### Copying values, heap\n",
    "- Every value on the heap has a unique owner\n",
    "- Assignment *moves* ownership\n",
    "- Memory is freed as soon as scope of owner ends"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e359975c-7683-4ba2-a292-7dd1f2ed53d7",
   "metadata": {},
   "outputs": [
    {
     "ename": "Error",
     "evalue": "value assigned to `x` is never read",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[unused_assignments] Error:\u001b[0m value assigned to `x` is never read"
     ]
    },
    {
     "ename": "Error",
     "evalue": "borrow of moved value: `s1`",
     "output_type": "error",
     "traceback": [
      "\u001b[31m[E0382] Error:\u001b[0m borrow of moved value: `s1`",
      "   \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0mcommand_71: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;68mm\u001b[0m\u001b[38;5;68mu\u001b[0m\u001b[38;5;68mt\u001b[0m\u001b[38;5;68m \u001b[0m\u001b[38;5;68ms\u001b[0m\u001b[38;5;68m1\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mS\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
      " \u001b[38;5;240m  │\u001b[0m     \u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m┬\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m  ",
      " \u001b[38;5;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 move occurs because `s1` has type `String`, which does not implement the `Copy` trait",
      " \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;249mm\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ms\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;54ms\u001b[0m\u001b[38;5;54m1\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;37m│\u001b[0m ",
      " \u001b[38;5;240m  │\u001b[0m               \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m value moved here",
      " \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 cloning the value if the performance cost is acceptable: `.clone()`",
      " \u001b[38;5;240m  │\u001b[0m ",
      " \u001b[38;5;246m4 │\u001b[0m \u001b[38;5;249mp\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m!\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249m1\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\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;249m2\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m\u001b[38;5;249m}\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100m1\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249m2\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;240m  │\u001b[0m                               \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m value borrowed here after move",
      "\u001b[38;5;246m───╯\u001b[0m"
     ]
    }
   ],
   "source": [
    "let mut s1 = String::from(\"hello\");\n",
    "let mut s2 = s1;\n",
    "s2.push_str(\", world\");\n",
    "println!(\"s1 = {}, s2 = {}\", s1, s2); "
   ]
  }
 ],
 "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
}
