Julia. Les premiers pas, sixième partie

2. Comprendre les types de paramètres

using Dates

let # portée locale
    d = Dates.now()
    println("Daniel Hagnoul $d\n")
end
Daniel Hagnoul 2020-11-02T10:31:39.258

Le concept de nombres est simple, mais dans la pratique, de nombreux types numériques sont mis en œuvre dans les systèmes informatiques en raison des différences de stockage physique et de représentation des données.

On peut naviguer dans la hiérarchie des types avec subtype() et supertypes().

Julia REPL et Jupyter traitent normalement ces fonctions utilitaires, mais weave.jl ne les connaît pas.

subtypes(Number) : 2-element Array{Any,1}: Complex Real

subtypes(Real) : 4-element Array{Any,1}: AbstractFloat AbstractIrrational Integer Rational

subtypes(AbstractFloat) : 4-element Array{Any,1}: BigFloat Float16 Float32 Float64

subtypes(Integer) : 3-element Array{Any,1}: Bool Signed Unsigned

subtypes(Signed) : 6-element Array{Any,1}: BigInt Int128 Int16 Int32 Int64 Int8

Travailler avec des types composites paramétriques

L'une des fonctionnalités les plus puissantes du langage Julia est la possibilité de paramétrer les types.

Les types paramétriques permettent au concepteur de logiciels de généraliser les types et de permettre au runtime Julia de se compiler automatiquement vers la version concrète en fonction des paramètres spécifiés.

Voyons comment cela fonctionne avec les types composites et abstraits.

#=
    Les types abstraits peuvent être paramétrés.

    Au type abstrait Possesion nous donnons le type paramétrique P
    pour dire que chaque élément de ce type devra contenir une 
    propriété du type P, nous pensons à une valeur monétaire.

    Attention le type paramétrique P se trouve entre parenthèses.
=#

abstract type Possesion{P} end

struct Action{P} <: Possesion{P}
    symbol::String
    nom::String
    prix_d_achat::P
end

apple = Action("AAPL", "Apple, Inc", 180.0)
microsoft = Action("MSFT", "Microsoft", 312.0)

mutable struct Portefeuille{T, P} <: Possesion{P}
    action::Action
    quantité::T
    valeur_d_achat::P
    valeur_actuelle::P
end

#=
    Il y a un piège à éviter, ne pas changer le type de la valeur paramètrique
    dans les différents appels.
=#

mon_portefeuille_apple = Portefeuille(apple, 100, apple.prix_d_achat * 100, 20000.0)
mon_portefeuille_microsoft = Portefeuille(microsoft, 265, microsoft.prix_d_achat * 265, 93720.0)

println("mon_portefeuille_apple = $(mon_portefeuille_apple)\n")
println("mon_portefeuille_microsoft = $(mon_portefeuille_microsoft)\n")

mon_portefeuille_microsoft.valeur_actuelle = 97615 # cet Int sera implicitement converti en Float64

println("mon_portefeuille_microsoft = $(mon_portefeuille_microsoft)")
mon_portefeuille_apple = Main.##WeaveSandBox#253.Portefeuille{Int64,Float64
}(Main.##WeaveSandBox#253.Action{Float64}("AAPL", "Apple, Inc", 180.0), 100
, 18000.0, 20000.0)

mon_portefeuille_microsoft = Main.##WeaveSandBox#253.Portefeuille{Int64,Flo
at64}(Main.##WeaveSandBox#253.Action{Float64}("MSFT", "Microsoft", 312.0), 
265, 82680.0, 93720.0)

mon_portefeuille_microsoft = Main.##WeaveSandBox#253.Portefeuille{Int64,Flo
at64}(Main.##WeaveSandBox#253.Action{Float64}("MSFT", "Microsoft", 312.0), 
265, 82680.0, 97615.0)

Résumé

Julia est livrée avec un système de types très riche qu'un programmeur peut utiliser pour raisonner la relation entre chaque type et d'autres types.

Les types abstraits nous permettent de définir des comportements dans une hiérarchie de relations, et les types concrets sont utilisés pour définir comment les données sont stockées.

Les types paramétriques sont utilisés pour étendre les types existants aux variations de types des propriétés.

Toutes ces constructions de langage permettent au programmeur de modéliser efficacement les données et le comportement.

Licence Creative Commons Attribution 2.0 Belgique