Histoire des simplifications dans les langages de programmation

Programmer plus vite et plus sûrement alors que les domaines d'applications évoluent, nécessite une évolution des langages de programmation.

Le langage C a été conçu pour écrire un système d'exploitation, donc pour utiliser directement le matériel. C'est pourquoi les types, comme int ou le pointeur de chaîne correspondant à la structure de la mémoire.
C veut décomposer les opérations au détriment du travail imposé au programmeur et est conçu en fait pour des logiciels critiques où le travail d'écriture n'est rien comparé aux difficultés du traitement et son optimisation.
C convient parfaitement pour les réaliser les programmes pour lesquels il a été conçu. Là où les choses tournent mal, c'est lorsque les créateurs de nouveau langages, initiés à C, et qui réalisent un compilateur en C, se croient obligé de reprendre la syntaxe de ce langage système même si les applications de ce nouveau langage n'on rien à voir avec le système et ne nécessitent aucunement ce type de syntaxe. C'est le cas de C++, un langage d'application conçu comme un langage système, et aussi de ceux qui lui ont succédé comme Java et C#.

Il y a toujours eu une résistance de la part des programmeurs envers la simplification des langages, leur outil de travail, auquel ils sont attachés. John von Neumann, l'inventeur des ordinateurs, lorsqu'on lui a présenté Fortran (1954), a eu cette réaction:

"Why would you want more than machine language?"
(Pourquoi voudrait-on autre chose que le langage machine?)

Lorsque l'assembleur est apparu, moins d'1% des programmeurs voulaient l'utiliser de préférence au langage machine, on le considérait comme un joujou pour fillette. (Source: References for "The future of Programming")

Aussi les innovations doivent-elle être imposées dans le but d'écrire le code le plus simple, pour faire le plus avec le moins de lignes. Heureusement, des créateurs ont su faire adopter de nouveaux langages et ont profité de l'occasion pour simplifier la syntaxe et le fonctionnement général. Nous allons voir quels genres de simplifications ont pu être trouvées, dans une liste qui n'est surement pas exhaustive.

Universalisation de l'objet

Dans Smalltalk (1970), toute chose est un objet. Il en est de même dans Scala. Cela permet d'hériter attributs et méthodes de toute chose et donc de réduire les déclarations.

Le principe des objets tels que conçu pour Smalltalk n'a pas été très bien compris dans les autres langages et notamment C++. On ne peut pas dire qu'ils simplifient vraiment les programmes. Mais ils aident à réutiliser le code et c'est déjà un progrès. Scala a fait mieux comme on va le voir.

Des boucles et pas des noeuds

Python (1991) a popularisé le for in avec des tableaux, ce qui est hérité de Gap (1986) et aussi les "ranges", hérités du langage Icon (1970).
On peut scanner un tableau, ou une collection qui est une catégorie d'objet.

for i in x
   ...

D'une façon générale, la syntaxe de Python facilite la programmation et aussi la lecture d'un programme, un aspect dont l'importance a été négligée dans C++ (toujours la question du joujou pour fillette).

Des objets encore plus universels

Dans JavaScript (1995), une fonction est aussi un objet. D'ailleurs la syntaxe est la même que pour un tableau associatif. Ce qui diffère de Smalltalk, outre le coté dynamique, est que l'on reprend les éléments classiques des langages procéduraux tels que fonction, tableau, objet pour en faire une unique entité du langage. Une fonction peut donc contenir d'autres fonctions et on peut scanner les attributs d'un objet...

Traitements et données unifiés

PHP (1995) a apporté des simplifications quelque fois plus gênantes qu'avantageuses. Par exemple, un tableau utilise les indices numériques comme des clés, et c'est une source de confusion.
Mais dans la problématique de l'unification des traitements et données, il a fait un pas. Ainsi le code PHP s'intègre dans un document, il se mêle aux données, mais il génère aussi le contenu de ce même document. JavaScript fait la même chose mais de façon dynamique.

Un switch universel

Dans Scriptol (2001) on peut faire un switch avec tout opérateur et tous types de données.

switch x
  < 10 : ...
  = 15 : ...
  else ...

La syntaxe de la boucle while intègre l'incrémentation, ainsi on ne risque pas d'entrer dans une boucle sans fin. Quelque chose de similaire a été implémenté dans des langages plus anciens.

x = 0
while x < 10
   ...
let x + 1

Des classes encore plus simples

Dans Scala (2004), on déclare une classe et son constructeur avec le même en-tête. Scala se targue d'écrire du code cinq fois plus compact que Java pour la même machine virtuelle, et c'est vrai grâce à ce genre de simplication.
On peut faire du pattern-matching avec des classes ce qui étend encore plus le swith ... case.
Une simplification plus subtile est la possibilité de créer un système d'échanges dans Scala en définissant des acteurs et les messages auxquels ils réagissent. Cela facilite la création des programmes à un niveau plus général.

La concurrence simplifiée

Dans Go (2009), on lance des tâches concurrentes comme de simples fonctions. Cela facilite la création d'application Web où la concurrence est essentielle, et est plus simple que JavaScript et la programmation par évènements.

Et ensuite?

Des langages nouveaux ont pu devenir populaires grâce aux simplifications qu'ils ont su intégrer. Il n'y a pas de raison que cette évolution s'arrête.

Quelques idées pour améliorer encore les langages...

Si vous avez d'autres idées, n'hésitez pas à les donner en commentaires....

Voir aussi: