Un commentaire très pertinent de Kontre m’a interpellé dernièrement : si Javascript est si pourri, pourquoi tout le monde s’y intéresse ?

TD;DR : L’inertie technique.

Il faut bien comprendre que PERSONNE ne s’intéresse à Javascript directement. Les gens s’intéressent passionnément à la programmation Web. Et il se trouve que, concernant la programmation côté client, il y a QUE Javascript de disponible.

Quand Ajax est arrivé, des mecs brillants ont rendu le Web plus interactif. Et ils ont utilisé ce qui était implémenté partout : Javascript. Pas parce qu’ils aimaient Javascript. Pas parce que Javascript était un bon langage.

Parce que c’était la seule solution dispo.

Avant, personne ne s’intéressait à ce truc. C’était un langage de script kiddies pour faire des flocons de neige sur les pages HTML. Et donc tout le monde se foutait royalement que ce soit de la merde. IE l’avait implémenté parce que Netscape l’avait fait. C’était alors un gros hybride qui tentait de rassurer les codeurs C et Java. Javascript était marketing, jusque dans le choix du nom. Puis IE6 a gardé le pouvoir pendant 10 ans, et du coup, tout le monde a suivi.

Personne n’a réfléchi. Personne n’a vu venir l’explosion du Web. Personne ne s’est dit “les gars faudrait peut être faire attention, le status quo pue la merde”. A cette époque, ça n’avait pas d’importance, on a mis les efforts de guerre ailleurs.

L’heure du Web 2.0 a alors sonné, et là les business ont eu besoin de puissance de feu. Mais c’était trop tard, il n’y avait plus qu’un seul truc hideux de dispo pour la prog…

Google a utilisé massivement les pages dynamiques, et devant le constat des performances misérables de la seule techno qu’il y avait a dispo, il a pondu chrome, et sa VM Javascript ultra performante. Si on avait appliqué la même techno à n’importe quelle autre langage, on aurait obtenu 10 fois cette vitesse.

C’est quand Google a enfin pu donner des perfs décentes – c’est à dire celles qu’ont d’autres langage depuis une décennie – à Javascript que les gens ont envisagé de l’utiliser sur le serveur. Encore une fois, pas parce que Javascript était une techno dont ils étaient fondamentalement amoureux.

Parce qu’ils voulaient éviter d’écrire deux fois le même code côté client et côté serveur et que toute tentative de générer du Javascript n’a pas été satisfaisante. Et aussi parce que le besoin de faire de l’asynchrone se faisait sentir et que les Dev clients n’avaient pas envie d’apprendre un autre langage. Ben oui, l’asynchrone, vous croyez que pas que ça existe que sur JS quand même ? C’est aussi vieux que les premiers compilateurs. Les Devs clients connaissaient déjà le JS, et ça faisait du DRY, alors pouet.

Personne. J’ai bien dit, personne ! Ne s’est jamais extasié devant l’incroyable ergonomie de Javascript. Devant sa facilité de debuggage. Devant la qualité de sa doc.

Ruby est un langage innovant and fun.

Python est un langage ergonomique and riche.

Php est un langage avec une super doc et une communauté noob friendly.

Lisp est un langage puissant avec un paradigme fonctionnel de référence.

Go est un langage propre avec une gestion de la concurrence très performante.

Javascript est juste là par hasard. Il ne dépasse aucun des langages ci-dessus en terme de ses qualités propres. Sa bibliothèque standard est risible. Il ne sert absolument à rien sans un framework côté serveur, et côté client il est parfaitement improductif sans une lib pour gommer les incompatibilités entre les implémentations.

Les docs sur JS sont éparpillées sur le Web. Les tutos sont déchirés entre tant de versions et de frameworks qu’on se croirait dans un script des frères wachowski.

Des notions de base comme les closures sont encore obscures pour la plupart des codeurs Javascript, alors qu’elles peuvent ruiner les perfs de votre programme ou créer des bugs énormes. Les projets innovants en Javascript sont tous faits par des gens hyper compétents parce qu’innover dans ce langage, ça demande une discipline de dingue tellement il offre d’opportunité de merder.

Javascript est un hack qu’on se traine.

C’est un bug legacy.

C’est un virus préinstallé dans les navigateurs.

Oui il y a des produits à base de Javascript fantastiques. Oui les innovations techno Web actuelles intéressantes tournent toutes autour de Javascript de près ou de loin. Et oui, vous devez définitivement mettre les mains dedans parce que le monde du dev avancera en dépit de vos goûts. En tout cas, en dépit des miens, j’en ai bien conscience.

