Développer, avec quel langage ?

Voici un article de 3 pages dans Programmez n°124 (nov 2009), rédigé pendant mon temps de travail chez Alter Way Solutions. Voici l'intro :

Un langage de programmation est un moyen, pas une fin. Pourtant, le choix d'un langage peut avoir des conséquences non négligeables sur la vie d'un projet, aussi bien au niveau technique qu'humain. Souvent, ce choix n'est d'ailleurs pas discuté : le langage est imposé, que ce soit par le développeur, le chef de projet, le projet lui-même, le client ou tout autre raison. Pourtant ce choix mérite qu'on s'y attarde un moment, étant donné la très grande diversité des langages existants. L'évolution des langages suit des modes à court terme et des tendances à plus long terme. On peut établir des classements selon de nombreux critères comme la syntaxe, le typage, le mode d'exécution ou le paradigme de programmation. Ces critères doivent vous guider lors de votre choix.

Je peux pas en mettre plus ici, mais vous pouvez télécharger un PDF (le minimag) qui contient les deux premières pages. Et si vous achetez le magazine, vous découvrirez en troisième page un magnifique classement qui place Python 1er, C++ 2ème et Haskell 3ème ! De quoi s'agit-il ? ;)


Texte original de l'article

Choisir un langage de programmation ?

Un langage de programmation est un moyen, pas une fin. Pourtant, le choix d'un langage peut avoir des conséquences non négligeables sur la vie d'un projet, aussi bien au niveau technique qu'humain. Souvent, ce choix n'est d'ailleurs pas discuté : le langage est imposé, que ce soit par le développeur, le chef de projet, le projet lui-même, le client ou tout autre raison.  Pourtant ce choix mérite qu'on s'y attarde un moment, étant donnée la très grande diversité des langages existants.  L'évolution des langages suit des modes à court terme et des tendances à plus long terme. On peut établir des classements selon de nombreux critères comme la syntaxe, le typage, le mode d'exécution ou le paradigme de programmation. Ces critères doivent vous guider lors de votre choix.

Paradigme de programmation

Les paradigmes de programmation font l'objet de très nombreuses variantes. Les trois grandes catégories les plus utilisées sont la programmation procédurale (typiquement le C), la programmation objet (Java, Python, Objective C) et la programmation fonctionnelle (Haskell, Erlang).  Certains langages, qui n'étaient pas objets, ont évolué progressivement pour le devenir (Perl ou PHP), certains l'étaient dès la conception (Ruby), certains imposent même ce mode (Java), et d'autres peuvent être utilisés selon plusieurs paradigmes (Scala, Python). La programmation objet s'est aujourd'hui généralisée et permet de haut niveaux d'abstraction. La programmation fonctionnelle revient progressivement à la mode avec des langages comme Erlang ou Haskell, du fait de la globalisation des applications et le cloud computing : ces langages sont idéaux pour créer des applications distribuées sur une grande quantité de nœuds et conserver la cohérence des données sans nécessiter de communication entre les nœuds.

La syntaxe

La syntaxe est le critère le plus visible pour le développeur et donne lieu à de nombreux débats. Ces débats ne sont pas stériles car la lisibilité d'un langage est cruciale pour la maintenance d'un programme et son évolution à moyen et long terme.  De très nombreux langages, comme le PHP ou le Java, ont une syntaxe héritée de celle du C qui, si est familière à une majorité de développeurs, n'est pourtant pas la plus lisible ni la plus concise. D'autres langages comme Python sont, de ce point de vue, fortement expressifs et mènent à des programmes plus courts. Le Perl, par contre, est réputé pour son manque de lisibilité. Les langages fonctionnels ont généralement une syntaxe un peu déroutante si on vient des langages procéduraux ou objets, mais on s'y habitue assez vite.

Typage

