{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2ffe347c",
   "metadata": {},
   "source": [
    "# Julia Dokumentation\n",
    "\n",
    "[https://docs.julialang.org/](https://docs.julialang.org/) die offizielle Dokumentation\n",
    "\n",
    "Einige Seiten mit Übersichten:\n",
    "\n",
    " - [https://docs.julialang.org/en/v1/base/punctuation/](https://docs.julialang.org/en/v1/base/punctuation/) Verzeichnis der Symbole\n",
    " - [https://docs.julialang.org/en/v1/manual/unicode-input/](https://docs.julialang.org/en/v1/manual/unicode-input/) Verzeichnis spezieller Unicode-Symbole und deren Eingabe in Julia via Tab-Vervollständigung\n",
    " - [https://docs.julialang.org/en/v1/manual/mathematical-operations/#Rounding-functions](https://docs.julialang.org/en/v1/manual/mathematical-operations/#Rounding-functions) Liste mathematischer Funktionen \n",
    "\n",
    "---------\n",
    "\n",
    "\n",
    "\n",
    "# Hilfe und praktische Tipps\n",
    "\n",
    "----\n",
    "\n",
    "\n",
    "## Julia REPL (Read - Eval - Print - Loop)\n",
    "\n",
    "Start von Julia in einem Terminal:\n",
    "```\n",
    "julia>\n",
    "```\n",
    "\n",
    "| Kommando                     | Wirkung                    |\n",
    "| :----------------------------|  :------------------------ |\n",
    "| `exit()` oder `Ctrl-d`       | exit Julia                 |\n",
    "| `Ctrl-c`                     | interrupt                  |\n",
    "| `Ctrl-l`                     | clear screen               |\n",
    "| Kommando mit `;` beenden     | Ausgabe unterdrückt        |\n",
    "| `include(\"filename.jl\")`     | Datei mit Julia-Code einlesen und ausführen |\n",
    "\n",
    "\n",
    "-----\n",
    "\n",
    "Der REPL hat verschiedene Modi: \n",
    "\n",
    "| Modus  | Prompt |  Modus starten  | Modus verlassen  |\n",
    "| :-     | :-      | :-             | :-               |\n",
    "|||||\n",
    "| default| `julia>` |  | |\n",
    "|||||\n",
    "| Package manager | `pkg>` | `]`    | `backspace` |\n",
    "|||||\n",
    "| Help    | `help?>` | `?`| `backspace `|\n",
    "|||||\n",
    "|Shell | `shell>`  | `;` | `backspace`|\n",
    "|||||\n",
    "\n",
    "--------\n",
    "\n",
    "\n",
    "## Jupyter notebooks (IJulia)\n",
    "\n",
    "Die Modi sind als Einzeiler in einer eigenen Input-Zelle nutzbar: \n",
    "\n",
    "(i) ein Kommando des Paket-Managers:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d6c200e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "] status   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9caf3630",
   "metadata": {},
   "source": [
    "(ii) eine Help-Abfrage:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c923aa16",
   "metadata": {},
   "outputs": [],
   "source": [
    "?sin"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfc75d15",
   "metadata": {},
   "source": [
    "(iii) Ein Shell-Kommando:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3617aff8",
   "metadata": {},
   "outputs": [],
   "source": [
    ";ls .."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdce3ab2",
   "metadata": {},
   "source": [
    "## Der Paket-Manager\n",
    "\n",
    "- Über 7000 Pakete, siehe   [https://julialang.org/packages/](https://julialang.org/packages/)\n",
    "- Bevor sie mit `using Module` verwendet werden können, müssen sie heruntergeladen und installiert werden.\n",
    "- Dazu dient der `package manager`\n",
    "- 2 Betriebsarten: \n",
    "  - als normale Julia-Anweisungen, die auch in einer `.jl`-Programmdatei stehen können:\n",
    "    ```\n",
    "    using Pkg\n",
    "    Pkg.add(\"TollesPaket\")\n",
    "    ```\n",
    "  - im speziellen pkg-Modus des Julia-REPLs:\n",
    "    ```\n",
    "    ] add TollesPaket\n",
    "    ```\n",
    "-----    \n",
    "\n",
    "### Einige Funktionen\n",
    "\n",
    "| Funktion                | `pkg` - Mode            | Erklärung                                               |\n",
    "|:------------------------|:----------------------|:----------------------------------------------------------|\n",
    "| `Pkg.add(\"MyPack\")`     | `pkg> add MyPack`     | add `MyPack.jl` to current environment                    |\n",
    "| `Pkg.rm(\"MyPack\")`      | `pkg> remove MyPack`  | remove `MyPack.jl` from current environment               |\n",
    "| `Pkg.update()`          | `pkg> update`         | update packages in current environment                    |\n",
    "| `Pkg.activate(\"mydir\")` | `pkg> activate mydir` | activate directory as current environment                 |\n",
    "| `Pkg.status()`    | `pkg> status`    | list packages                                  |\n",
    "\n",
    "\n",
    "### Installierte Pakete und Environments \n",
    "\n",
    "- Julia und der Paketmanager verwalten \n",
    "   1. eine Liste der mit dem Kommando `Pkg.add()` bzw. `]add`  explizit installierten Pakete mit genauer Versionsbezeichnung in einer Datei `Project.toml` und \n",
    "   2. eine Liste aller dabei auch als implizite Abhängigkeiten installierten Pakete in der Datei `Manifest.toml`. \n",
    "- Das Verzeichnis, in dem diese Dateien stehen, ist das `environment` und wird mit `Pkg.status()` bzw. `]status` angezeigt. \n",
    "- Im Normalfall sieht das so aus: \n",
    "```\n",
    "(@v1.7) pkg> status\n",
    "      Status `~/.julia/environments/v1.7/Project.toml`\n",
    "  [1dea7af3] OrdinaryDiffEq v6.7.1\n",
    "  [91a5bcdd] Plots v1.27.1\n",
    "  [438e738f] PyCall v1.93.1\n",
    "```\n",
    "- Man kann für verschiedene Projekte eigene `environments` benutzen. Dazu kann man entweder Julia mit \n",
    "```\n",
    "julia --project=path/to/myproject\n",
    "```\n",
    "starten oder in Julia das environment mit `Pkg.activate(\"path/to/myproject\")` aktivieren. Dann werden `Project.toml, Manifest.toml` dort angelegt und verwaltet. (Die Installation der Paketdateien erfolgt weiterhin irgendwo unter `$HOME/.julia`) \n",
    "\n",
    "\n",
    "### Zum Installieren von Paketen auf unserem Jupyter-Server `misun103`:\n",
    "- Es gibt ein zentrales Repository, in dem alle von mir erwähnten Pakete bereits installiert sind. \n",
    "- Dort haben Sie keine Schreibrechte.\n",
    "- Sie können aber zusätzliche Pakete in Ihrem `Home` installieren. Dazu ist als erster Befehl nötig, das aktuelle Verzeichnis zu aktivieren: \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "103bd8a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "] activate ."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "077e93f2",
   "metadata": {},
   "source": [
    "(Man beachte den Punkt!)\n",
    "\n",
    "----\n",
    "\n",
    "Danach können Sie mit `add` im Pkg-Modus auch Pakete installieren:\n",
    "\n",
    "```\n",
    "] add TollesPaket\n",
    "```\n",
    "\n",
    "\n",
    "Achtung! Das kann dauern! Viele Pakete haben komplexe Abhängigkeiten und lösen die Installation von weiteren Paketen aus. Viele Pakete werden beim Installieren vorkompiliert. Im REPL sieht man den Installationsfortschritt, im Jupyter-Notebook nicht.\n",
    "\n",
    "\n",
    "## Eingebaute Hilfe und Informationen\n",
    "Mit `?` und der `Tab`-Taste kommt man oft weiter. \n",
    "\n",
    "\n",
    "\n",
    "### weitere Hilfe: `@which`, `fieldnames()`, `methods()`, `names()`, `pwd()`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f099673",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Die Zuordnung zu einem Modul zeigt @which an:\n",
    "\n",
    "@which(sqrt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "44276c0d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Die Komponenten einer struct oder eines anderen zusammengesetzten Typs:\n",
    "\n",
    "fieldnames(Rational)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a200a34f",
   "metadata": {},
   "outputs": [],
   "source": [
    "fieldnames(Complex)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d99bfda9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# alle Methoden einer Funktion\n",
    "\n",
    "methods(sqrt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b3e6f127",
   "metadata": {},
   "outputs": [],
   "source": [
    "# alle Methoden einer Funktion bei bestimmten Argumenttypen. Die Argumenttypen müssen als Tupel angegeben werden\n",
    "\n",
    "methods(sqrt, (Number,))    #  Komma nötig für 1-elementiges Tupel "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e74572ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "# für einen Typ gibt methods() alle Konstruktoren aus\n",
    "\n",
    "methods(Int64)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4de6078",
   "metadata": {},
   "outputs": [],
   "source": [
    "# names(Module) gibt alle von einem Modul exportierte Namen aus. \n",
    "# genau wie auch\n",
    "#\n",
    "#     ?Module \n",
    "#\n",
    "# funktioniert es erst, wenn das Modul mit 'using Module' geladen ist.\n",
    "# Oft ist es besser, wenn die using-Anweisung in einer eigenen Zelle steht.\n",
    "\n",
    "using Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f1df8377",
   "metadata": {},
   "outputs": [],
   "source": [
    "names(Plots)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3654fab2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Julia kürzt den interaktiven Output. \n",
    "# ein explizites print() zeigt alles:\n",
    "\n",
    "print(names(Plots))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc9ca3b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# eine andere Möglichkeit der Ausgabe mit Überlänge in Jupyter\n",
    "\n",
    "show(stdout, MIME(\"text/plain\"), names(Plots))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9fa0f216",
   "metadata": {},
   "outputs": [],
   "source": [
    "# pwd()  \"print working directory\" zeigt, in welchem Verzeichnis Julia gerade operiert. \n",
    "#\n",
    "# Wichtig für die Ein/Ausgabe mit Dateien, z.B. include()\n",
    "\n",
    "pwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "99c19918",
   "metadata": {},
   "outputs": [],
   "source": [
    "include(\"Jupyter.jl\")  # Datei mit Julia-Code einlesen und abarbeiten"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1464d951",
   "metadata": {},
   "source": [
    "## Informationen zu Typen\n",
    "\n",
    "### `subtypes()`, `supertypes()`, `typemax()`, `typemin()`,  `fieldnames()`, `Base.return_types()`, `dump()`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1358c363",
   "metadata": {},
   "outputs": [],
   "source": [
    "subtypes(Real)       # die letzten zwei sind durch das 'using Plots' dazugekommen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e35fb7da",
   "metadata": {},
   "outputs": [],
   "source": [
    "supertypes(Real)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53be4687",
   "metadata": {},
   "outputs": [],
   "source": [
    "typemax(Int64), typemin(Int64), fieldnames(Complex)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a9ed940",
   "metadata": {},
   "outputs": [],
   "source": [
    "Base.return_types(sqrt, (Float64,))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "207af4bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "Base.return_types(sqrt, (Complex{Int64},))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66b42304",
   "metadata": {},
   "outputs": [],
   "source": [
    "# dump() zeigt alle Teile eines zusammengesetzten Objekts\n",
    "\n",
    "x = 3//4 + 75im\n",
    "dump(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c6edfea",
   "metadata": {},
   "source": [
    "## Der Julia JIT _(just in time)_ Compiler\n",
    "\n",
    "Julia baut auf die Werkzeuge des _LLVM Compiler Infrastructure Projects_ auf.\n",
    "\n",
    "\n",
    "Stages of Compilation \n",
    "\n",
    "|  stage & result   |  introspection command  |\n",
    "| :---          |          :--- |\n",
    "|Parse    ==>   Abstract Syntax Tree (AST) | `Meta.parse()` |\n",
    "| Lowering:     transform AST ==> Static Single Assignment (SSA) form | `@code_lowered`|\n",
    "|  Type Inference  |   `@code_warntype`, `@code_typed` |\n",
    "| Generate LLVM intermediate representation | `@code_llvm`|\n",
    "|  Generate native machine code | `@code_native` |\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4d433ab8",
   "metadata": {},
   "outputs": [],
   "source": [
    "function f(x,y)\n",
    "    z = x^2 + log(y)\n",
    "    return 2z\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de444d8a",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = Meta.parse( \"function f(x,y); z=x^2+log(y); return 2x; end  \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1ddf17aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "using TreeView"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "70d267d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "walk_tree(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b19b64ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "@code_lowered f(2,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57eb03f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "@code_warntype f(2,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf273a25",
   "metadata": {},
   "outputs": [],
   "source": [
    "@code_typed f(2,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "28779f6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "@code_llvm f(2,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "02711d1f",
   "metadata": {},
   "outputs": [],
   "source": [
    "@code_native f(2,4)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 1.8.5",
   "language": "julia",
   "name": "julia-1.8"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
