Cet article fait suite à Du bon usage de la compilation, premier plaidoyer pour la fréquente compilation des programmes par les étudiants, et à Pourquoi Scheme ?, essai de définition des qualités souhaitées d’un langage utilisé pour l’apprentissage.
Concision et cohérence de Scheme
Le langage Scheme, utilisé pour les articles de ce site et pour les enseignements auxquels ils correspondent, est défini par un document normatif connu sous le nom de R5RS, pour Revised5 Report on the Algorithmic Language Scheme, qui a le bon goût de tenir en 50 pages, à comparer aux centaines de pages de documents analogues pour d’autres langages, sinon des milliers en comptant les bibliothèques annexes. Cette concision de la définition de Scheme n’est pas une qualité anecdotique : elle procède de la clarté exceptionnelle des concepts qui ont présidé à sa création, et malgré cette parcimonie Scheme est un langage complet, même si l’on pourrait désirer le voir doté de quelques extensions, notamment pour permettre la compilation séparée de différents modules, ce que permettent certains compilateurs, mais hors de la norme.
Pour l’enseignant comme pour l’étudiant, la sobriété de Scheme est un avantage considérable : l’apprentissage en est raccourci d’autant, et surtout on ne passe pas des semaines à l’apprentissage d’une syntaxe biscornue et foisonnante. Comme l’a bien expliqué Matthias Felleisen, l’apprentissage de la syntaxe d’un langage est bien sûr une étape obligée, mais dépourvue de tout intérêt intellectuel, vers l’exercice de la programmation, il convient de la réduire au minimum. J’ai, ailleurs, un peu abordé cette question dans un article qui énumère certaines qualités souhaitables d’un langage utilisé pour l’apprentissage de la programmation.
Une question surgie au cours de la discussion pour la révision de la norme est la suivante (cf. ci-dessous) : l’évolution de Scheme a connu une époque où l’enjeu était d’écrire des compilateurs qui produisent du code exécutable aussi efficace que les langages procéduraux à la C/C++, et ce au prix du sacrifice partiel de certains aspects dynamiques du langage, comme call/cc ou l’absence de typage statique, voire eval ; cet enjeu est-il toujours pertinent ? Le succès de langages très dynamiques mais peu efficaces et incompilables comme Perl n’indique-t-il pas la voie de l’avenir ?
Place de Scheme parmi les langages
Scheme n’est certes pas le langage le plus répandu, et la question se pose de la place qui peut lui revenir entre, par exemple, C d’un côté, Java d’un autre et les langages de script (Perl-PHP-Python-Ruby) d’un troisième.
Lors du débat autour du R6RS, Tom Lord avait suggéré aux auteurs de traducteurs Scheme d’abandonner l’idée d’un langage aisément compilable au profit des aspects dynamiques du langage, qui pourraient même être amplifiés, par exemple en faisant des environnements et des fermetures des objets de première classe, susceptibles d’être nommés, passés en paramètres, affectés.
Joe Marshall lui avait répondu que le principal argument à l’encontre de cette extension des aspects dynamiques du langage n’était pas la perte d’efficacité, mais la perte d’intelligibilité. Selon lui (et j’adhère à son point de vue), il est utile de pouvoir attribuer une signification à un programme par un procédé plus prévisible que juste « lancer l’exécution et regarder ce qui se passe ». La signification doit être entendue ici comme le résultat de la traduction en langage machine du texte du programme. Dans cette perspective, certains traits du langage compliquent la sémantique, mais sont utiles, tandis que d’autres sont de nature à rendre complètement opaque la sémantique d’un programme. Ainsi, avec des environnements et des fermetures objets de première classe, n’importe quel élément de programme peut être modifié ou affecté à tout moment, ce qui interdit tout raisonnement sur le programme, puisque l’on en ignore la teneur jusqu’à l’exécution.
C’est exactement ce que fait un compilateur : il calcule un raisonnement d’après le texte d’un programme, et de ce raisonnement il infère une signification qu’il lui attribue. D’où il découle qu’un programme compilable est un programme sur lequel il est possible de tenir un raisonnement, que l’on soit compilateur ou humain. Cette qualité est précieuse, dans mes activités d’enseignement j’apprécie de pouvoir présenter à mes étudiants des textes de programmes auxquels je les invite à appliquer des raisonnements (et pour cet exercice Scheme est un excellent langage). Je ne vois pas très bien ce que pourrait être l’enseignement de la programmation en l’absence d’une telle possibilité.
À l’inverse, un programme que l’on ne peut pas compiler avoue par là être rétif au raisonnement que l’on pourrait tenter de lui appliquer ; cela ne veut pas dire que ce programme soit faux, ou inutile : mais il est difficile d’en dire quelque-chose de certain. Les auteurs qui se sont exprimés sur le sujet sont d’avis que si un compilateur est incapable de déterminer la signification d’un programme, il n’y a aucun espoir pour qu’un humain en soit capable.
C’est, à mon avis, ce qui rend difficile l’apprentissage de la programmation avec un langage tel que Perl, par ailleurs fort utile pour tout un tas d’usages.
Anton van Straaten poursuit la discussion en soulignant que l’un des moteurs du développement et de l’évolution de Scheme a été la recherche, et spécialement la recherche en compilation. « La recherche sur la relation entre le code source et le programme en exécution vise à élaborer des principes et des techniques de transformation de l’un en l’autre, dont une partie s’appelle “compilation”, et, oui, cet aspect des choses a été considéré comme important. »
Déception du R6RS
Une discussion est en cours actuellement pour la révision de la norme : le texte de la nouvelle version, baptisée R6RS, m’incline à la déception et à l’inquiétude ; s’il est désormais flanqué d’un document-frère consacré aux bibliothèques et si le nombre total de pages en est ainsi triplé, je n’y trouve que fort peu des extensions que je souhaitais et qui semblaient naturelles à tout praticien de la programmation, mais par contre la centaine de pages supplémentaires est pleine de subtilités byzantines dont l’intérêt n’est évident qu’aux yeux des clercs de la chapelle schemienne.
Bref, Scheme me semble menacé de perdre une de ses principales qualités pour ne rien gagner en échange. Pour citer Tom Lord, « une des forces de Scheme au long de son histoire a été de procurer une grande quantité de fonctions au moyen d’un petit nombre de mécanismes choisis avec parcimonie. » Il me semblerait précieux de pouvoir garder cette sobriété.