Mais ceci ne se fait pas grâce à Javascript. Ceci se fait en dépit de Javascript. Malgré le fait que c’est un langage au typage pourri, malgré son scoping dégueulasse, malgré l’absence des facilités modernes les plus basiques comme le passage d’arguments avancés ou un slicing décent.

Parce qu’il y a des gens très (TRÈS) bons qui ont eu Javascript comme contrainte, et qui en ont tiré le meilleur. Et c’est pas faute d’avoir essayé autre chose (Flash, GWT, Haxe…). Ces mecs sont incroyables, ce sont des Dieux vivant, Amen to them, mais Javascript reste à chier.

Et on va se le coltiner encore très, très longtemps.

Au cas où vous ne l’aurez pas encore compris, je vomis sur Javascript. Mais je code avec, et j’offre même des formations dessus, car je suis pragmatique. Les besoins de l’industrie, l’inertie technologie et le contexte social / technique / économique dictent bien plus souvent les standards que nous utilisons que leurs qualités intrasèques. Sinon nous n’aurions pas utilisé le format .doc ou les VHS.

En fait, je ne détesterais pas autant Javascript si je n’en avais pas besoin quotidiennement. Je le hais du plus profond de mon âme justement parce que c’est non seulement une contrainte inamovible de mon métier, mais en plus une tumeur que les chercheurs annoncent voir grossir de jour en jour. Avec le sourire, les connards !

Le VB est peut être pire que le JS, mais je m’en branle, je n’ai pas à y toucher.

Après cet argumentaire, je précise que je ne mettrai pas de tampon sur les commentaires, parce que je comprends bien que je ne peux pas lâcher une caisse et demander à tout le monde de respirer à fond et ne pas se plaindre.

Néanmoins, puisque cet article à des vocations thérapeutique – vous êtes tous un peu mes psy au fond (la confidentialité bloggeur / lecteur, ça marche ?) – voici un listing de tout ce que j’abhorre dans le Javascript.

)

Les experts recommandent d’éviter la moitié du langage

Il y a tellement de merdes dans JS que les plus grands experts s’accordent sur le fait que la première chose à faire est d’apprendre la liste des choses à ne PAS utiliser.

En fait, Douglas Crockford lui même a écrit un bouquin complet rien que sur le sujet.

Je n’ai pas tout en tête, mais en vrac…

Ne pas utiliser l’opérateur == , parce que :

'' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true " \t \r

" == 0 // true '' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true " \t\r

" == 0 // true

Notez que même === ne retire pas toutes les ambiguïtés :

> var a = { "abc" : 1 } > a [ [ [ [ "abc" ] ] ] ] === a [ "abc" ] true > var a = { "abc" : 1 } > a[[[["abc"]]]] === a["abc"] true

Ne pas utiliser parseInt sans préciser la base sinon :

> parseInt ( '06' ) 6 > parseInt ( '07' ) 7 > parseInt ( '08' ) 0 > parseInt ( '09' ) 0 > parseInt ( '10' ) 10 > parseInt('06') 6 > parseInt('07') 7 > parseInt('08') 0 > parseInt('09') 0 > parseInt('10') 10

Bien se souvenir d’utiliser var partout. En fait activer use strict dès que possible pour éviter l’insertion de ; automatiques.

Et ne pas utiliser la syntaxe de déclaration de variable sans var puisque ça créé une variable globale. Cependant, faites gaffe quand vous convertissez du code parce que :

a = 1

1

> var a = 1

undefined

Encore une connerie. Mais vous avez l’habitude :)

Ah oui, et ne pas utiliser les mots clés new ou with pour vos propres libs. Si, si, on bannit carrément des mots clés, c’est écrit dans le livre.

Faire du JS propre présuppose l’utilisation de design patterns

En l’état, on ne peut pas écrire du JS propre. Écrire la plus simple instruction Javascript est déjà écrire du code sale car toute variable devient globale. Il faut tout foutre dans un conteneur quelconque, souvent dans une fonction anonyme immédiatement appelée, mais il y a d’autres techniques (services avec injection de dépendance dans angularjs par exemple).

Pour être honnête, on commence à peine à savoir écrire des grosses applis Javascript propres côté client depuis quelques années. Ca a pris un temps fou de trial / error pour gommer petit à petit tous les aspects guedin de la techno et obtenir un socle utilisable.

