18 points par GN⁺ 2025-04-22 | 11 commentaires | Partager sur WhatsApp
  • Le pipelining est une fonctionnalité importante des langages de programmation qui améliore la lisibilité et la maintenabilité du code
  • C’est une manière de représenter naturellement le flux de données de gauche à droite et de haut en bas
  • Dans des langages comme Rust, le pipelining clarifie le flux du code et améliore la productivité des développeurs grâce à l’auto-complétion de l’IDE
  • Il est utilisé dans divers langages comme Haskell, Elm ou SQL, et les builder patterns ainsi que le method chaining peuvent aussi être considérés comme une forme de pipelining
  • Il a un impact positif sur la lisibilité, la facilité d’édition, le support des IDE et les outils de gestion de versions (diff, blame)
  • Il permet d’écrire un code plus concis et plus clair que l’imbrication de fonctions, ce qui le rend avantageux aussi pour la collaboration et la maintenance

Ma syntaxe de programmation préférée : le pipelining

Qu’est-ce que le pipelining ?

  • Une fonctionnalité qui permet d’omettre un argument dans la liste des paramètres en transmettant la valeur précédente
  • Cela améliore la lisibilité du code et facilite l’ajout de commentaires
  • Un style syntaxique centré sur les données qui applique séquentiellement une série d’opérations de traitement
  • Très utilisé dans le code de style fonctionnel sous forme de method chaining comme .map().filter().collect()
  • En Rust, le code suivant est un exemple représentatif :
    data.iter()  
        .filter(|w| w.alive)  
        .map(|w| w.id)  
        .collect()  
    
  • À l’inverse, si toutes les fonctions sont imbriquées, on obtient une structure qui doit être lue de l’intérieur vers l’extérieur :
    collect(map(filter(iter(data), |w| w.alive), |w| w.id))  
    

Pourquoi le pipelining est-il une bonne chose ?

  • 1. Lisibilité et maintenabilité

    • Facile à lire de haut en bas → un flux de données identique à l’ordre de lecture humain
    • Facile d’ajouter des commentaires à chaque ligne
    • Concis et clair sans imbrication de parenthèses sur de longues lignes
  • 2. Facilité d’édition

    • Il est facile d’ajouter une nouvelle fonction sur une ligne, par exemple .map()
    • Même dans git diff ou git blame, le suivi des changements reste propre et lisible
  • 3. Support IDE / LSP

    • La structure se prête bien à l’apparition d’une liste d’auto-complétion lorsqu’on appuie sur la touche .
    • Avantageux pour l’analyse statique, qui exige de connaître clairement les types
    • Pour que cette fonctionnalité marche correctement, le langage doit être basé sur un typage statique (p. ex. Rust, TypeScript)

Du pipelining aussi en SQL ?

  • Il existe une proposition visant à transformer les requêtes SQL à SELECT imbriqués en style pipeline
  • Exemple :
    FROM customer  
    |> LEFT OUTER JOIN orders ON ...  
    |> AGGREGATE COUNT(...) GROUP BY ...  
    |> ORDER BY ...  
    
  • Un flux plus clair et une meilleure lisibilité que le SQL existant
  • Inconvénient : si l’instruction SELECT remonte en haut, il peut devenir plus difficile d’identifier le type de retour → problème soluble

Lien avec le builder pattern

  • Une forme comme Builder::new().option().option().build() en Rust correspond à une structure pipeline typique
  • En composant des configurations optionnelles sous forme de méthodes, on facilite le suivi du code et la gestion des changements

Amélioration du pipelining en Haskell

  • Des opérateurs comme $, &, |> en Haskell permettent d’utiliser un pipeline au lieu de la composition de fonctions
  • Comparaison avant / après :
    -- 기존  
    checkPalindromes content = unlines $ map (show . isPalindrome) $ lines $ map toLower content  
    
    -- 개선  
    checkPalindromes content =  
      content  
        & map toLower  
        & lines  
        & map (show . isPalindrome)  
        & unlines  
    

Les avantages du pipelining en Rust

  • Le method chaining, l’inférence de types et l’extensibilité structurelle fondée sur les traits s’accordent très bien avec le pipelining
  • Rust semble ne retenir que les avantages des syntaxes fonctionnelle et orientée objet, ce qui rend l’usage du pipelining particulièrement naturel

Conclusion

  • Le pipelining n’est pas une simple syntaxe, mais une fonctionnalité clé qui influence le flux du code, l’éditabilité et même la collaboration
  • Au lieu d’une imbrication comme f(g(h(x))), une structure x |> h |> g |> f est plus adaptée aux humains
  • Sous la règle simple de « une opération par ligne », le pipelining est la meilleure manière d’exprimer un flux naturel

« Chaque segment du pipeline reçoit la donnée principale et exécute une seule tâche. Si on lui donne un nom clair à la fin, on obtient la structure de code idéale. »

