Générateur (informatique)

(Redirigé depuis Yield (instruction))

En informatique, un générateur est une routine non transparente référentiellement, généralement sans argument. Comme son nom l'indique, elle sert à créer de nouveaux objets. Parmi les générateurs les plus classiques, on trouve les générateurs de nombres aléatoires.

Un générateur suit le patron de conception itérateur, et permet en pratique de retourner un gros volume de données sans surcharger la mémoire vive, en la découpant en petits paquets[1].

Certains générateurs parcourent virtuellement une liste infinie, définie algorithmiquement. De tels générateurs sont appelés compréhensions de listes. Une fonction renvoyant tour à tour les éléments de la suite de Fibonacci ou tous les nombres premiers serait un tel générateur.

Implémentation modifier

Généralement un générateur est implémenté avec la fonction yield : une instruction de programmation qui sert à imposer la constructivité d'une fonction. Son utilisation dans une fonction permet de retourner un générateur.

Elle est plus souvent présente dans les langages à haut niveau comme PHP, Python, Ruby ou le C#.

Exemple en C# modifier

En C#, le mot-clé yield est suivi de return pour retourner la valeur suivante ou break pour interrompre l'itération.

using System.Collections.Generic;

public class Mots
{
    // Tableau contenant des mots :
    public string[] mots;

    // Constructeur
    public Mots(params string[] mots)
    { this.mots = mots; }

    // Énumérer tous les mots jusqu'à trouver
    // le mot contenu dans le paramètre dernier (exclu)
    // ou la fin du tableau.
    public IEnumerable<string> TousLesMotsJusquA(string dernier)
    {
        foreach(string mot in mots)
            if (mot.Equals(dernier)) yield break; // fin prématurée de l'itération
            else yield return mot; // élément de l'itération
        // fin normale de la boucle d'itération
    }
}

public class TestProgram
{
    public static void Main()
    {
        Mots fruits = new Mots( "pomme", "poire", "abricot", "fraise", "kiwi" );
        foreach( string fruit in fruits.TousLesMotsJusquA("fraise") )
            Console.WriteLine( fruit );
    }
}

Exemple en JavaScript modifier

Les générateurs sont apparus avec ES6 (en 2013).

function* fourInts() {
  let int = 0;
  while (int < 4) {
    yield int;
    int++;
  }
}

const gen = fourInts();   // création
alert(gen.next().value);  // 0
alert(gen.next().value);  // 1
alert(gen.next().value);  // 2
alert(gen.next().value);  // 3
alert(gen.next().value);  // undefined

Exemple en PHP modifier

Les générateurs sont apparus en PHP 5.5.0 (en 2013).

function fibonacci()
{
    $last = 0;
    $current = 1;
    yield 1;
    while (true) {
        $current = $last + $current;
        $last = $current - $last;
        yield $current;
    }
}

foreach (fibonacci() as $number) {
    echo $number, "\n";
}


Exemple en Python modifier

Les générateurs sont apparus sur la V2.2 en 2001.

Appeler la méthode next() d'un générateur exécutera la fonction et retournera une valeur. Le yield procède comme un return mais la fonction est liée à un générateur et le prochain appel de la méthode next() reprendra l'exécution là où elle en était[2].

def fonction(max):
    print('début fonction')
    for x in range(0, max+1):
        yield x
        print('incrémente x')

gen = fonction(2)
gen.next()
# début fonction
# 0
gen.next()
# incrémente x
# 1

NB : depuis Python 3.3, les générateurs peuvent aussi contenir des return[3].

Exemple en Ruby modifier

En Ruby, l'opérateur yield va entrainer l'exécution du bloc de code passé en paramètre :

def delimit
  puts "before yield"
  yield if block_given?
  puts "after yield"
end
delimit{ puts "in yield" } #=> "before yield\n" "in yield\n" "after yield\n"

Voir aussi modifier

Références modifier

  1. (en) « Python Generators to reduce RAM usage »
  2. (en) « The yield statement », sur documentation de python.org
  3. (en) « Generators and Iterators »