Transparence referentielle

Transparence referentielle

Transparence référentielle

La transparence référentielle est une propriété des langages de programmation qui fait que chaque expression peut être remplacée par son résultat sans changer le comportement du programme.

Sommaire

Définition

La transparence référentielle est une propriété des expressions d'un programme informatique. Une expression est référentiellement transparente si elle peut être remplacée par sa valeur sans changer le programme (c'est-à-dire résultant en un programme avec les mêmes effets et sorties pour les mêmes entrées). Le terme opposé est reférentiellement opaque.

Si toutes les fonctions impliquées dans l'expression sont des fonctions pures (c'est-à-dire sans effet de bord), alors l'expression est référentiellement transparente. Mais la réciproque est fausse : une expression référentiellement transparente peut impliquer des fonctions impures et donc des effets de bord.

La transparence référentielle est la pierre angulaire de la programmation fonctionnelle. Elle permet notamment la mémoization des fonctions référentiellement transparentes (c'est-à-dire la mémorisation des valeurs précédemment calculées).

Exemples et contre-exemples

Les opérations arithmétiques sont référentiellement transparentes : on peut ainsi remplacer 5*5 par sa valeur 25.

Beaucoup de fonctions, particulièrement celles dans le sens mathématique du terme : sin(x) est transparent, puisqu'il donne toujours le même résultat pour un x donné. L'expression x++ du langage C n'est pas transparente, car elle change la valeur de x.

Dans la plupart des langages, print( "Hello world" ) n'est pas transparent, car le remplacer par sa valeur change le comportement du programme puisque "Hello world" n'est pas imprimé. today() n'est pas transparent, car si vous l'évaluez et le remplacez par sa valeur (disons, "Jan 1, 2001"), vous n'obtenez pas le même résultat que si vous l'exécutez demain.

Contraste avec la programmation impérative

Un autre terme pour une fonction référentiellement transparente est fonction déterminée.

Si la substitution d'une expression par sa valeur est valide seulement à certains points d'un programme, alors l'expression n'est pas référentiellement transparente. La définition et l'ordre de ses points de séquence est la fondation théorique de la programmation impérative, et une porte de la sémantique des langages de programmation impératifs.

Néanmoins, puisqu'une expression référentiellement transparente peut être évaluée à tout moment, il n'est pas nécessaire de définir des points de séquence ou la garantie de l'ordre d'évaluation. On appelle programmation purement fonctionnelle la programmation libre de ces considérations.

L'avantage d'écrire du code avec un style référentiellement transparent est que l'analyse de code statique est plus facile et que des transformations d'amélioration de code sont automatiquement possibles. Par exemple, en programmation en C, il y a une pénalité de performance pour l'inclusion d'une fonction dans une boucle, même si l'appel de fonction pourrait être déplacé à l'extérieur de la boucle sans changer les résultats du programme. Le programmeur pourrait être forcé à faire ce déplacement, peut-être aux dépens de la lisibilité du code. Mais, si le compilateur est capable de déterminer si l'appel de la fonction est référentiellement transparent, il peut alors effectuer automatiquement cette transformation.

Le désavantage principal des langages imposant la transparence référentielle est qu'ils rendent malaisé et moins concis l'expression d'opérations qui s'expriment naturellement comme une suite de pas. De tels langages peuvent incorporer des mécanismes pour rendre ces tâches plus faciles tout en retenant leur qualité purement fonctionnelle tels que les monades et les definite clause grammars


Alors qu'en mathématiques toutes les applications de fonction sont référentiellement transparentes, en programmation ça n'est pas toujours le cas. Par exemple, prenez une fonction qui ne prend pas de paramètre et retourne une chaîne saisie au clavier. Un appel à cette fonction pourrait être GetInput(). La valeur de retour de GetInput() dépend de la valeur saisie au clavier, donc de multiples appels de GetInput avec des paramètres identiques (la liste vide) peuvent retourner des résultats différents.

Un exemple plus subtil : une fonction qui utilise une variable globale, ou une variable avec un scope dynamique ou lexical pour aider à calculer ses résultats. Puisque cette variable n'est pas passée comme paramètre mais peut être altérée, les résultats des appels suivants à la fonction peuvent différer même si les paramètres sont identiques. Dans les langages fonctionnels pur, l'affectation n'est pas autorisée. Donc une fonction qui utilise des variables globales ou au scope dynamique est référentiellement transparente puisque la valeur des variables ne peut pas changer.


L'importance de la transparence référentielle est qu'elle permet au programmeur ou au compilateur de raisonner sur le comportement du programme. Cela peut aider à prouver qu'il est correct, à trouver des bogues qui ne peuvent être trouvés par des tests, à simplifier un algorithme, à aider à modifier du code sans le casser, à optimiser le code par le moyen de la mémoization ou l'élimination des sous-expressions communes.

Certains langages de programmation fonctionnelle imposent la transparence référentielle pour toutes les fonctions.

Une conséquence de la transparence référencielle est qu'on ne fait pas ou ne reconnaît pas de différence entre une référence à une chose et la chose elle-même. Sans transparence référencielle, la différence peut aisément être faite et utilisée dans les programmes.

Principe de séparation commande-requête

Eiffel, bien que basé sur la programmation impérative, impose une séparation stricte entre les commandes qui peuvent produire des effets de bord et les requêtes qui doivent être référentiellement transparentes. Les requêtes retournent un résultat mais ne changent pas l'environnement. On appelle cette règle le principe de séparation commande-requête et débouche sur un style qui sépare clairement les parties référentiellement transparentes des autres. Par exemple dans la manipulation de listes :

my_list.finish        -- Déplace le curseur à la fin de la liste
value := my_list.item -- Obtient la valeur à la position du curseur : référentiellement transparent

Cela affecte même des fonctionnalités impératives comme les entrées :

my_file.read_integer          -- obtient le prochain entier; effet de bord, mais pas de valeur de retour
value := my_file.last_integer -- obtient le dernier entier lu: réferentiellent transparent

Appeler plusieurs fois en série last_integer donne le même résultat à chaque fois.

Autre exemple

Soit deux fonctions, dont l'une est référentiellement opaque, et l'autre référentiellement transparente :

globalValue = 0;
integer function rq(integer x)
begin
  globalValue = globalValue + 1;
  return x + globalValue;
end
integer function rt(integer x)
begin
  return x + 1;
end

Maintenant, rt est référentiellement transparent, ce qui signifie que rt(x) = rt(x) aussi longtemps que x contient la même valeur. Par exemple, rt(6) = 7, rt(4) = rt(3+1) = 5, et ainsi de suite. Mais vous ne pouvez pas dire cela de rq car il utilise une variable globale qu'il modifie.

Pourquoi est-ce une mauvaise chose ? Supposons maintenant que nous voulions raisonner sur le code suivant :

integer p = rq(x) + rq(y) * (rq(x) - rq(x));

A priori, on pourrait être tenté de simplifier cette ligne de code ainsi :

integer p = rq(x) + rq(y) * (0) = 
integer p = rq(x) + 0           = 
integer p = rq(x);

Mais cela ne marcherait pas pour rq() car rq(x) n'est pas nécessairement égal à rq(x)! En effet, la valeur de retour de rq est basée sur une variable globale (dont la valeur n'est pas passée comme paramètre) et qui peut être modifiée.

