D'un point de vue pratique, les combinateurs sont des sortes de constructions de programmation qui vous permettent de rassembler des éléments de logique de manière intéressante et souvent avancée. Leur utilisation dépend généralement de la possibilité de pouvoir intégrer du code exécutable dans des objets, souvent appelés (pour des raisons historiques) des fonctions lambda ou des expressions lambda, mais votre kilométrage peut varier.
Un exemple simple de combinateur (utile) est celui qui prend deux fonctions lambda sans paramètres et en crée un nouveau qui les exécute en séquence. Le combinateur actuel ressemble à ceci dans le pseudocode générique:
func in_sequence(first, second):
lambda ():
first()
second()
La fonction cruciale qui en fait un combinateur est la fonction anonyme (fonction lambda) sur la deuxième ligne. quand vous appelez
a = in_sequence(f, g)
L'objet résultant a n'est pas le résultat de l'exécution de f (), puis de g (), mais il s'agit d'un objet que vous pouvez appeler ultérieurement pour exécuter f () et g () dans l'ordre:
a() // a is a callable object, i.e. a function without parameters
Vous pouvez également avoir un combinateur qui exécute deux blocs de code en parallèle:
func in_parallel(first, second):
lambda ():
t1 = start_thread(first)
t2 = start_thread(second)
wait(t1)
wait(t2)
Et puis encore
a = in_parallel(f, g)
a()
La bonne chose est que 'in_parallel' et 'in_sequence' sont tous deux des combinateurs du même type / signature, c'est-à-dire qu'ils prennent tous deux deux objets fonction sans paramètre et en renvoient un nouveau. Vous pouvez alors écrire des choses comme
a = in_sequence(in_parallel(f, g), in_parallel(h, i))
et cela fonctionne comme prévu.
En résumé, les combinateurs vous permettent de construire (entre autres choses) le flux de contrôle de votre programme de manière souple et procédurale. Par exemple, si vous utilisez un combinateur in_parallel (..) pour exécuter le parallélisme dans votre programme, vous pouvez ajouter un débogage associé à cela à la mise en œuvre du combinateur in_parallel lui-même. Plus tard, si vous pensez que votre programme a un bogue lié au parallélisme, vous pouvez simplement réimplémenter in_parallel:
in_parallel(first, second):
in_sequence(first, second)
et d'un coup, toutes les sections parallèles ont été converties en séquences séquentielles!
Les combinateurs sont très utiles lorsqu'ils sont utilisés correctement.
Le combinateur Y, cependant, n'est pas nécessaire dans la vie réelle. C'est un combinateur qui vous permet de créer des fonctions auto-récursives que vous pouvez facilement créer dans n'importe quelle langue moderne sans le combinateur Y.