Environnements

Un article de Mangue.org, l'encyclopéde libre.

Vous apprendrez la manière dont les informations sont mémorisées par CAML et la façon dont il les utilise par la suite...


Introduction aux environnements

On appelle environnement l'état courant de la mémoire, c'est à dire ce que le Caml connait à un instant précis pour évaluer une expression. C'est un ensemble de données retenues en mémoire dans ce que nous appellons la pile.

Chaque définition est stockée en tête de l'environnement comme nous l'avons vus dans les premiers cours.

Remarque
Quand on vous parle de pile en informatique, il faut faire un rapprochement avec une pile de livres par exemple, et pas une pile électrique.
Quand vous avez une pile de livre, vous commencez toujours par regarder au sommet si ce que vous avez correspond à ce que vous recherchez, si ce n'est pas le cas vous descendez dans la pile... C'est exactement ça !

Nous allons maintenant définir successivement deux constantes avec le même nom mais des valeurs différentes. Voici ce qu'il se passe en mémoire :

# let a = 1 ;;
a : int = 1

# let a = 3 ;;
a : int = 3

A chaque définition, le Caml ajoute une liaison nom - type - valeur en tête de l'environnement actuel... Elle sera par la suite exploitée par le Caml. La seconde définition de la constante a rends la précédente inaccessible. Elle n'est en aucun cas effacée de l'environnement mais est oblitérée tout simplement.

Repensez à notre analogie (pile de livres), lorsque vous demanderez l'évaluation de a, le Caml commencera par chercher en haut de la pile, il ne trouvera rien puis arrivera sur notre liaison a - int - 3 qui correspondra à ce qu'il recherche, c'est pourquoi il ne retombera jamais sur a - int - 1

Remarque
Attention ceci n'est valable que pour les constantes, le fonctionnement est très différent pour les références puisque, vous le savez, c'est une adresse mémoire qui est stockée et pas une valeur.


Les dangers

Redéfinir une constante ne pose pas de grand problème, sinon que sa valeur précédente est perdue à jamais. Mais qu'arrivera-t-il si nous essayons de redéfinir une des fonctions de base du Caml comme sqrt (qui permet de calculer la racine carrée d'un nombre flotant je vous le rappelle)

# sqrt ;;
- : float -> float = <fun>
# let sqrt x = x +. 1.0 ;;
sqrt : float -> float = <fun>
# sqrt (2.0) ;;
- : float = 3.0
# let sqrt = true ;;
sqrt : bool = true
# sqrt (1.0) (* absurde puisque ce n'est plus une fonction *) ;;
Toplevel input:
> sqrt (1.0) (* absurde puisque ce n'est plus une fonction *) ;;
> ^^^^
This expression is not a function, it cannot be applied.

Non seulement il est possible de redéfinir sqrt, mais nous avons poussé le vice jusqu'à en changer le type ! Si vous ne faites pas attention et que vous définissez des choses sans être certain que vous n'aurez pas à les utiliser par la suite vous aurez du mal c'est sûr ;-)

La fonction sqrt n'est pas indispensable puisque l'opérateur ** existe, mais il est aussi possible de redéfinir des opérateurs (nous ne verrons pas comment dans ces cours), et là il serait impossible d'effectuer bien des opérations.

Astuce
Vous pouvez vérifier si un identificateur est libre ou pas tout simplement en en demandant l'évaluation, si une erreur de type The value identifier [...] is unbound. vous ets renvoyé celà indique que rien n'existe sous ce nom et que vous pouvez l'utiliser sans risques.


Stockage en mémoire...

Pour les constantes rien de plus simple, une liaison nom - type - valeur est créée et ajoutée en tête de l'environnement tout simplement. Les choses se compliquent un peu pour les fonctions qui font intervenir des valeurs fonctionnelles.
Toujours pour les fonctions vous devez retenir que lors de leur évaluation le Caml continue à parcourir l'environnement et ne recommence pas ! Celà implique que si une constante a utilisée dans le corps d'une fonction a été redéfinie plus tard avec une valeur différente ça n'aura pas d'effet sur la valeur fonctionnelle elle-même !

Ce n'est pas très différent pour les fonctions récursives, il faut juste noter qu'elles contiennent une sorte de pointeur en mémoire sur leur adresse dans la pile. Celà permet tout simplement de les laisser s'appeller elle-mêmes.

C'est différent pour les références puisque ce n'est pas une valeur qui est associée à un nom mais une adresse mémoire! Ce qui précède pour les constantes n'est pas applicable aux références. Il faut les imaginer comme des relations entre un nom et une adresse mémoire, un pointeur sur une adresse mémoire pour être exact.

Outils personels