Coté typage, on distingue le typage statique, ou les variables ont un type défini une fois pour toute du typage dynamique où les variables peuvent changer de type pendant l'exécution. Le typage peut également être fort ou faible. Un typage fort impose plus de contraintes sur les variables mais peut offrir plus de garanties avant l'exécution. Les conversions implicites entre types y sont par exemple interdites.

Vitesse et mode d'exécution

Concernant le mode d'exécution, les deux grandes catégories sont les langages compilés (exécutés directement par le processeur), et les langages interprétés ou fonctionnant sur une machine virtuelle c'est à dire la plupart des langages dynamiques. Là, le combat se fait entre rapidité d'exécution et rapidité de développement. L'augmentation exponentielle de la vitesse des processeurs fait qu'il devient possible de tout développer avec un langage interprété. Comme le temps du processeur coûte beaucoup moins cher que le temps du développeur, il est beaucoup plus intéressant d'utiliser un langage hautement expressif comme Ruby, Python ou Scala plutôt que du C ou du C++. Si certaines routines du programme ont besoin d'être très rapides, rien n'interdit de réécrire juste ces routines dans un langage compilé comme le C. Il faut aussi comprendre que les bibliothèques natives fournies avec les langages peuvent être extrêmement rapides car écrites elle-mêmes en C. En Python, l'utilisation de la bibliothèque NumPy permet par exemple de faire des calculs numériques complexes extrêmement rapides sur des matrices potentiellement énormes, avec très peu de lignes de code. Réimplémenter ces algorithmes de calcul soi-même en C est une très mauvaise idée et peut même être plus lent et plus gourmand en mémoire.

Gestion de la mémoire

La gestion de la mémoire est une tâche ingrate et difficile, source de nombreux problèmes. La majorité des langages modernes, y compris des langages comme l'Objective C, embarquent un garbage collector, qui se charge de libérer automatiquement la mémoire correspondant aux variables ou objets qui ne sont plus utilisés. La gestion manuelle de la mémoire, nécessaire dans des langages comme le C ou le C++ à moins d'utiliser un garbage collector additionnel, est risquée, gourmande en temps de développement et ne se justifie aujourd'hui que pour les plateformes embarquées ou l'écriture d'algorithmes hautement optimisés.

Multiplateforme

Aujourd'hui il n'est plus possible de ne raisonner que pour Windows.  La croissance fulgurante des plateformes mobiles de type Android ou iPhone, l'universalité des applications web et le développement des systèmes Mac Os X et Linux imposent de réfléchir au caractère multiplateforme des applications le plus tôt possible.  Heureusement, la plupart des langages modernes dynamiques sont capables de fonctionner quasiment partout à condition de prendre un minimum de soin. Ainsi, le « Write once, run everywhere » n'est pas réservé à Java, mais s'applique à la plupart des langages dynamiques modernes.

Sécurité

