{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction au langage julia #\n",
    "## Types, id et références ##\n",
    "`Julia` est un langage typé. La fonction `typeof` permet d'obtenir le type d'un objet ou d'une variable. Un seconde fonction importante pour comprendre comment sont stockés les objets est `objectid`. Cette\n",
    "fonction donne l'identifiant de l'objet (en gros sa place en mémoire)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 3\n",
    "println(typeof(a))\n",
    "println(objectid(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Int, float, complexes, rationnels et booléens ##\n",
    "### Les entiers et réels flottants\n",
    "- Les types entiers signés : Int8, Int16, Int32, Int64, Int128;\n",
    "- Les types entiers non signés : UInt8, UInt16, UInt32, UInt64, UInt128;\n",
    "- Les réels flottants : Float16, Float32, Float64.\n",
    "Par défaut, le type d'une variable est définie par son affectation, mais on peut préciser son type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 12\n",
    "println(\"x =\",x)\n",
    "println(\"type de x : \",typeof(x))\n",
    "y = UInt64(12)\n",
    "println(\"y = \",y)\n",
    "println(\"type de y : \",typeof(y))\n",
    "z = 1.0\n",
    "println(\"type de z : \",typeof(z))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Les complexes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 1+2im\n",
    "println(\"a = \",a)\n",
    "println(\"type de a : \",typeof(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Les rationnels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "q = 2//3\n",
    "println(\"q = \",q)\n",
    "println(\"type de q\",typeof(q))\n",
    "q = q + 1//5\n",
    "println(\"q = \",q)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Booléens"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = true\n",
    "println(\"a = \",a)\n",
    "println(\"type de a : \",typeof(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Itérateur\n",
    "1:5 est un **itérateur**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 1:2:7\n",
    "println(\"a = \",a)\n",
    "println(\"type de a : \", typeof(a))\n",
    "b = collect(a)                         # renvoie le vecteur des valeurs\n",
    "println(\"b = \",b)\n",
    "println(\"type de b : \", typeof(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## type array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1 2 3]\n",
    "b = [1,2,3]\n",
    "c = [1.0 2 3 ; 1 2 3]\n",
    "println(\"a = $a, b = $b, c = $c\")\n",
    "b_type = typeof(b)\n",
    "a_type = typeof(a)\n",
    "c_type = typeof(c)\n",
    "println(\"type de a = $a_type, type de b = $b_type, type de c = $c_type\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- a est une matrice d'entier à 1 ligne, 3 colonnes\n",
    "- b est un vecteur d'entier\n",
    "- c est une matrice de flottants 2 lignes, 3 colonnes\n",
    "Que se passe-t-il si on calcul : `a*b, b*a, c*b, c*a`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b*a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c*a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c*b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "b est donc un vecteur colonne"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Opérations terme à terme\n",
    "On a bien sur les opétations classique : + * et /, l'étoile \n",
    "\\* est la multiplication matricielle pais on a aussi les opérations terme à terme"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = 2*ones(2,3)\n",
    "c .* d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Attention au .** Étant donné que le point . permet à la fois de définir un float et d'effectuer\n",
    "les opérations élément par élément, il faut mettre des espaces entre les points afin de pouvoir distinguer\n",
    "la signification de chaque point."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "5. .+ [1,2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "5.+[1,2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "E = 1:4\n",
    "println(\"E = \",E)\n",
    "println(\"type de E : \",typeof(E))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut extraire des sous matrice facilement, mais attention "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "E = [1 2 3 4 ; 5 6 7 8 ; 9 10 11 12]\n",
    "E[[1,3],1:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "E[[1,3],[1:2]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Les tuples\n",
    "Ce sont des sortes de tableaux à 1 dimension dont les objets peuvent avoir des types différents. Ce sont des objet non modifiables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = 12, 13, \"quatorze\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t[3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "typeof(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t[2]=1         # erreur car non modifiable"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Autres types de base\n",
    "* les chaînes de caractères;\n",
    "* les dictionnaires;\n",
    "* les ensembles.\n",
    "\n",
    "On peut aussi créer des types : structures, ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fonctions\n",
    "**Les paramètres de type scalaire ou tuple sont en entrée**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function fct2(a,b)\n",
    "    a_id = objectid(a)\n",
    "    b_id = objectid(b)\n",
    "    println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "    b = a\n",
    "    a_id = objectid(a)\n",
    "    b_id = objectid(b)\n",
    "    println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "    return b\n",
    "end\n",
    "a = 0\n",
    "b = 1\n",
    "a_id = objectid(a)\n",
    "b_id = objectid(b)\n",
    "println(\"Avant fct2\")\n",
    "println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "println(\"a, b = $a, $b\")\n",
    "println(\"Dans fct2\")\n",
    "c = fct2(a,b)\n",
    "println(\"Après fct2\")\n",
    "a_id = objectid(a)\n",
    "b_id = objectid(b)\n",
    "println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "println(\"a, b, c = $a,$b,$c\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Type Array\n",
    "\n",
    "**Les paramètres sont passés par référence**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function fct3(a,b)\n",
    "    a_id = objectid(a)\n",
    "    b_id = objectid(b)\n",
    "    println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "    b[1] = a[1]\n",
    "    b[2] = a[2]\n",
    "    a_id = objectid(a)\n",
    "    b_id = objectid(b)\n",
    "    println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "    println(\"a, b =  $a, $b\")\n",
    "    return b                 \n",
    "end\n",
    "a = [0,0]\n",
    "b = [1,1]\n",
    "a_id = objectid(a)\n",
    "b_id = objectid(b)\n",
    "println(\"Avant fct3\")\n",
    "println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "println(\"a, b =  $a, $b\")\n",
    "println(\"Dans fct3\")\n",
    "c = fct3(a,b)\n",
    "println(\"Après fct3\")\n",
    "a_id = objectid(a)\n",
    "b_id = objectid(b)\n",
    "c_id = objectid(c)\n",
    "println(\"objectid(a) = $a_id, objectid(b) = $b_id, objectid(c) = $c_id\")\n",
    "println(\"a, b, c =  $a, $b, $c\")\n",
    "c[1]=10\n",
    "println(\"b = $b, c = $c\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**`b`et `c`sont les mêmes objects!**\n",
    "\n",
    "**`a` et `b` sont les mêmes objets**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function fct3_1(a,b)\n",
    "    a_id = objectid(a)\n",
    "    b_id = objectid(b)\n",
    "    println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "    b[1] = a[1]\n",
    "    b[2] = a[2]\n",
    "    a_id = objectid(a)\n",
    "    b_id = objectid(b)\n",
    "    println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "    println(\"a, b =  $a, $b\")\n",
    "    return b[:]              # on renvoie un nouvel objet                 \n",
    "end\n",
    "a = [0,0]\n",
    "b = [1,1]\n",
    "a_id = objectid(a)\n",
    "b_id = objectid(b)\n",
    "println(\"Avant fct3_1\")\n",
    "println(\"objectid(a) = $a_id, objectid(b) = $b_id\")\n",
    "println(\"a, b =  $a, $b\")\n",
    "println(\"Dans fct3_1\")\n",
    "c = fct3_1(a,b)\n",
    "println(\"Après fct3_1\")\n",
    "a_id = objectid(a)\n",
    "b_id = objectid(b)\n",
    "c_id = objectid(c)\n",
    "println(\"objectid(a) = $a_id, objectid(b) = $b_id, objectid(c) = $c_id\")\n",
    "println(\"a, b, c =  $a, $b, $c\")\n",
    "c[1]=10\n",
    "println(\"b = $b, c = $c\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**`b`et `c`sont différents**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- le contenu du vecteur b a été modifié;\n",
    "- le pointeur sur le vecteur b est le même."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**`fct`et `fct!` donnent les mêmes résultats**. Par convention on aura un ! à la fin du nom de la fonction si au moins un des paramètres en entrée est modifié (en général le premier)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Arguments\n",
    "- arguments optionnels;\n",
    "- vectorisation : `sin.([0,\\pi/2,\\pi])`;\n",
    "- `Maps`et `Filters`(programmation fonctionnelle);\n",
    "- récursivité."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    " function showtypetree(T, level=0)\n",
    "     println(\"\\t\" ^ level, T)\n",
    "     for t in subtypes(T)\n",
    "         if t != Any\n",
    "             showtypetree(t, level+1)\n",
    "         end\n",
    "    end\n",
    " end\n",
    " \n",
    " showtypetree(Number)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# vecteur\n",
    "A = Array{Real}(undef,3)\n",
    "B = Vector{Real}(undef,4)\n",
    "A_type = typeof(A)\n",
    "B_type = typeof(B)\n",
    "println(\"type de A = $A_type, type de B = $B_type\")\n",
    "\n",
    "println(A)\n",
    "A_type == B_type       # renvoie true\n",
    "#\n",
    "# Matrices\n",
    "A = Array{Real}(undef,2,4)\n",
    "B = Matrix{Real}(undef,3,4)\n",
    "A_type = typeof(A)\n",
    "B_type = typeof(B)\n",
    "println(\"type de A = $A_type, type de B = $B_type\")\n",
    "A_type == B_type       # renvoie true "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Int<:Real"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Int<:AbstractFloat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Types dans les fonctions\n",
    "### Paramètres en entrée\n",
    "\n",
    "Si les paramètres ne sont pas du bon type alors le programme plante"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function fct5(a::Int, b::Int)\n",
    "    return a+b\n",
    "end\n",
    "f1 = fct5(2.,2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Paramètre en sortie"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function fct6!(a::Real ,x::Vector)\n",
    "#function fct(a::Real ,x::Vector, y::Vector)\n",
    "  a = \"a\"          # a is a new variable\n",
    "  x = [2,2]      # x is new variable\n",
    "  return a, x\n",
    "end\n",
    "\n",
    "function fct7!(a::Real ,x::Vector)::Tuple{Int,Vector}\n",
    "  a = \"a\"          # a is a new variable\n",
    "  x = [2,2]      # x is new variable\n",
    "  return a, x\n",
    "end\n",
    "\n",
    "println(\"Main Program, test of fct6!\")\n",
    "println(\"--------------------------\")\n",
    "a = 1\n",
    "x = [0, 0]\n",
    "f_a, f_x = fct6!(a, x)\n",
    "println(\"a, x =  $a, $x\")\n",
    "println(\"f_a, f_x = $f_a, $f_x\")\n",
    "\n",
    "println(\"Main Program, test of fct7!\")\n",
    "println(\"--------------------------\")\n",
    "a = 1\n",
    "x = [0, 0]\n",
    "f_a, f_x = fct7!(a, x)\n",
    "println(\"a, x, =  $a, $x\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dispatch multiple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function fct5(a::Real, b::Int)\n",
    "    return a-b\n",
    "end\n",
    "f1 = fct5(2,2)\n",
    "f2 = fct5(2.0,2)\n",
    "println(\"f1 = $f1, f2 = $f2\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "methods(fct5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Portée des variables\n",
    "De nombreux langages de programmation font la différence entre les variables globales (communes à tout le programme) et les variables locales, qui correspondent aux variables introduites dans le code d'une fonction\n",
    "Ici, la situation est un peu plus complexe, car la philosophie générale est d'aller vers une localisation plus forte des variables de manière à éviter des conflits de noms pouvant induire des comportements non voulus.\n",
    "Ce renforcement du cloisonnement se fait de deux manières :\n",
    "* Une variable déclarée dans le programme principal (ou en ligne de commande REPL) n'est pas immédiatement accessible dans les blocs for. . . end, while. . . end,try. . . end du programme principal, non plus que dans les fonctions appelées par le programme. Leur appel doit être précédé du mot global.\n",
    "* Une variable déclarée dans une fonction est visible dans toute fonction interne à cette fonction, ainsi que dans les blocs for. . . end, while. . . end,try. . . end de cette fonction.\n",
    "* Si dans un bloc de code la déclaration d'une variable est précédée du mot clef local, c'est une nouvelle variable locale qui est créée. Elle sera détruite à la fin du bloc; si une variable précédente existait, c'est à nouveau elle qui a la main."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function niveau_un() \n",
    "    function niveau_deux()\n",
    "        x=3;\n",
    "        println(\"x=\",x) \n",
    "    end\n",
    "    function niveau_deux_deux()\n",
    "        local x=5; \n",
    "        println(\"x=\",x)\n",
    "    end\n",
    "    x=1; \n",
    "    println(\"x=\",x) \n",
    "    for i=1:1\n",
    "        x=4;\n",
    "    end\n",
    "    println(\"x=\",x)\n",
    "    niveau_deux();\n",
    "    println(\"x=\",x)\n",
    "    niveau_deux_deux();\n",
    "    println(\"x=\",x)\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "niveau_un()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function niveau_deux()\n",
    "        x=3;\n",
    "        println(\"x = \",x) \n",
    "    end\n",
    "function niveau_deux_deux()\n",
    "    local x=5; \n",
    "    println(\"x = \",x)\n",
    "end\n",
    "x = 1;\n",
    "println(\"x = \",x)\n",
    "for i = 1:1\n",
    "    x = 4;\n",
    "end\n",
    "println(\"après le for x = \",x)\n",
    "niveau_deux();\n",
    "println(\"x = \",x)\n",
    "niveau_deux_deux()\n",
    "println(\"x = \",x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**mais sous julia REPL on obtient pour `x`après le for 1 !**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Performance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = rand(1000);\n",
    "\n",
    "function sum_global()\n",
    "    s = 0.0\n",
    "    for i in x\n",
    "        s += i\n",
    "    end\n",
    "    return s\n",
    "end;\n",
    "\n",
    "p1 = @time sum_global()\n",
    "println(\"Permormance1 = $p1\")\n",
    "\n",
    "p2 = @time sum_global()\n",
    "println(\"Permormance2 = $p2\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On the first call (@time sum_global()) the function gets compiled. (If you've not yet used @time in this session, it will also compile functions needed for timing.) You should not take the results of this run seriously. For the second run, note that in addition to reporting the time, it also indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in a vector of 64-bit floats so there should be no need to allocate memory (at least not on the heap which is what @time reports)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = rand(1000);\n",
    "\n",
    "function sum_arg(x)\n",
    "    s = 0.0\n",
    "    for i in x\n",
    "        s += i\n",
    "    end\n",
    "    return s\n",
    "end;\n",
    "\n",
    "p1 = @time sum_arg(x)\n",
    "println(\"Permormance1 = $p1\")\n",
    "\n",
    "p2 = @time sum_arg(x)\n",
    "println(\"Permormance2 = $p2\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Conclusion : attention aux variables globales!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function sumofsins1(n::Integer)  \n",
    "    r = 0  \n",
    "    for i in 1:n  \n",
    "        r += sin(3.4)  \n",
    "    end  \n",
    "    return r  \n",
    "end  \n",
    "\n",
    "function sumofsins2(n::Integer)  \n",
    "    r = 0.0  \n",
    "    for i in 1:n  \n",
    "        r += sin(3.4)  \n",
    "    end  \n",
    "    return r  \n",
    "end  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sumofsins1(100_000)  \n",
    "sumofsins2(100_000)  \n",
    "\n",
    "@time [sumofsins1(100_000) for i in 1:100];  \n",
    "@time [sumofsins2(100_000) for i in 1:100];"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@time [sumofsins1(100_000) for i in 1:100];  \n",
    "@time [sumofsins2(100_000) for i in 1:100];"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Autres points\n",
    "### Modules\n",
    "### Interface programme en C, en fortran, ...\n",
    "### Calcul parallèle\n",
    "### ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Remarques\n",
    "### Caractères UTF-8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "β\n",
    "α = 10.               # on tape \\alp puis TAB, on obtient \\alpha et on retape TAB et on a le caractère grec"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ch = \"élément\"\n",
    "ch[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ch[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ch[3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Inconvénients\n",
    "* la portée des variables;\n",
    "* la possibilité dans une fonction de créer une variable (locale) de même nom qu'un paramètre formel;\n",
    "* On compile à la volé lors de chaque lancement d'une session. Possibilité de générer du code compiler?"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 1.6.0",
   "language": "julia",
   "name": "julia-1.6"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}