Un autre truc : personne ne s’est mis d’accord sur l’utilisation des objets : prototypage, simulation d’héritage, instanciation ou pas, composition uniquement ? En tout cas vous devez en choisir un, et ne pas le merder.

Au fait, vous avez déjà essayé d’expliquer le prototypage à quelqu’un ? Bonne chance !

Non seulement c’est du typage faible, mais en plus c’est du typage con

J’ouvre Firefox, je tape:

> { } + { } // Ceci n 'est effectivement PAS un nombre NaN > {} + [] // logique IMPARABLE 0 > [] + {} // fuck la commutativité "[object Object]" > {} + {} // Ceci n'est effectivement PAS un nombre NaN > {} + [] // logique IMPARABLE 0 > [] + {} // fuck la commutativité "[object Object]"

Et après on va me dire que c’est juste l’API DOM qui est incohérente selon les implémentations. Mais non, tenez, même ça c’est cohérent. Je fais la même chose sous Node 0.8 (sur lequel j’ai par ailleurs déjà râlé):

> { } + [ ] '[object Object]' > {} + [] '[object Object]'

Enfin quelle implémentation ? Node original ? Le fork Io.js ? Ou le fork qui doit merger les deux ?

On pourrait continuer longtemps avec ces saloperies, mais je finis sur un exemple qui résume bien tout le merdier :

> '5' + 3 '53' > '5' - 3 2 > "Vous en étiez à... peau de couilles je crois ?" + 1 'Vous en étiez à... peau de couilles je crois ?1' > "Vous en étiez à... peau de couilles je crois ?" - 1 NaN > '5' + 3 '53' > '5' - 3 2 > "Vous en étiez à... peau de couilles je crois ?" + 1 'Vous en étiez à... peau de couilles je crois ?1' > "Vous en étiez à... peau de couilles je crois ?" - 1 NaN

Et vous pouvez toujours vous dire que si vous faites attention, vous n’aurez pas de problème, mais ça a des répercussions sur TOUT le langage, dans les recoins les plus vicieux :

> Math. min ( null , 1234 ) 0 > Math. min ( 'null' , 1234 ) NaN > Math. min ( '1' , 1234 ) 1 > Math.min(null, 1234) 0 > Math.min('null', 1234) NaN > Math.min('1', 1234) 1

L’élégance d’un chameau bourré à la villageoise

On se déchaîne

Ruby :

coucou = "" "Ceci est une looooooooooooooooooooooooooooooooooooooooongue chaine ! Sur plusieurs lignes ! Et une autre ! Et une autre ! J'adore les sauts de ligne, c'est tellement lisible !!! " "" puts coucou coucou = """Ceci est une looooooooooooooooooooooooooooooooooooooooongue chaine ! Sur plusieurs lignes ! Et une autre ! Et une autre ! J'adore les sauts de ligne, c'est tellement lisible !!! """ puts coucou

Python :

variable = "foo" coucou = """Ceci est une looooooooooooooooooooooooooooooooooooooooongue chaine ! Sur plusieurs lignes ! Et une autre ! Et une autre ! J'adore les sauts de ligne, c'est tellement lisible !!! Et en prime voila une variable : %s ! """ % variable print coucou variable = "foo" coucou = """Ceci est une looooooooooooooooooooooooooooooooooooooooongue chaine ! Sur plusieurs lignes ! Et une autre ! Et une autre ! J'adore les sauts de ligne, c'est tellement lisible !!! Et en prime voila une variable : %s ! """ % variable print coucou

Javascript :

var variable = "foo" ; var coucou = "Ceci est une looooooooooooooooooooooooooooooooooooooooongue chaine ! \ Sur plusieurs lignes !

\ Et une autre !

\ Et une autre !

\ J'adore les sauts de ligne, c'est tellement lisible !!!

\ Et en prime voila une variable : " + variable + " !" console. log ( coucou ) var variable = "foo"; var coucou = "Ceci est une looooooooooooooooooooooooooooooooooooooooongue chaine !\ Sur plusieurs lignes !

\ Et une autre !

\ Et une autre !

\ J'adore les sauts de ligne, c'est tellement lisible !!!

\ Et en prime voila une variable : " + variable + " !" console.log(coucou)

C’est vrai que manipuler des chaînes, c’est pas la PUTAIN D’OPERATION INFORMATIQUE LA PLUS COURANTE DANS LE PUTAIN DE MONDE. PUTAIN.

Séquence émotion