11 commentaires

 
progdesigner 2025-04-23

Comme pour n’importe quel texte,
les retours à la ligne et l’indentation
semblent ici relever du même enjeu de lisibilité.

 
forgotdonkey456 2025-04-23

LINQ, c’est le top !

 
bus710 2025-04-23

Gleam le prend aussi en charge, donc on peut écrire du code de façon assez élégante.

Cela dit, comme il y a un bloc de code dans le corps de l’article, j’ai l’impression qu’il s’affiche aussi avec la mise en page desktop sur mobile.

 
bus710 2025-04-23

En y repensant, Elm le permet aussi.

 
galadbran 2025-04-22

Avec une petite quantité de données et un code simple comme dans l’exemple ci-dessus, je trouve que c’est agréable à lire et qu’il n’y a pas vraiment d’inconvénient.

Mais à mesure qu’on met un peu de code dans map()... le code a tendance à s’alourdir progressivement, et
selon le langage ou la bibliothèque d’implémentation, quand le volume de données augmente, cela peut facilement devenir des milliers de fois plus lent que de simplement accumuler ou manipuler les données dans une structure de données pour les traiter.

Et puis j’ai aussi une nouvelle raison de ne plus aimer ça : j’ai lu cet article sur mon téléphone, et comme la largeur de niveau PC était conservée telle quelle, la taille du texte est devenue minuscule, ce qui rendait l’article très difficile à lire T.T

Globalement, je n’aime pas ça, et je ne fais pas d’effort particulier pour écrire volontairement de cette manière.

 
bichi 2025-04-22

Donnez-moi aussi un peu de js |> suppliant, suppliant

 
secret3056 2025-04-22

|> est trop beau

 
howudoin 2025-04-22

C’est la syntaxe que je déteste le plus
Dès que la stack trace est un peu embrouillée, le débogage devient un cauchemar

 
cosine20 2025-04-25

Tellement vrai

 
GN⁺ 2025-04-22
Avis Hacker News
  • L’auteur appelle cela « pipelining », mais estime que le terme correct est plutôt « method chaining »

    • Comparaison avec un pipeline Bash simple : chaque composant s’exécute en parallèle et les résultats intermédiaires sont transmis en flux
    • En Ruby, chaque ligne est traitée séquentiellement et un tableau complet est créé entre chaque étape
    • Cela rend le débogage difficile, donc il écrit désormais du code plus explicite
    • Le code explicite paraît moins élégant, mais permet d’inspecter facilement les états intermédiaires
  • Personnellement, il est favorable à garder l’ensemble des fonctionnalités d’un langage réduit et à parvenir rapidement à un ensemble cohérent et complet

    • Cependant, il aimerait que toutes les langues adoptent la syntaxe |> d’Elixir
  • Les macros Lisp offrent une solution générale permettant de déterminer l’ordre d’une chaîne d’appels, et pas seulement pour les opérateurs chaînés sur des collections

    • Par exemple, on peut écrire (foo (bar (baz x))) sous la forme (-> x baz bar foo)
    • Cela fonctionne aussi lorsqu’il y a des arguments supplémentaires
    • Pour plus de détails, voir le guide des macros de threading de Clojure
  • J’ai appris ce terme sous le nom d’interface fluide. Le pipelining est autre chose

  • L’opérateur de pipeline est une forme d’application partielle, qui permet de lier plusieurs arguments pour créer une nouvelle fonction et d’en transmettre le résultat à une autre fonction

    • L’application partielle est très utile pour écrire des programmes, et un jour les langages (hors Haskell) l’utiliseront comme base de la composition des programmes
  • Les utilisateurs de tidyverse en R l’utilisent déjà

  • Le pipelining est difficile à déboguer. La gestion des exceptions est compliquée, ce qui oblige à ajouter des branches dans le pipeline

    • Le pipeline n’est utile que lorsqu’on programme le chemin heureux
  • La syntaxe SQL est inutilement complexe

    • SQL est déjà un langage d’opérateurs, mais il est très contraint pour des raisons historiques
    • Si l’on allait autoriser une nouvelle syntaxe, on pourrait écrire quelque chose de plus simple
    • La syntaxe |> manque d’expressivité et ajoute du bruit visuel
  • L’auteur affirme que « la sémantique l’emporte sur la syntaxe », mais se concentre en réalité sur des préférences syntaxiques

    • Le pipelining devient plus difficile à déboguer à mesure que la chaîne s’allonge
    • Il est critique envers Python, mais sans avancer de raisons concrètes
    • La définition de « pipelining » n’est pas claire
  • effect-ts permet d’écrire à la fois des pipelines et du code impératif

    • Une documentation est fournie sur l’écriture de pipelines et l’utilisation de générateurs
    • La majeure partie de la communauté a fini par préférer les générateurs dans un style impératif
    • Cela semble plus facile à déboguer et à maintenir