On va enfin enseigner l’informatique dans le secondaire
En marchant à reculons, l’Éducation nationale semble enfin accepter l’idée qu’aujourd’hui un enseignement secondaire sans informatique n’est plus concevable. Et qu’il s’agit bien de la science informatique, pas des usages d’outils divers et variés réalisés au moyen de techniques informatiques. Comme Gérard Berry l’a signalé lors de son intervention au congrès de la Société informatique de France de 2018, il serait temps : déjà le rapport remis en 1984 à Laurent Fabius, à la rédaction duquel il avait collaboré sous la direction de Maurice Nivat, soulignait que la France était en retard pour l’introduction d’un tel enseignement, dont les premières expérimentations remontent au début des années 1970. Notons au passage que la plupart des recommandations de ce rapport, toujours d’actualité, n’ont toujours pas été mises en œuvre.
Pour faire de l’informatique, il faut des langages de programmation
Enseigner l’informatique comporte forcément l’apprentissage de la programmation, et pour cela il faut choisir un langage de programmation.
Au fil des ans j’ai vu prôner pour cet usage quantité de langages, de Fortran à Javascript en passant par Basic, C++, Perl, APL et Cobol. De mon expérience j’ai retenu deux langages particulièrement propices à l’enseignement, pour des raisons que je me propose d’exposer ci-dessous : Turbo Pascal et Scheme. D’autres choix sont plus ou moins raisonnables. Aujourd’hui on n’entend plus parler que de Python, dont Gérard Berry, toujours au congrès de la SIF, soulignait l’appartenance, avec ses cousins Perl, PHP et Javascript, à une famille de langages qui avaient jeté par-dessus bord les acquis de 50 ans de recherche en théorie et pratique des langages de programmation, par exemple par l’abandon de techniques de typage des données propres à éviter de nombreux bugs.
Le choix d’un langage pour enseigner la programmation exige un certain soin, parce que les progrès des étudiants et la qualité de leur apprentissage en dépendent pour une part.
Sept critères de choix du langage
Après avoir enseigné une demi-douzaine de langages, de l’assembleur 360 à Scheme, en avoir parlé pendant des heures avec des collègues, et avoir lu des centaines de pages sur le sujet, les critères de choix d’un langage pour l’enseignement de la programmation à des débutants me semblent être les suivants (sans prétention à l’exhaustivité) :
- Le langage doit être suffisamment simple pour que le débutant puisse assez vite en avoir une vue d’ensemble, et soit capable d’écrire des programmes simples de façon autonome ; la locution « assez vite » a son importance pédagogique, cf. plus bas ;
- un élément important de cette simplicité réside dans la syntaxe du langage, dont les qualités essentielles me semblent être la sobriété, la régularité et l’expressivité [1] ; comme l’a souligné Matthias Felleisen, l’apprentissage de la syntaxe est du temps perdu, parce que cela ne présente aucun intérêt, il convient donc qu’il soit réduit au minimum ; de plus, la clarté de la syntaxe confère aux programmes (ou permet de leur conférer, en tout cas) une qualité essentielle : la lisibilité ;
- le niveau d’abstraction doit être suffisant pour que le débutant ne soit pas d’emblée contraint de comprendre le fonctionnement du système d’exploitation et du processeur sous-jacents, compréhension hors de sa portée tant qu’il n’a pas acquis quelque expérience de la programmation ;
- mais le niveau d’abstraction ne doit pas non plus être excessif, ce qui serait un obstacle à l’acquisition des mécanismes fondamentaux : si la recherche dans une table, le tri ou la manipulation d’une table associative sont des primitives du langage, il est impossible d’apprendre à les programmer, or cet apprentissage est fondamental ;
- du point précédent découle que l’apprentissage de la programmation avec des objets pourra compléter l’apprentissage de la programmation procédurale, mais ne pourra pas s’y substituer : la programmation procédurale et la programmation récursive sont des compétences fondamentales et indispensables à qui veut se proclamer informaticien, ou bio-informaticien [2] ;
- c’est un détail technique, mais il a son importance : le langage doit posséder un système de gestion automatique de la mémoire, de préférence un glaneur de cellules (garbage collector) ; gérer l’allocation dynamique de mémoire est une complication dont il est bon de faire l’économie au début, il y a bien assez de choses à apprendre avec le reste ;
- enfin, le langage doit pouvoir être compilé : avec les langages uniquement interprétés, le débutant a trop de mal à distinguer les objets créés par son programme de ceux qu’il trouve dans l’environnement de l’interprète, et ne peut guère se former une représentation du programme comme un objet distinct, physiquement et logiquement. Cette question de la compilation fait l’objet de deux autres articles, un pour suggérer qu’en soit développé l’usage, l’autre pour expliquer en quoi elle est un critère d’intelligibilité des programmes.
Pourquoi cela ne doit pas prendre trop de temps ?
Que l’apprentissage du langage demande le triple de temps a des répercussions qui ne se bornent pas à l’emploi du temps et aux réservation de salles : les efforts intellectuels devront être soutenus trois fois plus longtemps, le délai entre le moment où l’on se posera une question et celui où l’on obtiendra la réponse sera trois fois plus long, etc.
En programmation procédurale, comme en programmation récursive, il est assez facile d’exposer aux étudiants un modèle de l’environnement et un modèle de la mémoire, ce qui leur donne accès à l’intuition de l’endroit où sont les données qu’ils créent et qu’ils manipulent. Avec le modèle objet c’est beaucoup plus difficile, à la limite il faudrait leur apprendre en plus UML, mais je crains que cela ne fasse exploser le budget horaire, et il n’est d’ailleurs rien moins que certain qu’UML donne une représentation convenable de la mémoire pour un système d’objets.
Pour apprendre C il faut déjà savoir programmer
Ada est un fort beau langage, dont la syntaxe a bien des qualités, mais l’étendue des connaissances à posséder pour commencer à voler de ses propres ailes est telle que bien des étudiants auront perdu pied avant de pouvoir se raccrocher à l’exercice pratique de la programmation, qui permet de reprendre de l’assurance.
Le langage C est indispensable au paquetage de l’informaticien en campagne, mais de trop bas niveau, c’est-à-dire trop proche du système et du matériel, pour le débutant, qui de par son état n’est pas encore en mesure d’en comprendre le fonctionnement. De surcroît, la syntaxe de C semble faite pour décourager l’apprentissage. Combien de biologistes n’ai-je pas vus, obligés de programmer en C sans maîtriser le langage, et de ce fait entraînés par des courants pleins de traîtrise vers des bancs de sable où ils s’échouaient sans recours ?
Pourquoi pas Java ?
Aujourd’hui le leitmotiv c’est « Pourquoi pas Java ? » Ma réponse est simple : Java est un langage raisonnable pour l’enseignement initial de la programmation, il répond (avec plus ou moins de bonheur) à la liste de critères énumérés ci-dessus. Aujourd’hui, le cours d’initiation à la programmation, basé sur Scheme, comporte 30 heures de cours et 30 heures de TP, à l’issue desquelles les élèves arrivent à écrire des programmes simples. Si nous devions faire le même cours avec Java, pour atteindre le même résultat il nous faudrait le triple, soit 180 heures au total. Pourquoi ? Parce que :
– Java est un langage plus complexe que Scheme, pour l’apprendre il faut acquérir en parallèle ses aspects procéduraux et ses aspects objet, ce qui n’est pas simple pour un débutant ;
– la syntaxe de Java est assez punitive ;
– les environnements de développement comme Eclipse, les bibliothèques de classes toutes faites sont formidables pour les gens qui savent déjà programmer, pour des débutants il s’agit d’une masse de choses supplémentaires à maîtriser, cela ne fait que charger la barque.
Consistance de la syntaxe et de la sémantique
Parmi les qualités que je trouve à Scheme, je citerai celle qui peut être commodément résumée par un aphorisme de John Foderaro : Lisp (dont Scheme est une variante) est un langage de programmation programmable. Un programme Lisp est un objet du langage Lisp. Cela pourrait sembler anodin, mais évacue toute une série d’aspects arbitraires dans la syntaxe, et confère à ce que l’on écrit la dimension de la nécessité ; pour écrire en Scheme (en Lisp), il est nécessaire de savoir ce que l’on écrit, il est impossible d’entamer une boucle sans bien savoir ce que l’on va lui faire faire, juste pour commencer et « on verra bien ce que ça fait ». Il est bien sûr possible d’écrire en Scheme, comme en tout autre langage, des programmes laids, faux, ou les deux, mais il est beaucoup plus difficile d’écrire un programme incohérent.
En relisant ces dernières lignes, je m’aperçois que l’on pourrait dire la même chose d’Ada : un argument classique (et véridique) des partisans de ce langage est que s’il est souvent plus laborieux de rédiger un programme syntaxiquement correct en Ada qu’en tel ou tel autre langage, une fois ce résultat obtenu, il y a beaucoup moins d’erreurs à l’exécution. Mais justement, Ada atteint ce résultat par de tout autres moyens que Scheme, par l’empilement de couches de contrôle dont la lourdeur et la complexité font la difficulté de la programmation (et de l’écriture de compilateurs !), là où Scheme se contente d’une idée, pourrait-on dire, celle déjà citée plus haut : un programme Lisp est un objet du langage Lisp.