Une autre opération qu’on fait 100 fois par jour : créer des séquences (fichiers, settings, données en base, etc), en récupérer une partie, itérer dessus, les transformer, etc.*

Soit la liste :

l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Récupérer les carrés des nombres paires de la moité supérieure de la liste ?

Python :

l = [ x*x for x in l [ 5 : ] if x % 2 == 0 ] l = [x*x for x in l[5:] if x %2 == 0]

Ruby :

l = l [ 5 .. 10 ] . select { | x | x % 2 == 0 } . collect { | x | x * x } l = l[5..10].select{|x| x % 2 == 0 }.collect{|x| x * x}

Javascript (Ma que, gracieux comme oune popotamé):

var new_list = [ ] l. splice ( 0 , 5 ) for ( var i = 0 ; i < l. length ; i ++ ) { if ( l [ i ] % 2 == 0 ) { new_list. push ( l [ i ] * l [ i ] ) ; } } l = new_list ; var new_list = [] l.splice(0, 5) for (var i = 0; i < l.length; i++) { if (l[i] % 2 == 0) { new_list.push(l[i] * l[i]); } } l = new_list;

Et encore, je suis cool, je mets un code JS qui utilise l.length directement dans la boucle et pas de variable pour l[i] .

Array.map arrive avec JS 1.6 et les arrays comprehensions avec la 1.7, que vous pourrez utiliser sur tous les navigateurs d’ici 2056. Ou alors juste sur le serveur, mais si c’est pour pas avoir le même code sur le client ou le serveur, pourquoi ne pas utiliser un langage qui possède tout ça et bien plus depuis 5 ans ?

DéLire

Lire un fichier ligne à ligne ? Une opération vraiment rare et compliquée…

Python :

for line in open ( 'fichier' ) : print line for line in open('fichier'): print line

Ruby :

File . foreach ( '/etc/fstab' ) { | x | print x } File.foreach('/etc/fstab') {|x| print x }

En JS… Heu, enfin avec NodeJS:

