• [^] # Re: Donc pour résumer...

    Posté par . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 3. Dernière modification le 09 octobre 2016 à 22:01.

    Je viens de réaliser qu'il y a un bug dans le code de mon module sur les tableaux persistants : les codes des fonctions to_array et of_array permettent de manipuler la mémoire partagée en dehors des fonctions fournies par le module, et donc de casser l'invariant. :-/

    Au passage ça me permet d'illustrer ce qui se passe sur cette mémoire partagée.

    let shared = [|0; 1; 2; 3|];;
    let tab = PA.of_array shared;;
    val tab : int PA.t = <abstr>
    let tab' = PA.set tab 0 4;;
    val tab' : int PA.t = <abstr>
    (* maintenant la zone partagée contient le tableau tab' *)
    shared;;
    - : int array = [|4; 1; 2; 3|]
    (* dès qu'on opère sur tab, c'est lui qui se retrouve dans shared *)
    PA.get tab 0;;
    - : int = 0 
    shared;;
    - : int array = [|0; 1; 2; 3|]
    (* par contre si on modifie shared, cela modifie les tableaux sensés être immuables *)
    Array.set shared 1 6;;
    - : unit = ()
    PA.to_array tab;;
    - : int array = [|0; 6; 2; 3|]
    PA.to_array tab';;
    - : int array = [|4; 6; 2; 3|]

    La solution consiste à effectuer une copie des tableaux mutables pour conserver « l'encapsulation » et maintenir l'invariant.

    let to_array pa = Array.copy (reroot pa)
    let of_array a = ref (Arr (Array.copy a))
    let shared = [|0; 1; 2; 3|];;
    val shared : int array = [|0; 1; 2; 3|]
    let tab = PA.of_array shared;;
    val tab : int PA.t = <abstr>
    (* si on modifie shared, le tableau tab reste bien inchangé *)
    Array.set shared 0 5;;
    - : unit = ()
    PA.to_array tab;;
    - : int array = [|0; 1; 2; 3|]

    Au passage, cet exemple m'aura permis de montrer que l'on peut également faire de la gestion de mémoire bas niveau en OCaml : pointeur en lecture, pointeur en lecture-écriture, pointeur sur pointeur... bien que la libération de la mémoire soit automatisée et déléguée au runtime et au GC.

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.