Edit

kc3-lang/kc3/doc/3_Guides/3.5_Tutorial.fr.md

Branch :

  • doc/3_Guides/3.5_Tutorial.fr.md
  • # Tutoriel KC3 et exemples
    
    Voici quelques exemples `ikc3` avec lesquels vous pouvez vous exercer.
    
    ## Maps
    
    Les maps KC3 sont des structures clé-valeur. Vous pouvez utiliser
    n’importe quel `Tag` comme clé et lui associer une valeur.
    
    Vous pouvez utiliser la déstructuration pour accéder aux maps KC3 :
    ```elixir
    ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
    %{id: 1, title: "My title", message: "Hello, world !"}
    ikc3> a = %{}
    %{id: 1, title: "My title", message: "Hello, world !"}
    ikc3> %{id: id, title: "My title", message: message} = a
    %{id: 1, title: "My title", message: "Hello, world !"}
    ikc3> id
    1
    ikc3> message
    "Hello, world !"
    ```
    
    Vous pouvez utiliser la syntaxe par point pour accéder aux valeurs
    d'une clé `Sym` :
    ```elixir
    ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
    %{id: 1, title: "My title", message: "Hello, world !"}
    ikc3> a.id
    1
    ikc3> a.message
    "Hello, world !"
    ```
    
    Vous pouvez également utiliser la fonction `KC3.access` pour obtenir
    le même résultat :
    ```elixir
    ikc3> a = %{id: 1, title: "My title", message: "Hello, world !"}
    %{id: 1, title: "My title", message: "Hello, world !"}
    ikc3> access(a, :id)
    1
    ikc3> access(a, :message)
    "Hello, world !"
    ```
    
    ## Unicode characters
    
    `ikc3` prend entièrement en charge Unicode :
    
    Quelques caractères Unicode :
    ```elixir
    ikc3> '\U+1B2FB'
    '𛋻'
    ikc3> '𐅀'
    '𐅀'
    ikc3> '🤩'
    '🤩'
    ikc3>
    ```
    
    ## Grands entiers
    
    ```elixir
    ikc3> a = 1 + 100000000000000000000000000000000
    100000000000000000000000000000001
    ikc3> a * a
    10000000000000000000000000000000200000000000000000000000000000001
    ikc3>
    ```
    
    ## Ratios
    
    Les ratios sont créés avec un couple d'entiers : le numérateur
    qui peut être n'importe quel entier, et le dénominateur qui doit être positif.
    Ils représentent des fractions de nombres entiers.
    Ils s’écrivent avec un slash sans espace.
    
    ```elixir
    ikc3> 1/2 + 2/3
    7/6
    ikc3> 1/2 * 2/3
    1/3
    ikc3> 1/2 / 2/3
    3/4
    ikc3> 1/2 - 2/3
    -1/6
    ```
    
    ## Nombres complexes
    
    Les nombres complexes sont construits à l’aide de l’opérateur `+i` sur tout
    type de nombre (entiers signés, non signés, flottants, ratios, ou même
    d'autres nombres complexes). Par exemple vous pouvez ecrire `a +i b`
    où `a` et `b` sont des nombre flottants.
    
    ```elixir
    ikc3> 1 +i 2
    1 +i 2
    ikc3> 1 +i 2 + 2 +i 3
    3 +i 5
    ikc3> (1 +i 2) * (2 +i 3)
    -4 +i 7
    ikc3> (1 +i 2) / (2 +i 3)
    0 +i 0
    ikc3> (1/1 +i 2/1) / (2 +i 3)
    8/13 +i 1/13
    ```
    
    Comme vous pouvez voir la division entiere ne produit pas de fractions.
    Cela pourrait changer dans les versions futures.
    
    ## Lists
    
    Les listes s'écrivent avec des crochets : `[]`.
    
    Les listes régulières peuvent être :
     - un élément et une liste : `[1 | []]` → `[1]`
     - plusieurs éléments : `[1, 2, 3]`
     - plusieurs éléments et une liste : `[1, 2 | [3, 4]]` → `[1, 2, 3, 4]`
     - la liste vide : `[]`
    
    Les listes régulières se terminent toutes par la liste vide :
    `[1] == [1 | []]`.
    
    On peut également contruire des listes pointées comme en Common Lisp
    où le pointeur de liste suivante est une valeur arbitraire (`Tag`).
    Par exemple :
     - un élément et un élément : `[1 | 2]`
     - plusieurs éléments et un élément : `[1, 2, 3 | 4]`
     - la liste vide et un élément : `[[] | 1]`
    
    Tous ces formats de listes sont supportés dans la déstructuration.
    
    ## L'identification de motifs et la déstructuration
    
    Les principes de *pattern-matching* viennent d'Erlang et Elixir.
    
    Toutes les structures de données taggées de KC3 peuvent être identifiées
    (match) par un motif (pattern) en utilisant le signe égal (`=`) sur des
    valeurs littérales contenant des identifiants. Tous les identifiants sont
    repérés comme des nouvelles variables qui seront liées à une valeur lors
    de la déstructuration. Si vous voulez utiliser une variable c'est possible
    dans un appel de fonction ou en utilisant l'operateur identité :
    `^ ma_variable`. Les variables peuvent se trouver de chaque coté du signe
    égal tant qu'une vraie valeur se trouve dans la même structure de l'autre
    côté de l'operateur égal.
    
    Exemples :
    ```elixir
    ikc3> a = 1
    1
    ikc3> a = 2
    2
    ikc3> a
    2
    ikc3> ^ a = 1
    void
    ikc3> ^ a = 2
    2
    ikc3> ^ a = b
    2
    ikc3> b
    2
    ```
    
    Pour utiliser la déstructuration il suffit de taper la valeur littérale
    que l'on veut identifier et de mettre des identifiants sur les parties
    inconnues que l'on veut récupérer de l'autre coté du signe égal. C'est
    l'approche la plus visuelle possible pour programmer une identification
    de valeurs, bien plus simple que SQL ou SPARQL. Les données sont
    constamment affichées dans le code en affichant les variables dans la
    structure d'origine. On voit les données et leur type à l'écran
    constamment. Cela aide vraiement pour écrire de gros programmes qui ont
    besoin de grandir en terme d'abstractions : laisser les données passer
    dans le code à travers des types visuels.
    
    Exemples :
    ```elixir
    ikc3> [x, y | z] = List.reverse([1, 2, 3, 4])
    [4, 3, 2, 1]
    ikc3> x
    4
    ikc3> y
    3
    ikc3> z
    [2, 1]
    ```
    
    ## Macros
    
    Les macros KC3 sont comme les macros Common Lisp avec le *pattern-matching*
     (déstructuration) d'Elixir.
    
    Les macros sont comme des fonctions mais sont introduites par `macro`
    au lieu de `fn` et leurs arguments ne sont pas évalués. Par contre ils
    sont déstructurés avec toute la puissance du *pattern-matcher* pour
    extraire des variabes des arguments passés à la fonction. On peut
    utiliser un `Map` pour avoir des arguments nommés, une liste pour avoir
    des arguments `&rest`, ou un bloc pour avoir un argument `&body`.
    
    Une fois évaluée un appel de macro retourne un `Tag` (une valeur) qui est
    à son tour évaluée dans l'environnement lexical de l'appel. Cela permet
    la création de DSL (*domain-specific languages*) en KC3.
    
    Plusieurs opérations basiques sont définies comme des macros en KC3 :
    la gestion des erreurs, les segment de code de *clean-up* avec
    `unwind_protect`, les opérations sur la base de données en graphe.
    
    ## If, then, else.
    
    Les conditions en KC3 fonctionnent comme en Ruby, par exemple :
    ```elixir
    ikc3> if true && true
    ikc3>   1 + 1
    ikc3>   2 + 2
    ikc3> end
    4
    
    ikc3> if true && false
    ikc3>   1 + 1
    ikc3>   2 + 2
    ikc3> else
    ikc3>   3 + 3
    ikc3>   4 + 4
    ikc3> end
    8
    ```
    
    Un `if` renvoie toujours une valeur. Si la condition est vraie une fois
    castée en `Bool` avec `Bool.cast` (`bool_init_cast`), le premier bloc est
    évalué et retourné. Si la condition donne `false` (faux) alors le second
    bloc est évalué (`else`). Si la condition est fausse et qu'il n'y a pas
    de second bloc, `void` est retourné.
    
    Exemples sur une seule ligne avec `then` :
    ```elixir
    ikc3> if 42 then 100 else 101 end
    100
    ikc3> if 0 then 100 else 101 end
    101
    ```
    
    ## defmodule et def
    
    Exemple :
    ```elixir
    ikc3> defmodule Example do
    ikc3>   def three = 3
    ikc3>   def double = fn (x) do x * 2 end
    ikc3>   def double_tuple = macro (x) do {x, x} end
    ikc3>   def operator_double = %KC3.Operator{sym: :double, symbol_value: fn (x) { x * 2 }
    ikc3> end
    Example
    ikc3> Example.three
    3
    ikc3> Example.double
    fn (x) do x * 2 end
    ikc3> Example.double(21)
    42
    ikc3> Example.double_tuple(:ok)
    {:ok, :ok}
    ikc3> double 21
    42
    ```
    
    ## Facts
    
    Le module Facts (faits) permet un acces en lecture et en écriture vers
    une base de données en graphe contenant des faits : des triplets sujet,
    relation, objet.
    
    Des exemples pour faire des requêtes sur la base de données de KC3
    contenant toutes les définitions de l'interpreteur :
    
    ```elixir
    ikc3> Facts.with_tags(Facts.env_facts(), KC3, :op, ?,
            fn (fact) { puts(fact.object); :ok })
    operator_eq
    operator_gt
    operator_lt
    [...]
    :ok
    ```
    
    ---
    
    Top : [KC3 Guides](./)
    
    Previous : [Guide de la structure de KC3](3.4_Structure)