var fs = require ( "fs" ) ; fs. readFileSync ( './input.txt' ) . toString ( ) . split ( '

' ) . forEach ( function ( line ) { console. log ( line ) ; } ) ; var fs = require("fs"); fs.readFileSync('./input.txt').toString().split('

').forEach(function (line) { console.log(line); });

Ah oui, il faut installer un MODULE SUPPLEMENTAIRE pour gérer tout autre encoding que les variantes d’unicode.

PASramètre

Comment on fait ça en Javascript ?

def fonction ( param , param2 = "valeur" , **params ) : print param , param2 , params fonction ( 1 , autre_valeur = 2 ) def fonction(param, param2="valeur", **params): print param, param2, params fonction(1, autre_valeur=2)

On fait pas. Du coup on se retourne vers la bonne vieille technique de “j’attends un objet en paramètre et je le fusionne avec un autre objet qui a mes valeurs par défaut”.

Javascript ça marche partout !

Node ne tourne pas sous Windows, excluant de sa pool d’apprentissage les 3/4 des foyers de la planète. Parce que je sais pas pour vous, mais moi, quand j’ai appris la programmation, j’ai pris le premier ordinateur qui m’est tombé sous la main et j’ai essayé. Parce que je n’y connaissais rien. Je ne me suis pas soucié de l’OS.

On me signale dans la comemntoreillette que j’ai dis une connerie.

Ah oui, et sans node, le Javascript on en fait quoi déjà ? Des Interface graphiques poussées comme avec QT ? Du calcul scientifique de haut niveau comme avec Scipy ? Du sys admin windows comme avec pywin32 ?

Ah non, en fait, on fait rien.

Deux structures de données devraient suffire à n’importe qui

Donc, vous avez les arrays. Et les objets. Et pour le reste, vous vous démerdez.

Des sets ? Des heaps ? Des tuples ? Des views ? C’est pour les petites bites tout ça. C’est tellement plus rigolo de réimplémenter la roue.

D’ailleurs, même les roues fournies sont carrées, juste au cas où vous vous sentiez trop à l’aise.

Qui se souvient des params de splice pour le slicing ? Vous, moi ? Nope. Jamais. C’est con parce que c’est AUSSI la seule manière d’enlever un élément au milieu d’un array sans laisser une case vide. On allait pas coder ça, ça sert pas souvent…

En parlant de trucs biens faits, mélanger une structure de données qui fait objet ET hashmap, quelle bonne idée ! Encore plus con que de mélanger les listes et le mapping en PHP. Tu veux récupérer les attributs de ton objet ? Paye ta boucle (et fait gaffe à la chaine de prototypage). Tu veux updater ton dico avec le contenu d’un autre. Écris ta méthode toi-même, c’est un truc dont on a pas besoin IRL.

Et tout est comme ça. Encore une fois, le langage tout seul te laisse à poil, il y a toujours un machin à recoder à la main à moins d’installer une (voir 2) libs pour avoir ne serait-ce que les trucs de base : faire un hash md5, générer un ID unique, filtrer des doublons sur un objet qui n’est pas une chaîne, et mon grand favoris, la division entière.

Ouai. La division entière n’est pas incluse de base en JS.

Or le JS, c’est typiquement le truc pour lequel on veut charger le MOINS DE CHOSES POSSIBLES pour que ta page s’affiche vite. Du coup on passe notre temps à créer des solutions de contournement avec de la mignification, des CDN qui aident à optimiser l’usage du cache, et tout le bordel.

Ah mais il faut utiliser coffeescript !

Oui donc pas Javascript. Point made.

Le langage est tellement à chier qu’on a inventé un autre langage pour le générer et pas avoir à s’en soucier. Et ensuite, on a inventé des libs pour automatiquement faire cette compilation pour le dev, et les outils pour le déployer. Et on a inséré dans les navigateurs une nouvelle technologie : le source map, parce que sinon c’était trop chiant à débugger. Qu’il faut aussi déployer pendant le dev. Et former les gens dessus.

Vous trouvez ça normal ?

Vous trouvez que c’est le signe d’un BON langage ?

Ouai mais ça fait un seul langage côté server et client

Oui, c’est pour ça que les gens s’y mettent. Encore une fois, ça n’a rien à voir avec les qualités de Javascript. Ca reste de la merde en boîte, mais de la merde unifiée.

Et encore, car si on a bien le même langage, on est loin d’avoir le même code. Le code serveur et le code client est, sauf dans les frameworks avancés comme météorjs, très peu partagé au final. Surtout que vous n’avez PAS la même version du moteur Javascript côté serveur et côté client.

Les libs externes bien conçues marcherons de la même façon par contre, ce qui est un avantage.

Encore une fois, la question n’est pas “est-ce que les gens doivent utiliser Javascript ?” La réponse à cette question est oui. Pas le choix.

Mais on ne l’utilise pas parce que c’est un bon langage. On l’utilise parce que c’est le status quo. Qui est tout pérave.

Arrête de baver et donne nous ta solution !

J’ai pas de solution parce qu’il n’y en a pas. C’est trop tard. Le Javascript et là et on l’a dans le cul. D’où ma frustration. La 1.7 va dans la bonne direction, mais le temps qu’elle soit adoptée partout…

Par contre si ce n’est pas trop demandé, arrêtez de mettre du Javascript partout. Limitez la contamination. Vous n’avez pas vu “28 jours plus tard” ? Il faut isoler le problème avant que la pandémie ne dévore l’humanité. Il y a des tas d’alternatives : Python, Ruby, Clojure, Go, Lua, etc.

Si vous faites un langage de scripting embarqué, si vous faites un outils de déploiement, si vous faites un premier binding pour votre outil… Ne donnez pas la prio à cette bouse. Quand je vois Gnome ou QT adopter le JS pour leur scripting, ça me met dans une rage folle. C’est de la connerie pure. Bordel, il y a un site appelé 99 bottles of beer avec des milliers de langages. Vous avez le choix !

C’est bien beau d’avoir le même langage partout, mais si c’est pour se trainer un boulet… Vous ne travaillerez pas plus vite.

D’ailleurs, vous n’aurez jamais le même langage partout. Vous aurez toujours à apprendre et utiliser 2 ou 3 langages. C’est un fait de la vie. Les humains ne parlent pas tous anglais ou chinois. Et les codeurs ne coderont jamais dans un espéranto, fusse-t-il fantastique.

Je sais, je sais, quand on vient du C, Javascript parait si facile, on se dit que c’est une amélioration de l’ergonomie au prix de la performance. Mais non, c’est comme acheter une 2 chevaux pour aller en ville à la place de son tracteur, alors qu’on vous avait proposé une smart ou une mini pour le même prix.

Par ailleurs, il y a une vie en dehors de la prog Web vous savez.

Si il n’y a pas de solution, ferme ta gueule alors

C’est mon blog, je fais ce que je veux. Na.