Mes commentaires et critiques, sur 20 langages de programmation
Voilà quelques remarques, commentaires et critiques sur une vingtaine de langages. Je ne prétends pas être exhaustif ou neutre. Pour plus de détails, je vous renvoie sur les sites officiels des langages.
Ada
Ce langage au typage statique très fort, a une syntaxe inspirée de Pascal. Mais cette syntaxe est inutilement verbeuse, lourde et peu agréable. Contrairement à celle de Perl, elle privilégie des mots anglais aux symboles. On retrouve le "begin" "end" de Pascal en pire :il faut répéter le nom de la fonction ou de la structure de contrôle au niveau du "end" : "end my_function", "end for", "end if". De plus,le bloc est obligatoire, même lorsqu'il n'y a qu'une instruction dedans. Au final, Ada ressemble à une caricature de Pascal. Je me suis d'ailleurs toujours demandé comment les gens pouvaient lire du code Ada sans s'endormir.
Mais Ada a quand même la qualité du typage statique fort, qui détecte un grand nombre d'erreurs à la compilation. On apprécie aussi les range (intervalle de valeurs, pour les entiers), avec toutes les vérifications autour. Au nom de la sécurité, on trouve aussi 4 types de strings. Cela devient vraiment contraignant, et incite à toujours utiliser le même, pour des raisons de simplicité.
Alice
Alice est un langage de programmation fonctionnel de la famille de
ML. On y trouve de l'évaluation paresseuse, de la programmation
concurrente et de la programmation par contraintes. Il y a des
primitives assez sympa. Par exemple, le mot-clé spawn permet
d'effectuer un calcul dans un thread distinct, ce qui permet de
continuer le déroulement du programme. Et au moment où on a besoin du résultat du calcul, le programme principal attend que le thread ait
fini, de manière complètement transparente.
Le langage est en grande partie compatible avec le Standard ML, on a
donc bien sûr, du typage fort, statique, de l'inférence de type et du
pattern matching. C'est un langage original, qui m'a l'air assez
sympa.
Anubis
Anubis est un langage fonctionnel français reposant sur de profondes
bases mathématiques. Il ne fait pas partie de la famille ML et s'en
démarque par plusieurs aspects, notamment l'absence d'inférence de
type. Le langage se veut également beaucoup plus sûr : il est conçu de
telle manière que, lors de pattern matching, il y a un et un seul
motif qui peut correspondre. Le langage supporte la programmation
impérative et objet, mais le déconseille, et privilégie le
fonctionnel.
Anubis est très intéressant au niveau des concepts. Il est bien conçu
au niveau mathématique (il est écrit par un mathématicien). Mais pour
un programmeur amateur, je ne suis pas sûr que ce langage soit bien
adapté. L'auteur revendique un temps de débogage 40 fois plus court
qu'en C. Je le crois sans problème (même si c'est un peu facile de se
moquer des langages déficients).
C
Le C est un langage bas-niveau. Je ne critiquerai donc pas le fait de devoir manipuler des pointeurs et de gérer la mémoire à la main. C'est normal, on souhaite rester proche de la machine et avoir de très bonnes performances. Mais cela ne justifie pas tout. Pourquoi n'y a-t-il pas de type booléen (#define true 1 n'est pas un booléen :)), ni de type string ? Pourquoi le système de typage est-il si faible qu'il confond l'entier 0 et le pointeur nul, qu'il confond un entier,un caractère et un type énuméré ? Pourquoi la syntaxe est-elle silaide au point de considérer la boucle "for" comme une boucle "while" ? Pourquoi interdire les fonctions imbriquées ? Sans compter le système de headers qui se résume à un vulgaire "include" (même Pascal fait beaucoup mieux sur ce point). Pourquoi le switch est-il limité aux entiers (mais bon, presque tout est un int en C :)) et nous oblige-t-il à mettre des "break" partout (et un oubli entraine des résultats quasi-aléatoires) ? Tant qu'une alternative est possible, je déconseille fortement ce langage.
C++
Quasiment un sur-ensemble du C, C++ a cherché à corriger les problèmes du langage. La tâche était très dure, et ce n'est pas vraiment gagné. On trouve quand même un tas d'améliorations utiles : les références, les objets, la surcharge d'opérateurs, les templates, les exceptions. Même si certains considèrent le C++ comme fortement typé,il n'en est pas moins qu'il hérite des problèmes du C, et que l'on trouve nombre de conversions implicites.L'intérêt du langage est son aspect bas-niveau, sa rapidité (les compilateurs génèrent souvent du code efficace) et sa popularité. Mais à moins d'avoir des contraintes fortes (temps réel par exemple), autant choisir un langage de haut-niveau.
C#
Encore un langage construit sur les bases bancales du C, avec une philosophie très impérative. Ce langage est souvent comparé à Java et les deux langages ont beaucoup de points communs : tentative ratée de
sûreté du langage malgré un typage fort ; syntaxe lourde et verbeuse ;
orienté objet boiteux : pourquoi les entiers ne sont pas des objets,
alors que l'on oblige la fonction "main" à être dans un objet (soit
on fait du tout objet, soit on laisse le choix, faut être cohérent) ?
Malgré tout ça, C# est un langage assez mature et les nouvelles
fonctionnalités s'annoncent intéressantes : types génériques ; méthodes
anonymes avec fermeture ; LINQ (qui permet de faire des requêtes SQL à
l'intérieur même du langage, en gardant un vrai typage ; expressions lambda ; inférence de type locale ; types anonymes... Tout ça fait que le langage commence à être utilisable. Bien sûr, toutes ses nouvelles fonctionnalités existaient déjà depuis très longtemps dans les vrais langages. D'ailleurs, si C# a pu les intégrer, c'est grâce à F# qui a servi de test (F# était entre autres le premier langage .Net à supporter les generics). Même si j'ai souvent craché sur ce langage, je reconnais qu'il sera à peu près utilisable avec C# 3.0.
D
Dans la même philosophie bancale de C# et Java, se trouve le langage D. Enfin, pas exactement. Il me semble plutôt à mis chemin entre Java et C++. Le créateur a voulu corriger le tir de C++, en augmentant la sûreté, et en perdant le moins de puissance possible. Du coup, on retrouve les accès bas-niveau du C en même temps que le GarbageCollector, une compilation en natif, des mixins, de l'inférence locale... Pendant longtemps, le site de référence proposait une comparaison du langage avec le C, le C++, C# et Java. Et il semblait les dépasser sur pas mal de fonctionnalités. Mais les langages ont évolué (enfin, juste les deux derniers) et le comparatif a disparu... Du coup, je ne suis plus sûr de l'intérêt de D. Je pense qu'il y avait pas mal de bonnes idées et que ça aurait pu être intéressant s'il était sorti plus tôt. Maintenant, entre Java, C# et C++, il n'y plus vraiment de place.
Erlang
Erlang est un langage fonctionnel concurrent temps réel et distribué. On retrouve une certaine influence de ML, avec entre autres du pattern matching, la même gestion des tuples et des listes. En revanche, il y a du typage dynamique. Le principal intérêt est quand même la programmation concurrente. Je connais très peu ce langage, donc je ne vais pas m'y attarder.
F#
Ah ! Vu que j'en parle et parlerai dans d'autres messages, je ne serai pas trop long. Citons juste, qu'en plus des merveilleux avantages d'OCaml (pas tous, mais 90% d'entre eux), on trouve une syntaxe encore plus jolie, l'intégration dans .Net et sa bibliothèque, la surcharge d'opérateurs, des interfaces, des fonctions génériques d'affichage, et pleins d'autres choses sympa. Même si l'on peut regretter un manque de maturité (le langage est encore très jeune), on peut apprécier que le langage évolue rapidement (nouvelle version dans 10 jours !). Je le recommande très très fortement à tout le monde, et pour (presque) tous les
besoins.
Haskell
Un langage magnifique. Quand on le voit, on a l'impression que c'est
un langage pour les extrémistes : du fonctionnel pur et dur (on ne
peut jamais modifier de variable), du typage fort et statique, une
évaluation paresseuse par défaut, du pattern matching, de la surcharge
d'opérateurs (polymorphisme ad-hoc) de l'inférence de type... La
syntaxe est courte et très jolie. Le langage est très intéressant et
possède pleins de concepts sympa, mais il est un peu déroutant : la
philosophie est particulière et l'évaluation systématiquement
paresseuse et le système de monades sont très inhabituels. J'ai déjà lu un livre entier sur Haskell, mais j'ai très peu de pratique. Ce
langage mériterait que je m'y attarde plus longtemps.
Java
Je crois que vous savez déjà ce que je pense de ce langage. On
retrouve beaucoup de points communs avec C# (cf plus haut). Pour les
remarques plus détaillées, je vous renvoie à ma critique du langage
Java.
Un certain nombre d'autres critiques sur le langage : http://www.jwz.org/doc/java.html
Javascript
Ce langage est souvent comme un langage jouet, pour débutants. S'il
est vrai que JavaScript est utilisé presque exclusivement dans les
pages web, au milieu du HTML, et que beaucoup de débutants
l'apprennent en copiant-collant des scripts ridicules, il n'en reste
pas moins que le langage a quelques bonnes idées.
D'abord, il supporte la programmation fonctionnelle (mais ne
l'encourage pas vraiment). On retrouve notamment les fonctions
anonymes et les fermetures, qui me sont si chères. Plus surprenant
encore est son système objet. Ce dernier, inspiré du langage Self, est
à prototypes. C'est-à-dire qu'il n'y a pas de notion de classe : on
écrit directement l'objet (le prototype). Ensuite, on peut créer
d'autres objets par clônage ou héritage. Ce qui est amusant aussi,
c'est que l'héritage est complètement dynamique : on peut changer de
père à tout moment.
Malgré ça, le langage a pas mal de problèmes. On peut notamment
critiquer sa syntaxe, son manque désastreux de rigueur, les
différences entre les différents interpréteurs disponibles (ce qui
entraine un certain de hack pour quiconque souhaite avoir du code
portable). Et bien sûr, malgré les quelques points intéressants,
JavaScript est quand même loin de la puissance de la plupart des
langages récents : JavaScript a surtout été pensé pour être simple à
utiliser.
Lisaac
Ce langage français est lui aussi un langage orienté objet à
prototypes. Il a été écrit pour la réalisation du système
d'exploitation Isaac. C'est un langage assez haut-niveau, mais qui
permet quand même des accès bas-niveau (indispensable pour l'écriture
de drivers). On trouve aussi un support pour la programmation par
contrats et pour la programmation système. Le langage est surtout
inspiré de Self et de Eiffel. Et ce qui est très intéressant, c'est
surtout l'approche minimaliste dans son design. Il n'y a pas de
primitive pour les boucles ou les conditionnelles (if...) : tout est
implémenté en dehors du compilateur. Ce qui prouve que le cœur du langage est particulièrement expressif. Son aspect orienté objet à prototype est assez développé : il supporte à la fois l'héritage dynamique et l'héritage multiple. De plus, le système de portée a été repensé : on peut choisir avec beaucoup de finesse qui aura accès à certaines méthodes et qui n'y aura pas accès.
Le but final est de créer un système d'exploitation complet, basé sur ce langage. Moi aussi, je rêve de voir un nouveau système d'exploitation moderne, débarrassé de ce parasite qu'est le C, et utilisant vraiment l'objet. Je vous invite à aller voir la page du projet Lisaac.
Lisp
Encore un langage minimaliste, mais extrêmement puissant. Ce langage,
bien que très vieux, est très expressif et possède beaucoup de
qualités : aspect fonctionnel, méta-programmation très développée
(grâce entre autres à sa syntaxe minimaliste) et grande pureté. Lisp a
un petit nombre de concepts élémentaires, et tout ce construit
au-dessus de ça. C'est une petite boîte à outils qui permet de tout
faire. Comme le dit Paul Graham, Lisp est avant tout un langage pour
"hackers".
« Lisp is worth learning for the profound enlightenment experience you
will have when you finally get it; that experience will make you a
better programmer for the rest of your days, even if you never
actually use Lisp itself a lot. » (Eric Raymond)
En revanche, Lisp n'est pas un langage facile à aborder. Je reproche
surtout à Lisp son typage dynamique et son absence de syntaxe, même si
ces deux éléments contribuent indéniablement à la puissance du
langage. Je considère qu'un langage devrait privilégier la sûreté et
la lisibilité du code : pour moi, le langage serait plus agréable avec
plus de sucre syntaxique.
Lua
C'est un langage de script très léger qui a pour vocation d'être
embarqué dans des logiciels, pour les étendre. On est donc loin de la
lourdeur et du nombre impressionnant de fonctionnalités de Ruby. Le cœur est relativement petit, mais supporte plusieurs paradigmes :
procédural, objet à prototypes, fonctionnel. Le langage se veut
extensible et permet l'introspection. Le langage me semble assez bien
conçu et répond correctement à un besoin : le langage est assez pur,il est léger et dynamique. Il s'intègre a priori bien dans un
logiciel.
Oz
Oz est un langage multi-paradigme. Le nombre de concepts qu'il supporte est assez impressionnant, on a l'impression qu'ils ont tout mis dans le langage. Le paradigmes supportés sont : le procédural, l'orienté objet (à base de classes), le fonctionnel, la programmation logique, concurrente, à contraintes et la programmation distribuée. L'objectif était de combiner tout ça dans un ensemble cohérent. On trouve aussi du pattern matching, un garbage-collector, une évaluation stricte par défaut (mais l'évaluation paresseuse est disponible) et un typage dynamique. Le langage part donc d'une bonne intention, la volonté de regrouper différentes idées en un seul langage, mais j'ai un peu de mal à y croire. La syntaxe ne me convainc pas, ça me semble un bordélique. À mon avis, le problème est d'avoir voulu tout mettre dans le noyau, alors qu'une approche comme celle de Lisp me semble plus saine et mène à un langage plus simple et plus cohérent. Je pense qu'il aurait mieux fallu limiter la taille du cœur, et de proposer, via du sucre syntaxique et des bibliothèques annexes, les différentes fonctionnalités souhaitées.
OCaml
Du fonctionnel, de l'impératif, de l'objet, du polymorphisme, de l'inférence de type, du pattern matching, du typage structurel,définition de nouveaux opérateurs... ce langage a vraiment beaucoup de qualités. On regrette quand même l'absence de surcharge, qui fait qu'il faut avoir de l'imagination pour nommer ses fonctions de même nature (print_int, print_float, print_char...) ou ses opérateurs ("+.","*.", "+/", "-/"). On regrette aussi un certain nombre de contraintes (on a pas le droit de déclarer deux structures ayant un même nom de
champ) qui ne sont pas toujours les bienvenues (même si elles
contribuent à la sûreté du langage). Je vous renvoie aussi à mon
introduction sur OCaml, pour plus de précisions.
Au final, c'est un très bon langage, vraiment sûr (un programme qui
compile a 95% de chances de marcher), avec une syntaxe très concise
qui n'a rien à envier aux langages dynamiques...
Pascal
C'est un langage impératif, de bas-niveau et assez proche du C. Il
s'en démarque par sa clarté et sa rigueur, au prix d'une verbosité
plus élevée. Il est aussi plus sûr que le C, grâce à son système de
typage fort et statique. La syntaxe est plus nette et plus cohérente,
mais parfois un peu lourde ("begin", "end"). Même si on peut apprécier
la rigueur imposée (notamment, on différencie l'interface de l'implémentation ; les déclarations de variables du code), cela
devient parfois trop contraignant. Pour tout un tas de raisons, Pascal
me semble plus intéressant que le C, pour la majorité des
programmes. Mais il faut reconnaître que le C possède toujours un
intérêt, celui de la programmation système, alors que Pascal ne sert
plus à rien : il a été dépassé depuis longtemps par d'autres langages,
et sa gestion des pointeurs et du bas-niveau sont trop restreints par
cette prétendue sûreté du langage.
Perl
Si j'étais de mauvaise foi, je dirai que le seul intérêt de Perl est de pouvoir dessiner des ascii-arts qui sont aussi du code valide. L'intérêt de Perl était de remplacer Awk, c'est-à-dire, un outil pour le traitement de fichiers. Mais ce qui est particulièrement pénible, c'est cette syntaxe, remplie de caractères spéciaux, qui n'est absolument pas naturelle. Et puis aussi, un certain manque decohérence, comme le dit si bien Larry Wall dans le manuel :
« There is no rule that relates the behavior of an expression in list
context to its behavior in scalar context, or vice versa. It might do
two totally different things. Each operator and function decides which
sort of value it would be most appropriate to return in scalar
context. Some operators return the length of the list that would have
been returned in list context. Some operators return the first value
in the list. Some operators return the last value in the list. Someoperators return a count of successful operations. In general, they
do what you want, unless you want consistency. »
On peut quand même apprécier la simplicité du traitement de chaînes
(et les expressions rationnelles), le support de la programmation
fonctionnelle et la concision du langage. Ce qui fait que Perl n'est
pas totalement ridicule. Au final, il y a beaucoup de bonnes idées dans
Perl, notamment l'intégration de la syntaxe s/// de sed ; mais le
résultat est plutôt moyen. Je conseille donc d'utiliser les autres
langages plus sérieux, qui se sont inspirés de Perl.
Php
Php est un langage créé spécialement pour la programmation Web, qui a
jugé utile de récupérer les problèmes de syntaxe du C. Pire, son
système de typage particulièrement bancale, ses conversions implicites
et inattendues et cette volonté sans limite d'exécuter du code, même
quand il est clairement erroné, sans afficher le moindre
avertissement, font que le langage est particulièrement peu fiable,
laid et ridicule.
Il faut mettre un dollar devant un identifiant pour le considérer
comme une variable (ce qui est moche). Mais, si jamais on oublie le
dollar, PHP supposera que c'est une chaine de caractère et que le
programmeur a été assez fainéant pour oublier les guillemets. C'est
gentil, ça part d'une bonne intention, mais il n'y a qu'une chance sur
100 pour que ce soit effectivement ce que je souhaitais faire. Il y a
aussi cette manie de déclarer implicitement des variables
correspondant aux valeurs passées en argument.
On a vraiment l'impression que l'interpréteur fait tout son possible
pour réussir à exécuter du code manifestement faux. Mais, chose
étrange, et comble suprême de l'incohérence, on ne peut pas accéder à
une variable globale depuis une fonction. Du moins, pas sans le dire
explicitement. L'intérêt ? Probablement pour rendre le langage moins
cohérent et amener le programmeur à faire plus d'erreurs, toujours
sans le moindre avertissement. Par exemple, si l'on écrit :
$a = 2;
function toto() { $a = 3; }
toto();
echo $a;
Cela affichera, contre toute attente, 2 (oui, une nouvelle variable a
été implicitement déclarée dans la fonction). Les règles de portée
sont donc chamboulées par rapport à ce qui existe dans les autres
langages. Bien entendu, le système de typage est complètement
dynamique, totalement faible. Bref, c'est sans espoir.
Cette volonté malsaine de vouloir introduire le programmeur en erreur, sans juger bon de l'avertir... je n'en veux pas. Peut-être en cherchant très longtemps, on pourrait trouver une qualité au langage ? Je l'ai pourtant utilisé assez souvent, mais je n'ai jamais vu le moindre point fort.
Python
Python, un langage dynamique, mais assez sympa. Il autorise les
paradigmes impératifs, objets et fonctionnels. La syntaxe est assez
claire et structurée et basée sur l'indentation. On retrouve un
certain nombre de fonctionnalités assez sympa : les compréhensions de
listes, les expressions lambda, de l'héritage multiple, de la
méta-programmation et de la réflexion, du duck-typing. C'est donc un
langage assez sympa, mais malheureusement typé dynamiquement. Cependant, Python est un langage hybride, ayant des fonctions pour la
programmation procédurale et des objets pour l'OO. On peut être déçu
par ce manque de pureté, surtout quand on connait Ruby.
Ruby
On retrouve quasiment toutes les qualités de Python. L'héritage
multiple est cependant remplacé par des mixins, un mécanisme très
puissant : une définiton de classe peut inclure un module, et
bénéficier des ses méthodes. Le système objet est beaucoup plus pur et
la programmation fonctionnelle bien plus agréable ; on a les
fermetures, les lambda expressions, les continuations, la réflexivité,
les yields. La programmation fonctionnelle est donc assez puissantes en Ruby, mais il est dommage que le langage encourage les effets de
bord. Pour moi, on gagnerait en sûreté et en clarté, si la déclaration
de variables d'était pas implicite en Ruby. Modifier une variable (et
donc faire un effet de bord) et en déclarer une ont exactement la même
syntaxe ; de ce fait, la programmation fonctionnelle n'est pas
vraiment encouragée par le langage.
Même si je n'approuve vraiment pas le typage dynamique, j'aurais
tendance à conseille ce langage. Il y a vraiment plein de bonnes
choses, et la syntaxe est magnifique.
- LLB
- 16:53
- > Lien permanent
- > Commentaires
- > Abus ?


![[Jeu] Ideo](images_/carre1.gif)