Le choix du langage et du mode de développement peut influencer la qualité des programmes. Les langages compilés à typage statique fort sont beaucoup plus contraignants et vont avertir le développeur très tôt des failles potentielles, mais ne préviendront pas des erreurs de conception ou de logique.  Les langages fonctionnels comme le Haskell offrent des avantages intrinsèques supplémentaires grâce à la notion de pureté des fonctions (des fonctions dont le résultat ne dépend d'aucune variable globale ou environnementale). Avec les langages à typage dynamique faible, la stratégie utilisée est d'accorder la plus grande importance aux tests, au point d'aboutir à du développement dirigé par les tests : on écrit d'abord les tests correspondant au résultat qu'on souhaite obtenir, puis seulement ensuite l'implémentation. Si les tests passent, le programme est considéré comme correct. Si un problème est détecté, on écrit d'abord un test (unitaire ou fonctionnel) correspondant au problème, puis on corrige le programme. On peut étendre ce principe à la documentation, comme ce qui est pratiqué en Python avec la notion de « doctest » : un mélange de test et de documentation, qu'on peut écrire dès la phase de conception. Des outils de test et de sécurité en ligne de commande existent également en PHP (PHPUnit, PHP_CodeSniffer).

Licence

Un langage en soi n'est pas soumis à une licence, mais les outils le sont, c'est à dire les compilateurs, les interprètes, les bibliothèques et tout ce qui fait vivre un langage. Prenez toujours le temps de lire le petit texte juridique qui accompagne les outils que vous utilisez car il arrive qu'on ait des surprises. Les outils et bibliothèques de base du langage ne devrait imposer aucune contrainte sur les programmes réalisés. C'est le cas pour la quasi-totalité des langages issus du milieu de l'open-source, qui vous permettent de créer aussi bien des logiciels libres que des logiciels propriétaires. Les notions de copyleft applicables portent sur les outils eux-mêmes, pas sur les programmes que vous développez.

Type de projet

Chaque langage a ses domaines de prédilection. Ceux dans lesquels ils peuvent être utilisés dépendent en grande partie de la richesse de ses bibliothèques. Python est connu pour être « fourni avec les piles », c'est-à-dire que sa bibliothèque standard permet d'origine de tout faire. Des bibliothèques additionnelles autorisent le développement de grosses applications scientifiques, calcul numérique, visualisation 2D ou 3D, interfaces graphiques. Il est également utilisé depuis plus de dix ans pour le développement web orienté objet. Java est également très riche de ce point de vue et peut être utilisé pour tout projet. Le PHP n'est à l'aise que pour des applications web mais possède une visibilité et une communauté énormes. Perl et Ruby sont tout autant généralistes et utilisés également dans de nombreux domaines. Ruby, très utilisé au Japon, s'est fait surtout connaître en Europe via son framework web Ruby On Rails, dont les équivalents PHP et Python se nomment Symfony, Zend Framework, Pylons ou Django.  Dans le monde mobile, on retrouve l'Objective C sur l'iPhone, et le Java sur Android.  Des langages spécialisés existent aussi pour des domaines très précis, comme comme le « R » ou le « S » pour les calculs statistiques. Le C# est lui aussi généraliste, mais reste assez lié à Windows même s'il existe des implémentations libres (Mono) sous Linux.

Écosystème, communauté

Outre la qualité et la quantité des outils et des bibliothèques, il faut aussi veiller à la taille de la communauté. Il est intéressant de choisir un langage soutenu par une grosse communauté de personnes ou d'entreprises.

Il peut aussi être intéressant de suivre les tendances. Plusieurs indicateurs existent, comme l'index TIOBE, qui donne dans l'ordre pour Octobre 2009 : Java, C, PHP, C++, Basic, C#, Python, Perl, Javascript et Ruby.  Le graphique ci-dessous correspond au nombre de personnes connectées aux canaux IRC correspondant à chacun des langages (un mardi vers 17h30). Ce n'est pas représentatif des parts de marché, mais c'est un indicateur comme un autre qui montre l'intérêt des développeurs pour les langages.

Conclusion

Le meilleur langage est en pratique celui que vous maîtrisez ou que l'équipe connaît. Car c'est avec celui-ci que le travail sera effectué le plus rapidement. Néanmoins, en tant que développeur, et même si certains langages permettent de tout faire et d'aller très vite, il est vital de maîtriser plusieurs technologies. En acquérant de bonnes notions de développement objet et de développement fonctionnel, vous serez à même d'aborder n'importe quel problème sous le meilleur angle possible. En maîtrisant un langage dynamique interprété et un langage bas niveau compilé, vous bénéficierez à la fois de la vitesse de développement et de la vitesse d'exécution si besoin. Quant au choix final, si comme vous l'aurez compris ma préférence va à Python, mon meilleur conseil est de se forcer à apprendre un nouveau langage régulièrement, vous n'aurez que l'embarras du choix. Et vive la diversité !

Christophe Combelles
Consultant,
Responsable du centre de compétence Python
Alter Way Solutions