+++ to secure your transactions use the Bitcoin Mixer Service +++

 

Aller au contenu

« Erlang (langage) » : différence entre les versions

Un article de Wikipédia, l'encyclopédie libre.
Contenu supprimé Contenu ajouté
m Ajout d’un lien Wikipedia sur un mot difficile à comprendre
Balises : Éditeur visuel Modification par mobile Modification par le web mobile
Xqbot (discuter | contributions)
m Bot: remplacer la balise <source> obsolète et le paramètre "enclose"; changements cosmétiques
Ligne 19 : Ligne 19 :
| système d'exploitation = [[Logiciel multiplate-forme|Multi-plateforme]]
| système d'exploitation = [[Logiciel multiplate-forme|Multi-plateforme]]
}}
}}
[[Fichier:LYME_software_bundle.svg|thumb|300px|[[:en:LYME_(software_bundle)|LYME]] et LYCE sont basés sur '''Erlang''' et offres alternatives à [[LAMP]].]]
[[Fichier:LYME_software_bundle.svg|vignette|300px|[[:en:LYME_(software_bundle)|LYME]] et LYCE sont basés sur '''Erlang''' et offres alternatives à [[LAMP]].]]
'''Erlang''' est un [[langage de programmation]], supportant plusieurs [[Paradigme (programmation)|paradigmes]] : [[Programmation concurrente|concurrent]], [[Système temps réel|temps réel]], [[Architecture distribuée|distribué]]. Son cœur séquentiel est un [[Programmation fonctionnelle|langage fonctionnel]] à [[évaluation stricte]], [[Affectation (informatique)|affectation unique]], au [[typage dynamique]] [[Typage fort|fort]]. Sa couche concurrente est fondée sur le [[modèle d'acteur]]. Il possède des fonctionnalités de [[tolérance aux pannes]] et de mise à jour du code à chaud, permettant le développement d'applications à très haute disponibilité. Erlang est conçu pour s'exécuter sur une machine virtuelle spécifique appelée [[BEAM (machine virtuelle)|BEAM]].
'''Erlang''' est un [[langage de programmation]], supportant plusieurs [[Paradigme (programmation)|paradigmes]] : [[Programmation concurrente|concurrent]], [[Système temps réel|temps réel]], [[Architecture distribuée|distribué]]. Son cœur séquentiel est un [[Programmation fonctionnelle|langage fonctionnel]] à [[évaluation stricte]], [[Affectation (informatique)|affectation unique]], au [[typage dynamique]] [[Typage fort|fort]]. Sa couche concurrente est fondée sur le [[modèle d'acteur]]. Il possède des fonctionnalités de [[tolérance aux pannes]] et de mise à jour du code à chaud, permettant le développement d'applications à très haute disponibilité. Erlang est conçu pour s'exécuter sur une machine virtuelle spécifique appelée [[BEAM (machine virtuelle)|BEAM]].


Ligne 30 : Ligne 30 :
Comme tous [[Programmation fonctionnelle|les langages fonctionnels]], Erlang repose beaucoup sur la [[Algorithme récursif|récursivité]].
Comme tous [[Programmation fonctionnelle|les langages fonctionnels]], Erlang repose beaucoup sur la [[Algorithme récursif|récursivité]].


En Erlang, la fonction [[factorielle]] peut s'écrire sous une forme récursive, comme suit :
En Erlang, la fonction [[factorielle]] peut s'écrire sous une forme récursive, comme suit :


<source lang="erlang">
<syntaxhighlight lang="erlang">
-module(fact). % le nom du fichier est fact.erl (fichier et module doivent porter le même nom)
-module(fact). % le nom du fichier est fact.erl (fichier et module doivent porter le même nom)
-export([fac/1]). % exporte (publiquement) la fonction fac, d'arité 1 (un seul argument)
-export([fac/1]). % exporte (publiquement) la fonction fac, d'arité 1 (un seul argument)
Ligne 39 : Ligne 39 :
fac(N) when N > 0 -> N*fac(N-1). % cœur récursif : quand N vaut 1, alors fac(N-1) retourne 1,
fac(N) when N > 0 -> N*fac(N-1). % cœur récursif : quand N vaut 1, alors fac(N-1) retourne 1,
% la récursion s'arrête et N * 1 est retourné comme résultat
% la récursion s'arrête et N * 1 est retourné comme résultat
</syntaxhighlight>
</source>


où <code>fac(0)</code> est le cas de base, et <code>fac(N)</code> le cœur récursif.
où <code>fac(0)</code> est le cas de base, et <code>fac(N)</code> le cœur récursif.
Ligne 45 : Ligne 45 :
Une version utilisant la [[récursion terminale]], avec un accumulateur :
Une version utilisant la [[récursion terminale]], avec un accumulateur :


<source lang="erlang">
<syntaxhighlight lang="erlang">
-module(tail_fact).
-module(tail_fact).
-export([tail_fact/1]).
-export([tail_fact/1]).
Ligne 57 : Ligne 57 :
% suivante sans conserver les N-1 valeurs de tail_fact()
% suivante sans conserver les N-1 valeurs de tail_fact()
% précédentes en mémoire (le cas de base gère le retour final)
% précédentes en mémoire (le cas de base gère le retour final)
</syntaxhighlight>
</source>


L'algorithme de tri [[tri rapide|Quicksort]] avec une implémentation également récursive peut s'écrire sous cette forme en Erlang (de nombreuses variantes existent) :
L'algorithme de tri [[tri rapide|Quicksort]] avec une implémentation également récursive peut s'écrire sous cette forme en Erlang (de nombreuses variantes existent) :


<source lang="erlang">
<syntaxhighlight lang="erlang">
%% quicksort:qsort(List)
%% quicksort:qsort(List)
%% Trie une liste d'éléments
%% Trie une liste d'éléments
Ligne 70 : Ligne 70 :
qsort([Pivot|Reste]) ->
qsort([Pivot|Reste]) ->
qsort([ X || X <- Reste, X < Pivot]) ++ [Pivot] ++ qsort([ Y || Y <- Reste, Y >= Pivot]).
qsort([ X || X <- Reste, X < Pivot]) ++ [Pivot] ++ qsort([ Y || Y <- Reste, Y >= Pivot]).
</syntaxhighlight>
</source>


Le code fait des appels récursifs à la fonction <code>qsort</code> jusqu'à ce que l'ensemble soit trié. L'expression <code>[ X || X <- Reste, X < Pivot]</code> peut se traduire par « Choisir l'ensemble des <code>X</code> tels que <code>X</code> est un membre de <code>Reste</code> et <code>X</code> est inférieur à <code>Pivot</code> ». L'opérateur <code>++</code> est celui de la concaténation entre les listes.
Le code fait des appels récursifs à la fonction <code>qsort</code> jusqu'à ce que l'ensemble soit trié. L'expression <code>[ X || X <- Reste, X < Pivot]</code> peut se traduire par « Choisir l'ensemble des <code>X</code> tels que <code>X</code> est un membre de <code>Reste</code> et <code>X</code> est inférieur à <code>Pivot</code> ». L'opérateur <code>++</code> est celui de la concaténation entre les listes.
Ligne 83 : Ligne 83 :
dans lequel <code>Pid</code> est l'identité du processus destinataire et <code>Message</code> une expression quelconque.
dans lequel <code>Pid</code> est l'identité du processus destinataire et <code>Message</code> une expression quelconque.


À la différence d'autres langages concurrents comme [[Ada (langage)|Ada]], l'envoi et la réception d'un message sont [[Asynchrone|asynchrones]] en Erlang. Du point de vue de l'émetteur, l'envoi est instantané quel que soit l'état du destinataire. Le message est simplement remis dans la boîte aux lettres de ce dernier qui pourra le consommer au moment voulu. Cette propriété permet de découpler temporellement l'émetteur du receveur et ainsi de maximiser le niveau de concurrence dans le système tout en restant tolérant à la latence introduite par la communication dans un système distribué.
À la différence d'autres langages concurrents comme [[Ada (langage)|Ada]], l'envoi et la réception d'un message sont [[asynchrone]]s en Erlang. Du point de vue de l'émetteur, l'envoi est instantané quel que soit l'état du destinataire. Le message est simplement remis dans la boîte aux lettres de ce dernier qui pourra le consommer au moment voulu. Cette propriété permet de découpler temporellement l'émetteur du receveur et ainsi de maximiser le niveau de concurrence dans le système tout en restant tolérant à la latence introduite par la communication dans un système distribué.


=== Gestion explicite du temps ===
=== Gestion explicite du temps ===
Du fait de ses origines comme outil logiciel de télécommunications, Erlang permet la définition de contraintes de temps réel souple (''{{Langue|en|soft real time}}''), c'est-à-dire l'exécution d'une action à l'intérieur d'un temps déterminé. Erlang incorpore la gestion du temps dans la primitive de réception de message ''{{Langue|en|receive}}'', dont la syntaxe est la suivante :
Du fait de ses origines comme outil logiciel de télécommunications, Erlang permet la définition de contraintes de temps réel souple (''{{Langue|en|soft real time}}''), c'est-à-dire l'exécution d'une action à l'intérieur d'un temps déterminé. Erlang incorpore la gestion du temps dans la primitive de réception de message ''{{Langue|en|receive}}'', dont la syntaxe est la suivante :
<source lang="erlang">
<syntaxhighlight lang="erlang">
receive
receive
Message1 ->
Message1 ->
Ligne 97 : Ligne 97 :
ActionTimeOut
ActionTimeOut
end
end
</syntaxhighlight>
</source>


Le processus qui exécute le code ci-dessus attendra au plus, la valeur de l'expression <code>Timeout</code>. Si aucun message correspondant à <code>Message1</code> ou <code>Message2</code> n'est reçu par le processus d'ici là, il exécute alors l'action <code>ActionTimeOut</code>.
Le processus qui exécute le code ci-dessus attendra au plus, la valeur de l'expression <code>Timeout</code>. Si aucun message correspondant à <code>Message1</code> ou <code>Message2</code> n'est reçu par le processus d'ici là, il exécute alors l'action <code>ActionTimeOut</code>.


=== La programmation distribuée à base de nœud et de processus ===
=== La programmation distribuée à base de nœud et de processus ===
Ligne 107 : Ligne 107 :


=== La richesse de l'environnement ===
=== La richesse de l'environnement ===
Bâties sur le langage, les bibliothèques ''Open Telecom Platform (OTP)'' offrent des fonctionnalités de distribution des traitements et de supervision des nœuds avancées, ainsi qu'une base de données répartie. L'accent est mis sur la tolérance aux pannes puisque le couple Erlang/OTP permet entre autres de :
Bâties sur le langage, les bibliothèques ''Open Telecom Platform (OTP)'' offrent des fonctionnalités de distribution des traitements et de supervision des nœuds avancées, ainsi qu'une base de données répartie. L'accent est mis sur la tolérance aux pannes puisque le couple Erlang/OTP permet entre autres de :
* mettre à jour le code d'un programme sans arrêter celui-ci ;
* mettre à jour le code d'un programme sans arrêter celui-ci ;
* désigner des processus superviseurs qui suivront des instructions bien précises en cas d'arrêt des processus supervisés (redémarrage immédiat ou retardé, décompte du nombre d'erreurs avant de ne plus essayer de redémarrer le processus fautif, etc.) ;
* désigner des processus superviseurs qui suivront des instructions bien précises en cas d'arrêt des processus supervisés (redémarrage immédiat ou retardé, décompte du nombre d'erreurs avant de ne plus essayer de redémarrer le processus fautif, etc.) ;

Version du 19 avril 2020 à 13:08

Erlang
Logo.

Date de première version 1987
Paradigme Concurrent
Fonctionnel
Auteur Ericsson
Développeur Ericsson
Dernière version 26.2.5 ()[1]Voir et modifier les données sur Wikidata
Typage Dynamique
Fort
Influencé par Prolog
A influencé Scala, Clojure
Écrit en ErlangVoir et modifier les données sur Wikidata
Système d'exploitation Multi-plateforme
Licence Licence Apache version 2.0[2]Voir et modifier les données sur Wikidata
Site web www.erlang.orgVoir et modifier les données sur Wikidata
Extension de fichier erlVoir et modifier les données sur Wikidata
LYME et LYCE sont basés sur Erlang et offres alternatives à LAMP.

Erlang est un langage de programmation, supportant plusieurs paradigmes : concurrent, temps réel, distribué. Son cœur séquentiel est un langage fonctionnel à évaluation stricte, affectation unique, au typage dynamique fort. Sa couche concurrente est fondée sur le modèle d'acteur. Il possède des fonctionnalités de tolérance aux pannes et de mise à jour du code à chaud, permettant le développement d'applications à très haute disponibilité. Erlang est conçu pour s'exécuter sur une machine virtuelle spécifique appelée BEAM.

Il a été créé par Ericsson, qui l'utilise dans plusieurs de ses produits, tels que le commutateur ATM AXD 301. Initialement propriétaire, il est publié sous licence Open Source depuis 1998. Il est également utilisé par d'autres entreprises développant des logiciels liés aux réseaux de télécommunications, comme T-Mobile, Nortel ou encore plus récemment WhatsApp pour de la messagerie instantanée.
Il est aussi utilisé pour écrire le serveur XMPP ejabberd, la base de données NoSQL CouchDB, le serveur HTTP Yaws ainsi que le logiciel de modélisation 3D Wings 3D. Il possède de nombreuses bibliothèques incluses dans la distribution de base et regroupées sous le nom de OTP (Open Telecom Platform). OTP représente le framework standard de l'univers Erlang, la plupart des programmeurs l'utilisant comme base d'interopérabilité. Il peut s'interfacer avec d'autres langages comme Java ou C++.

Le nom « Erlang » fait référence au mathématicien Agner Erlang, tout en faisant figure de mot valise de l’expression Ericsson Language.

Exemples

Comme tous les langages fonctionnels, Erlang repose beaucoup sur la récursivité.

En Erlang, la fonction factorielle peut s'écrire sous une forme récursive, comme suit :

-module(fact). % le nom du fichier est fact.erl (fichier et module doivent porter le même nom)
-export([fac/1]). % exporte (publiquement) la fonction fac, d'arité 1 (un seul argument)

fac(0) -> 1; % cas de base : notez le point-virgule qui signifie « ou »
fac(N) when N > 0 -> N*fac(N-1). % cœur récursif : quand N vaut 1, alors fac(N-1) retourne 1,
                                 % la récursion s'arrête et N * 1 est retourné comme résultat

fac(0) est le cas de base, et fac(N) le cœur récursif.

Une version utilisant la récursion terminale, avec un accumulateur :

-module(tail_fact).
-export([tail_fact/1]).

tail_fact(N) -> tail_fact(N,1). % interface publique : délègue à l'implémentation tail_fact/2
tail_fact(0,Acc) -> Acc; % cas de base : si N vaut 0, on retourne l'accumulateur
tail_fact(N,Acc) when N > 0 -> tail_fact(N-1,N*Acc). % cœur récursif : contrairement au cas récursif simple,
                                                     % où la valeur de fac() est multipliée à N et doit être
                                                     % conservée en mémoire, ici tail_fact() est « seule »,
                                                     % l'accumulateur Acc permettant de passer à l'itération
                                                     % suivante sans conserver les N-1 valeurs de tail_fact()
                                                     % précédentes en mémoire (le cas de base gère le retour final)

L'algorithme de tri Quicksort avec une implémentation également récursive peut s'écrire sous cette forme en Erlang (de nombreuses variantes existent) :

%% quicksort:qsort(List)
%% Trie une liste d'éléments
-module(quicksort).
-export([qsort/1]).
 
qsort([]) -> [];
qsort([Pivot|Reste]) ->
    qsort([ X || X <- Reste, X < Pivot]) ++ [Pivot] ++ qsort([ Y || Y <- Reste, Y >= Pivot]).

Le code fait des appels récursifs à la fonction qsort jusqu'à ce que l'ensemble soit trié. L'expression [ X || X <- Reste, X < Pivot] peut se traduire par « Choisir l'ensemble des X tels que X est un membre de Reste et X est inférieur à Pivot ». L'opérateur ++ est celui de la concaténation entre les listes.

Fonctionnalités notables

Le partage de données par passage de message

Contrairement aux processus légers (threads) dans des langages classiques tels Java ou C, les processus Erlang ne partagent pas de mémoire pour communiquer, ce qui permet d'éviter les problèmes liés à la synchronisation. La transmission d'informations se fait uniquement par passage de messages. La primitive qui permet l'envoi d'un message est send, exprimée par !.

La syntaxe est la suivante :

Pid ! Message

dans lequel Pid est l'identité du processus destinataire et Message une expression quelconque.

À la différence d'autres langages concurrents comme Ada, l'envoi et la réception d'un message sont asynchrones en Erlang. Du point de vue de l'émetteur, l'envoi est instantané quel que soit l'état du destinataire. Le message est simplement remis dans la boîte aux lettres de ce dernier qui pourra le consommer au moment voulu. Cette propriété permet de découpler temporellement l'émetteur du receveur et ainsi de maximiser le niveau de concurrence dans le système tout en restant tolérant à la latence introduite par la communication dans un système distribué.

Gestion explicite du temps

Du fait de ses origines comme outil logiciel de télécommunications, Erlang permet la définition de contraintes de temps réel souple (soft real time), c'est-à-dire l'exécution d'une action à l'intérieur d'un temps déterminé. Erlang incorpore la gestion du temps dans la primitive de réception de message receive, dont la syntaxe est la suivante :

 receive
     Message1 ->
        Action1;
     Message2 ->
        Action2
 after
     Timeout ->
        ActionTimeOut
 end

Le processus qui exécute le code ci-dessus attendra au plus, la valeur de l'expression Timeout. Si aucun message correspondant à Message1 ou Message2 n'est reçu par le processus d'ici là, il exécute alors l'action ActionTimeOut.

La programmation distribuée à base de nœud et de processus

Les processus Erlang s'exécutent dans une machine virtuelle. Plusieurs machines virtuelles possiblement situées sur différents ordinateurs peuvent être connectées entre elles et former les nœuds d'un système distribué. La communication entre processus localisés sur des nœuds différents utilise les mêmes primitives et possède la même sémantique que pour la communication entre processus du même nœud. Du point de vue du programmeur, la localisation d'un processus est transparente.

Les connexions entre nœuds sont dynamiques. Un nœud peut joindre et quitter le système (ou en être isolé par une panne) à n'importe quel moment. Cette caractéristique autorise la tolérance aux pannes par redondance et la montée en charge d'une application par ajout de nouveaux nœuds.

La richesse de l'environnement

Bâties sur le langage, les bibliothèques Open Telecom Platform (OTP) offrent des fonctionnalités de distribution des traitements et de supervision des nœuds avancées, ainsi qu'une base de données répartie. L'accent est mis sur la tolérance aux pannes puisque le couple Erlang/OTP permet entre autres de :

  • mettre à jour le code d'un programme sans arrêter celui-ci ;
  • désigner des processus superviseurs qui suivront des instructions bien précises en cas d'arrêt des processus supervisés (redémarrage immédiat ou retardé, décompte du nombre d'erreurs avant de ne plus essayer de redémarrer le processus fautif, etc.) ;
  • mettre en place une hiérarchie de supervision redondante et centralisée de telle sorte que l'application soit entièrement supervisée tout en répartissant la logique de supervision à chaque niveau.

Annexes

Articles connexes

  • Reia, langage de script pour la machine virtuelle Erlang, inspiré de Ruby, projet abandonné au profit de :
  • Elixir, langage de script pour la machine virtuelle Erlang, inspiré de Ruby.

Liens externes

  1. a et b « Release 26.2.5 », (consulté le )
  2. « Erlang/OTP 18.0 has been released » (consulté le )