Programmation ascendante

1993

(Cet essai est tiré de l'introduction deOn Lisp .)

C'est un principe de style de programmation établi de longue date que les éléments fonctionnels d'un programme ne doivent pas être trop volumineux. Si un composant d'un programme dépasse le stade où il est facilement compréhensible, il devient une masse de complexité qui dissimule les erreurs aussi facilement qu'une grande ville dissimule les fugitifs. Un tel logiciel sera difficile à lire, difficile à tester et difficile à déboguer.

Conformément à ce principe, un grand programme doit être divisé en morceaux, et plus le programme est grand, plus il doit être divisé. Comment diviser un programme ? L'approche traditionnelle est appelée conception descendante (ou top-down design) : vous dites « le but du programme est de faire ces sept choses, donc je le divise en sept sous-routines majeures. La première sous-routine doit faire ces quatre choses, donc elle aura à son tour quatre de ses propres sous-routines », et ainsi de suite. Ce processus se poursuit jusqu'à ce que l'ensemble du programme ait le bon niveau de granularité – chaque partie étant suffisamment grande pour faire quelque chose de substantiel, mais suffisamment petite pour être comprise comme une unité unique.

Les programmeurs Lisp expérimentés divisent leurs programmes différemment. En plus de la conception descendante, ils suivent un principe que l'on pourrait appeler conception ascendante (ou bottom-up design) -- modifier le langage pour l'adapter au problème. En Lisp, vous n'écrivez pas seulement votre programme vers le langage, vous construisez également le langage vers votre programme. Pendant que vous écrivez un programme, vous pouvez penser « j'aimerais que Lisp ait tel ou tel opérateur ». Alors vous allez l'écrire. Ensuite, vous réalisez que l'utilisation du nouvel opérateur simplifierait la conception d'une autre partie du programme, et ainsi de suite. Le langage et le programme évoluent ensemble. Comme la frontière entre deux États en guerre, la limite entre le langage et le programme est tracée et retracée, jusqu'à ce qu'elle se stabilise finalement le long des montagnes et des rivières, les frontières naturelles de votre problème. Au final, votre programme aura l'air d'avoir été conçu pour le langage. Et lorsque le langage et le programme s'adaptent bien l'un à l'autre, vous obtenez un code clair, petit et efficace.

Il est important de souligner que la conception ascendante ne signifie pas simplement écrire le même programme dans un ordre différent. Lorsque vous travaillez de manière ascendante, vous obtenez généralement un programme différent. Au lieu d'un programme unique et monolithique, vous obtiendrez un langage plus vaste avec des opérateurs plus abstraits, et un programme plus petit écrit dans ce langage. Au lieu d'un linteau, vous obtiendrez une arche.

Dans le code typique, une fois que vous avez abstrait les parties qui ne sont que de la gestion (ou « bookkeeping »), ce qui reste est beaucoup plus court ; plus vous construisez le langage vers le haut, moins vous aurez de distance à parcourir de haut en bas. Cela présente plusieurs avantages :

  1. En faisant en sorte que le langage fasse plus de travail, la conception ascendante produit des programmes plus petits et plus agiles. Un programme plus court n'a pas besoin d'être divisé en autant de composants, et moins de composants signifie des programmes plus faciles à lire ou à modifier. Moins de composants signifie également moins de connexions entre les composants, et donc moins de risques d'erreurs à cet endroit. Tout comme les designers industriels s'efforcent de réduire le nombre de pièces mobiles dans une machine, les programmeurs Lisp expérimentés utilisent la conception ascendante pour réduire la taille et la complexité de leurs programmes.

  2. La conception ascendante favorise la réutilisation du code. Lorsque vous écrivez deux programmes ou plus, de nombreux utilitaires que vous avez écrits pour le premier programme seront également utiles dans les suivants. Une fois que vous avez acquis un large substrat d'utilitaires, écrire un nouveau programme ne peut prendre qu'une fraction de l'effort qu'il faudrait si vous deviez commencer avec du Lisp brut.

  3. La conception ascendante rend les programmes plus faciles à lire. Une instance de ce type d'abstraction demande au lecteur de comprendre un opérateur à usage général ; une instance d'abstraction fonctionnelle demande au lecteur de comprendre une sous-routine à usage spécial. [1]

  4. Parce qu'elle vous pousse à toujours rechercher des motifs dans votre code, travailler de manière ascendante aide à clarifier vos idées sur la conception de votre programme. Si deux composants éloignés d'un programme sont de forme similaire, vous serez amené à remarquer la similitude et peut-être à repenser le programme d'une manière plus simple.

La conception ascendante est possible dans une certaine mesure dans des langages autres que Lisp. Chaque fois que vous voyez des fonctions de bibliothèque, la conception ascendante est à l'œuvre. Cependant, Lisp vous donne des pouvoirs beaucoup plus étendus dans ce domaine, et l'augmentation du langage joue un rôle proportionnellement plus important dans le style Lisp – à tel point que Lisp n'est pas seulement un langage différent, mais une toute autre façon de programmer.

Il est vrai que ce style de développement est mieux adapté aux programmes qui peuvent être écrits par de petits groupes. Cependant, en même temps, il étend les limites de ce qui peut être fait par un petit groupe. Dans The Mythical Man-Month, Frederick Brooks a proposé que la productivité d'un groupe de programmeurs ne croît pas linéairement avec sa taille. À mesure que la taille du groupe augmente, la productivité des programmeurs individuels diminue. L'expérience de la programmation Lisp suggère une manière plus optimiste de formuler cette loi : à mesure que la taille du groupe diminue, la productivité des programmeurs individuels augmente. Un petit groupe gagne, relativement parlant, simplement parce qu'il est plus petit. Lorsqu'un petit groupe profite également des techniques que Lisp rend possibles, il peut gagner purement et simplement.

Nouveau : Téléchargez On Lisp gratuitement.


[1] « Mais personne ne peut lire le programme sans comprendre tous vos nouveaux utilitaires. » Pour comprendre pourquoi de telles affirmations sont généralement erronées, voir la Section 4.8.