{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "generics-intro",
      "metadata": {},
      "source": "# Aner: private state and generic classes\n\nUse your installed Aner executable and the compatible VS Code extension (**0.1.16** for this example). Follow the versions recommended together by your release; see `docs/INSTALLATION.md` and `docs/VSCODE.md`. Choose **Run All** in this shared variable notebook. This example reuses one `Node<T>` and `LinkedList<T>` definition for `Int64`, `Float64`, and Employee references. All type arguments are explicit. `Int32` is not implemented.\n\nFields are private by default; ordinary `fn` methods are public. `public` and `private` can explicitly set visibility on fields or methods. The synthesized constructor accepts values for every declared field, including private ones; subsequent external reads/writes must use the public API.\n"
    },
    {
      "cell_type": "code",
      "id": "generics-definitions",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "// Fields are private by default. Methods are public by default.\n",
        "class Node<T> {\n",
        "    let value: T\n",
        "    var next: Node<T>?\n",
        "\n",
        "    fn get() { return value }\n",
        "    fn next_node() { return next }\n",
        "}\n",
        "\n",
        "class LinkedList<T> {\n",
        "    var head: Node<T>?\n",
        "\n",
        "    fn push(value: T) {\n",
        "        head = Node<T>(value: value, next: head)\n",
        "    }\n",
        "\n",
        "    fn first() { return head }\n",
        "\n",
        "    fn len() {\n",
        "        var count = 0\n",
        "        var cursor = head\n",
        "        while cursor != null {\n",
        "            let node = cursor.unwrap()\n",
        "            count = count + 1\n",
        "            cursor = node.next_node()\n",
        "        }\n",
        "        return count\n",
        "    }\n",
        "}\n",
        "\n",
        "class Employee {\n",
        "    let name: String\n",
        "    let age: Int64\n",
        "\n",
        "    private fn internal_name() { return name }\n",
        "    public fn name_text() { return internal_name() }\n",
        "    fn years() { return age }\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "generics-numbers-note",
      "metadata": {},
      "source": "## Supported numeric types\n\nThese two lists have distinct concrete types. Aner checks method arguments against each element type; an Employee or Float64 cannot be pushed into `LinkedList<Int64>`. No dynamic `Any` or automatic numeric narrowing is involved.\n"
    },
    {
      "cell_type": "code",
      "id": "generics-numbers",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "// Constructor type arguments are explicit; Int32 is not implemented.\n",
        "let numbers = LinkedList<Int64>(head: null)\n",
        "numbers.push(10)\n",
        "numbers.push(20)\n",
        "print(\"Number count\")\n",
        "print(numbers.len())\n",
        "print(\"First number\")\n",
        "print(numbers.first().unwrap().get())\n",
        "\n",
        "let measurements = LinkedList<Float64>(head: null)\n",
        "measurements.push(1.5)\n",
        "print(\"First measurement\")\n",
        "print(measurements.first().unwrap().get())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "generics-employee-note",
      "metadata": {},
      "source": "## User defined payloads\n\nThe same list stores references to Employee objects. The employee fields stay private; `name_text()` and `years()` expose selected values. The private helper `internal_name()` is callable only from Employee methods. The records below are fictional examples.\n"
    },
    {
      "cell_type": "code",
      "id": "generics-employees",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "// The same linked-list definition holds user-class references.\n",
        "// These are fictional teaching records; names and ages are constructor inputs.\n",
        "let employees = LinkedList<Employee>(head: null)\n",
        "employees.push(Employee(name: \"Lin\", age: 29))\n",
        "employees.push(Employee(name: \"Ada\", age: 36))\n",
        "let employee = employees.first().unwrap().get()\n",
        "print(\"Employee count\")\n",
        "print(employees.len())\n",
        "print(\"First employee\")\n",
        "print(employee.name_text())\n",
        "print(employee.years())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "generics-nested-note",
      "metadata": {},
      "source": "## Nested type arguments\n\nA node can hold another concrete node. Explicit specialization keeps each field and method statically typed. Generic functions, traits/interfaces, inheritance, and user defined value structs remain future work.\n"
    },
    {
      "cell_type": "code",
      "id": "generics-nested",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": [
        "// A type argument can itself be a concrete generic class.\n",
        "let nested = Node<Node<Int64>>(\n",
        "    value: Node<Int64>(value: 7, next: null),\n",
        "    next: null,\n",
        ")\n",
        "print(\"Nested node value\")\n",
        "print(nested.get().get())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "generics-state",
      "metadata": {},
      "source": "## State and visibility\n\nObjects retain reference identity: storing an Employee in a list does not deep copy it. Privacy is an Aner access rule, not encryption or a security boundary. A method of the owning class may access its private fields and methods; unrelated code and other classes may not. Nullable node links still require explicit `.unwrap()` after checking for `null`.\n\nClass templates and concrete objects persist between cells. Restart the notebook session before redefining the classes or rerunning the definition cell. Static errors preserve earlier state; runtime errors clear the session. Saving stores source and outputs, not a live object heap. See `docs/OOP.md` for ownership, instantiation, and resource limits.\n"
    }
  ],
  "metadata": {
    "kernelspec": {
      "name": "aner",
      "display_name": "Aner",
      "language": "aner"
    },
    "language_info": {
      "name": "aner",
      "file_extension": ".aner",
      "mimetype": "text/x-aner"
    },
    "aner": {
      "status": "example",
      "execution_mode": "persistent-session"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