Cela fonctionnerait néanmoins avec rt, qui est une fonction référentiellement transparente.

On peut donc appliquer des raisonnements mathématiques avancés au code, ce qui conduit à des programmes plus robustes et permet de trouver des bogues qui échapperaient aux tests classiques. Cela permet même d'identifier des opportunités d'optimisation.

Voir aussi

Ce document provient de « Transparence r%C3%A9f%C3%A9rentielle ».

Wikimedia Foundation. 2010.

Contenu soumis à la licence CC-BY-SA. Source : Article Transparence referentielle de Wikipédia en français (auteurs)

Игры ⚽ Нужно сделать НИР?

Regardez d'autres dictionnaires:

  • Transparence référentielle — La transparence référentielle est une propriété des expressions d un langage de programmation qui fait qu une expression peut être remplacée par son résultat sans changer le comportement du programme. Sommaire 1 Définition 2 Exemples et contre… …   Wikipédia en Français

  • Transparence (Informatique) — Transparence Voir « transparence » sur le Wiktionnaire …   Wikipédia en Français

  • Transparence — Sur les autres projets Wikimedia : « Transparence », sur le Wiktionnaire (dictionnaire universel) Transparence a plusieurs significations en fonction du contexte. Transparence …   Wikipédia en Français

  • Langage fonctionnel — Programmation fonctionnelle La programmation fonctionnelle est un paradigme de programmation qui considère le calcul en tant qu évaluation de fonctions mathématiques et rejette le changement d état et la mutation des données. Elle souligne l… …   Wikipédia en Français

  • Programmation fonctionnelle — La programmation fonctionnelle est un paradigme de programmation qui considère le calcul en tant qu évaluation de fonctions mathématiques et rejette le changement d état et la mutation des données. Elle souligne l application des fonctions,… …   Wikipédia en Français

  • Effet De Bord (Informatique) — Pour les articles homonymes, voir Effet de bord. En informatique, une fonction est dite à effet de bord si elle modifie un état autre que sa valeur de retour. Par exemple, une fonction peut modifier une variable statique ou globale, modifier un… …   Wikipédia en Français

  • Effet de bord (informatique) — Pour les articles homonymes, voir Effet de bord. En informatique, une fonction est dite à effet de bord si elle modifie un état autre que sa valeur de retour. Par exemple, une fonction peut modifier une variable statique ou globale, modifier un… …   Wikipédia en Français

  • Effet secondaire (informatique) — Effet de bord (informatique) Pour les articles homonymes, voir Effet de bord. En informatique, une fonction est dite à effet de bord si elle modifie un état autre que sa valeur de retour. Par exemple, une fonction peut modifier une variable… …   Wikipédia en Français

  • Corps (informatique) — Fonction informatique Pour les articles homonymes, voir Fonction. En informatique, une fonction est une portion de code représentant un sous programme, qui effectue une tâche ou un calcul relativement indépendant du reste du programme. En… …   Wikipédia en Français

  • Corps D'une Fonction Ou D'une Procédure — Fonction informatique Pour les articles homonymes, voir Fonction. En informatique, une fonction est une portion de code représentant un sous programme, qui effectue une tâche ou un calcul relativement indépendant du reste du programme. En… …   Wikipédia en Français

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”