Au-delà de Javascript – Synthèse

Cet article synthétise les travaux de veille technologique entrepris autour du thème des nouvelles technologies alternatives à Javascript.

 Javascript : vue d’ensemble, limites et défauts

Aujourd’hui, la technologie Javascript jouit d’une grande popularité dans les développements d’applications web modernes : non seulement le langage lui-même, qui s’est imposé comme le langage de script de référence pour le web, mais aussi les nombreux outils basés sur Javascript (bibliothèques, frameworks, méthodes AJAX). Javascript offre un moyen simple d’augmenter le dynamisme et l’interactivité d’un site. De plus, sa communauté est active, comme en témoigne d’ailleurs le nombre important de bibliothèques et frameworks qui étendent les possibilités du langage.

Cependant, Javascript souffre de défauts non négligeables. Par exemple, les mécanismes d’héritage, basés sur les chaînes de prototypes et non les classes, sont assez laborieux. Le langage permet une grande permissivité et réserve de nombreuses surprises, notamment en ce qui concerne la déclaration des variables et la gestion de leurs types. Ce qui peut rendre les tâches de déboggage très délicates. La syntaxe de Javascript, inspirée des langages tels que C ou Java, n’est pas adaptée à sa vraie nature, qui se rapproche davantage de langages fonctionnels comme Lisp ou Scheme, selon Douglas Crockford. De plus, le comité ECMA, qui pilote la conception du langage, a déjà publié de nombreuses versions de Javascript, ce qui entretient une certaine confusion. D’ailleurs, malgré de nets progrès ces dernières années, les principaux navigateurs web présents sur le marché ont des implémentations différentes du langage (browser quirks), ce qui complexifie les développements. Enfin, Javascript pâtit de mauvaises pratiques, passées ou toujours en vigueur : récupération et exploitation abusives de données personnelles, surgissement de fenêtres intempestives, surcharge des capacités de calcul ou des temps de chargement côté client et détériotation de l’expérience utilisateur pour les non-voyants.

Technologies alternatives à Javascript

Il existe de nombreuses bibliothèques et de nombreux frameworks basés sur Javascript, principalement dédiés aux développements d’applications web riches (RIA), comme en témoigne le site du projet TodoMVC. Il existe également des langages alternatifs qui, tout en conservant une syntaxe relativement proche de Javascript, entendent le dépasser. Ces langages sont souvent compilables en Javascript, à l’image de TypeScript, CoffeeScript et Dart.

CoffeeScript

CoffeeScript est un langage de programmation issu d’un projet open source, à typage dynamique faible (comme Javascript) et multi-paradigme. Il est pensé comme une tentative de révéler le meilleur de Javascript le plus simplement possible. Il permet d’utiliser toutes les bibliothèques Javascript existantes. Bien qu’il n’apporte ni méthode ni objet nouveau, CoffeeScript est tout de même pensé pour remédier aux défauts de syntaxe de Javascript et le rendre “plus simple et plus sûr”.

CoffeeScript apporte aussi des fonctionnalités nouvelles inspirées de langages comme Python, Ruby ou Haskell : sucre syntaxique, filtrage par motif ou listes en compréhension.

CoffeeScript propose un code qui se veut élégant mais qui n’est pas pour autant plus facile à lire ou à écrire car il se destine à des développeurs familiers de Javascript et ayant une certaine connaissance du langage Ruby. De plus, CoffeeScript est basé sur la programmation fonctionnelle et semble moins adapté à la programmation web orientée objet qu’un langage comme Dart.

Dart

En 2011, Google a dévoilé le projet Dart : un langage largement basé sur Javascript fourni avec différents outils de développement, dont un EDI, un SDK et un compilateur vers JavaScript. Il existe une différence majeure entre CoffeeScript et Dart : tandis que le premier tend à promouvoir les meilleurs aspects du Javascript, le second entend le remplacer.

Zoom sur Dart

Motivation

Dart est né à partir du constat, fait par Google, que les problèmes inhérents à la nature de Javascript ne peuvent être résolus en le faisant évoluer. Le projet Dart vise donc à créer un langage facile à apprendre, plus performant et prédictible, offrant plus de sécurité et capable d’être utilisé aussi bien sur de petits projets que sur de larges applications.

Le langage Dart

Afin de rendre le projet attrayant et de faciliter la prise en main du langage, Dart s’inspire de concepts familiers aux développeurs Javascript, C# et Java. En fait, Dart regroupe des concepts empruntés à de nombreux langages : la syntaxe de Javascript, les types optionnels à la manière de Strongtalk, les objets sur le modèle de Smalltalk, certains concepts tirés de C# et un mécanisme de parallélisme inspiré par Erlang.

De manière générale, Dart est un langage orienté objet à héritage simple, basé sur les classes, qui se veut moins permissif que Javascript et sans surprise. D’autre part, Dart apporte ou revoie des fonctionnalités par rapport à des langages comme Javascript ou C# : portée lexicale, types statiques optionels, types génériques covariants, constructeurs nommés, appels en cascade, capture des variables de boucle (closures), absence de conversions implicites, etc. Enfin, toutes les bibliothèques et API Javascript sont utilisables en Dart.

Les outils de développement Dart

Le projet Dart propose également un panel d’outils destinés à former une plateforme complète pour les développements web : un EDI, un SDK, un navigateur web dédié, un compilateur Dart vers Javascript, une machine virtuelle standalone, un gestionnaire de paquets et des mécanismes de déploiement et d’optimisation du code source.

Évolutions du projet

Les développements autour du projet Dart se poursuivent. En effet, depuis 2011, Dart a connu deux mises à jour importantes : Dart’s Milestone 2 et 3. Sortie en décembre 2012, la Dart M2 apporte une large documentation avec tutoriels ainsi que des améliorations majeures de certaines fonctionnalités : réduction importante de la taille du code généré par le compilateur vers Javascript, amélioration des bibliothèques et du gestionnaire de paquets et support du SSL par la machine virtuelle. En février 2013 est parue la Dart M3, principalement consacrée à la programmation asynchrone et à la gestion des événements (nouvelle API dédiée et améliorations de l’existant).

Les critiques

Aujourd’hui, le développement de Dart continue mais il est trop tôt pour avoir une idée de la réussite de cet ambitieux projet. A cet égard, Dart est l’objet de nombreuses critiques, notamment en ce qu’il entend constituer un énième standard de langage web. Une autre critique visant le projet Dart concerne sa conception en dehors d’un consensus, à l’encontre du développement de l’open-web. Certains développeurs craignent une forme d’appropriation de la technologie Javascript par Google.

Plan du rapport

En conclusion de ces travaux de veille technologique, nous publierons un rapport PDF qui reprendra tous les points abordés précédemment. Voici un aperçu de son plan :

Le Javascript

Origine et nature du langage

Limites et défauts

Mauvaise conception du langage
Disparités des versions et des implémentations
Mauvaises pratiques
Multiplication des extensions

Technologies alternatives

Vue d’ensemble

Le projet CoffeeScript

Le projet Dart

Zoom sur le projet Dart

Raison d’être

Le langage Dart

Les outils de développement Dart

Évolutions et perspectives du projet

Critiques

Conclusion

 

Licence Creative Commons
Cet article est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 France.

Au-delà de Javascript – CoffeeScript et Dart

Suite et fin sur CoffeeScript

Revenons sur CoffeeScript.
Rappelons tout d’abord que le code CoffeeScript est compilé en JavaScript. Cela a l’avantage de rendre tout code JavaScript compatible avec des travaux entrepris sur CoffeeScript.
Le langage ajoute en fait du sucre syntaxique inspiré par des langages comme Python ou Ruby afin d’améliorer la brièveté et la lisibilité du JavaScript, tout en ajoutant des fonctionnalités comme le filtrage par motif ou les listes en compréhension.

Le sucre syntaxique est une expression qui désigne des extensions faites à un langage de programmation ne modifiant pas son expressivité mais le rendant plus agréable à la lecture comme à l’écriture. Par exemple, en C la notation tableau[i] est un exemple de sucre syntaxique pour l’expression *(tableau+i), qui évite au programmeur de recourir à l’arithmétique des pointeurs.
Le code qui suit illustre ces facilités d’écriture :

Le code CoffeeScript suivant :

square = (x) -> x * x
cube   = (x) -> square(x) * x

Compile comme cela en JavaScript :

var cube, square;
square = function(x) {
  return x * x;
};
cube = function(x) {
  return square(x) * x;
};

Source du code : http://coffeescript.org/

On observe évidemment une forte compression du code mais aussi une syntaxe très proche de Ruby ou Python.
Comme nous l’avons vu précédemment, les objets JavaScript sont basés sur des prototypes et non des classes et le mécanisme d’héritage, bien que fonctionnel, souffre d’une syntaxe très déroutante, qui pousse les développeurs à utiliser des astuces relevant du monkey patching.
L’exemple suivant montre le mécanisme d’héritage de CoffeeScript, bien plus “classique” puisque basé sur les classes :

class Animal
    constructor: (@name) ->

    move: (meters) ->
        alert @name + " moved " + meters + "m."

class Snake extends Animal
    move: ->
        alert "Slithering..."
        super 5

Source du code : http://coffeescript.org/

Le filtrage par motif est la vérification de la présence de constituants d’un motif par un programme informatique. Par exemple “travail*spatial” peut signifier toute chaîne de caractères commencant par “travail” et se terminant par “spatial”. Le mécanisme sous-jacent (dans un langage comme Haskel) est celui des Arbres/Expressions Rationnelles.

Enfin, CoffeeScript permet la définition de listes en compréhension (comme en Haskell et Python), c’est-à-dire des listes dont le contenu est défini par filtrage du contenu d’une autre liste. Par exemple pour créer la liste des 5 premiers entiers au cube :

list = [1, 2, 3, 4, 5]
cubes = (math.cube num for num in list)

Ou plus compact (les cubes de 10 à 1) :

cube_countdown = (math.cube num for num in [10..1])

Certaines limites de CoffeeScript

Ainsi, CoffeeScript a la prétention de proposer du “beau code” et de réduire la charge de travail du programmeur. Pour autant, le code produit n’est pas forcément plus facile à lire ou à écrire.
En effet, comme le souligne Benjamin Farrell dans le billet The CoffeeScript Dilemna de son blog : le code est plus lisible pour des développeurs possédant un background important en Ruby (CoffeeScript est issu de la communauté Ruby et sa syntaxe et ses mécanismes s’en inspirent fortement, comme nous l’avons vu).
D’autre part, Benjamin Farrell souligne une erreur à ne pas commettre : CoffeeScript s’adresse à des personnes ayant une bonne connaissance de JavaScript, pas à des débutants. Il ne serait pas efficace de l’utiliser en lieu et place de JavaScript lorsque l’on ne possède pas l’éxpérience nécessaire. CoffeeScript n’est donc pas une alternative complète à JavaScript.

Comme le souligne à plusieurs reprises Martin Heller dans son article intitulé Turn up your nose at Dart and smell the CoffeeScript paru en octobre 2011 sur JavaWorld.com, CoffeeScript reste basé sur de la programmation fonctionnelle alors que Dart – que nous présenterons dans la suite de cette étude – semble une meilleure alternative pour la programmation web orientée-objet.

Tandis que CoffeeScript ramène JavaScript dans une zone de confort pour les vétérans de Ruby (ou Python, Haskel, etc.), Dart, en s’attaquant au dynamisme (ou laxisme) de JavaScript et en le ramenant à un langage plus statique (d’après Jeremy Ashkenas), en fait un langage plus familier pour les dévelopeurs Java.

Par ailleurs, d’après Ryan Florence, la plus grande différence entre Dart et CoffeeScript est que ce dernier n’est pas une menace pour JavaScript car il se présente comme une évolution alors que l’objectif avoué de Dart est de remplacer JavaScript.

Introduction sur Dart

Dart désigne un langage de programmation web orienté object, basé sur les classes, à héritage simple, open-source et développé par Google. Le projet Dart, dévoilé en 2011 par Lars Bak et Kasper Lund, ne se limite pas au seul langage :

  • Dart Editor, un EDI léger qui permet de gérer des projets, offre des fonctionnalités classiques (complétion automatique, déboggage, etc.) et se décline en plugins pour IntelliJ et Eclipse notamment ;
  • un SDK contenant un ensemble de bibliothèques et des outils en ligne de commande ;
  • Chromium (ou Dartium), un navigateur web incluant une machine virtuelle, capable d’exécuter directement des programmes Dart, sans compilation vers Javascript ;
  • un compilateur Dart vers Javascript, écrit en Dart (qui peut donc se compiler lui-même en Javascript) ;
  • un gestionnaire de paquets de programmes Dart (dépôt public et outil en ligne de commande) ;
  • une machine virtuelle (outil en ligne de commande, intégrée à Dart Editor, au SDK et à Chromium).

La syntaxe de Dart est largement basée sur celle de Javascript. L’objectif de ce langage est de supplanter Javascript en tant que langage standard pour les développements web, tant du côté serveur que du côté client, adapté aux plus petits scripts comme aux plus larges applications. Dart prétend offrir le choix d’écrire du code typé ou non (mélange de résolution statique et dynamique), tout en étant plus rigoureux que Javascript sur la déclaration et la portée des variables. Il est également pensé pour être modulaire, utilisable avec de nombreuses bibliothèques, et comporte des mécanismes de parallélisme (Isolates).

Dans la suite de cette étude, nous reviendrons plus en détail sur le langage Dart, les défauts auxquels il apporte des solutions et ses perspectives. Nous donnerons également un aperçu d’autres technologies pouvant être présentées comme des alternatives à Javascript.

 

Licence Creative Commons
Cet article est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 France.

Les défauts de Javascript – A propos de CoffeeScript

Les défauts de Javascript

 Aberrations du langage

Les objets en Javascript sont basés sur des prototypes et non sur des classes. Cela est assez déroutant pour les développeurs habitués à une programmation orientée-objet plus classique, avec notamment des concepts de propriété propres ou de chaîne de prototypes.

Voici un exemple de mécanisme d’héritage en Javascript, tel que préconisé par le MDN*, avec correction du pointeur du constructeur de la classe dérivée pour parachever l’héritage :

// define the Person Class
function Person() {}

Person.prototype.walk = function(){
  alert ('I am walking!');
};
Person.prototype.sayHello = function(){
  alert ('hello');
};

// define the Student class
function Student() {
  // Call the parent constructor
  Person.call(this);
}

// inherit Person
Student.prototype = new Person();

// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;

// replace the sayHello method
Student.prototype.sayHello = function(){
  alert('hi, I am a student');
}

// add sayGoodBye method
Student.prototype.sayGoodBye = function(){
  alert('goodBye');
}

var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();

// check inheritance
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true

L’exemple ci-dessous témoigne de la permissivité de Javascript au niveau de la gestion des variables (pas de déclaration nécessaire, etc.) :

<script>
 var str = "text";
 str.foo = 0;
 alert(str.foo);
</script>

Ce script, exécuté dans un navigateur moderne, affiche “undefined”, sans aucune erreur de la console Javascript lors de l’affectation de la valeur 0 à la variable str.foo.

L’exemple en ligne de commande ci-dessous montre la confusion qui peut exister entre les concepts de type et d’instance (opérateurs typeof et instanceof) :

> var a = new String();
> typeof a
object
> a instanceof Object
true
> typeof null
object
> null instanceof Object
false

Dans cet exemple, on se sert de null comme une référence pour récupérer la propriété d’un objet, alors que null n’est pas une référence :

> null=2;
Exception: ReferenceError: Left side of assignment is not a reference.
> a={};
[object Object]
> a["null"]="foo";
foo
> a[null]
foo

La syntaxe

La syntaxe JavaScript est-elle adaptée aux caractéristiques du langage ? Non, répond le créateur du langage CoffeeScript, Jeremy Ashkenas, qui lui reproche de venir de Java. Il qualifie d’ailleurs CoffeeScript de “Javascript pas fantaisiste”. Selon Ashkenas, la syntaxe de Javascript est laide car copiée sur Java et inadaptée à la véritable nature du langage. Nombreux sont ceux qui, effectivement, considèrent Javascript comme un langage raffiné mais mal servi. Cette critique est notamment formulée par un célèbre spécialiste de Javascript, Douglas Crockford, auteur de JavaScript : the good parts, traduit en français par “Javascript : gardez le meilleur”. Il existe des réflexions de la communauté de développeurs sur les manières d’adopter une syntaxe adaptée au langage (voir ce fil de discussion sur developpez.com).

D’après Jeremy Ashkenas : “L’idée de base c’est de dire que le noyau JavaScript ainsi que son modèle orienté objet ou fonctionnel sont vraiment très bons, mais que tout ça est caché derrière une syntaxe qui vient de Java, principalement. Le problème qui en découle c’est que cette syntaxe ne reflète pas les concepts profonds du langage”, sous entendu : la syntaxe de JavaScript n’est pas aussi élégante et aussi utile que ses concepts.

Dans le contexte d’un navigateur web

Dans la deuxième moitié des années 90 et jusqu’au début de la décennie 2000, Javascript, développé initialement par Netscape, avait pour principal concurrent le langage de script JScript d’Internet Explorer (IE). Ces deux langage sont des implémentations différentes de la norme ECMAScript, qui ont entraîné des divergences dans la gestion des scripts par les moteurs des navigateurs. Certaines méthodes comme celles dévolues à la gestion d’événements ou à l’ajout de texte dans les balises HTML ont ainsi longtemps différé entre IE et les navigateurs héritiers de Netscape, comme Firefox ou Chrome. Ces disparités tendent à s’effacer, simplifiant le travail des développeurs. Mais il n’existe pas d’harmonie parfaite pour ce qui est de l’implémentation de la totalité de la norme ECMAScript.

Par ailleurs, certaines méthodes Javascript de manipulation du DOM sont dangereuses à utiliser car elles ont des comportements inattendus (dans l’absolu ou d’un navigateur à l’autre) et peuvent détruire les propriétés des objets du DOM sur lesquels elles sont appliquées, à l’image de document.write(), qu’il est fortement conseillé d’éviter.

Mauvaises pratiques et prudence des internautes

La popularité de Javascript est en partie due à sa simplicité. Le fait qu’il ait été massivement adopté et utilisé pour rendre des sites plus interactifs a donné lieu à la multiplication de mauvaises pratiques qui rendent les internautes méfiants, parfois à raison.

Voici les principales raisons pour lesquelles les internautes peuvent être amenées à désactiver Javascript (voir cet article et cette discussion) :

  • Le Javascript est un langage « client », il permet de récupérer des statistiques sur les usages des internautes (avec tous les marqueurs statistiques Google Analytics et Xiti) mais aussi des informations sur la vie privée. Il peut être le vecteur de failles de sécurité qui permettent entre autres de récupérer l’historique ou les champs de formulaires enregistrés.

  • Javascript est également utilisé pour faire surgir des pop-ups publicitaires de manière intempestive, ce qui nuit à l’expérience utilisateur.

  • L’utilisation abusive des méthodes AJAX pour mettre à jour automatiquement tout ou partie des pages web peut engendrer le chargement d’importants flots de données à l’insu de l’utilisateur. Cela peut rendre les applications web gourmandes en bande passante.

  • Javascript est un langage interprété dont le chargement est long. Pour offrir plus de fonctionnalités ou accroître la fluidité d’utilisation, certains sites utilisent à outrance le Javascript, ce qui peut provoquer des temps de chargement conséquents et nuire à l’expérience utilisateur. Surtout si, côté client, la puissance de calcul n’est pas suffisante ou si le matériel ou le logiciel n’est pas assez récent.

  • Enfin, du Javascript utilisé à mauvais escient peut avoir des effets néfastes en termes d’accessibilité : les logiciels pour les non-voyants s’accommodent plus facilement d’un contenu brut (directement renvoyé par le serveur) que de pages complexifiées par les CSS ou les scripts.

Malgré ces critiques, Javascript reste un langage très utile pour programmer des fonctionnalités haut-niveau qui rendent les sites web plus simples d’utilisation et plus interactifs. La communauté Javascript semble active si on se réfère à l’agenda des événements du MDN, la dernière conférence en date [au 7 décembre 2012] dédiée à Javascript ayant eu lieu le 15 novembre à Sydney (Australie).

 

Une introduction sur CoffeeScript

CoffeeScript est un langage de programmation sous licence MIT, à typage dynamique faible (comme Javascript) et multi-paradigme. Il est pensé comme une tentative de révéler le meilleur de Javascript le plus simplement possible.

La règle d’or de CoffeeScript est : “C’est juste du Javascript”. Le code compile en son équivalent Javascript et il n’y a pas d’interprétation à exécution. On peut utiliser toutes les bibliothèques Javascript existantes depuis CoffeeScript et inversement.

En quoi il pallie certains défauts de Javascript

Pour remédier principalement aux défauts de syntaxe de Javascript, Jeremy Ashkenas a donc eu l’idée de lancer un projet open-source baptisé CoffeeScript. Il s’agit d’une variation de JavaScript avec une syntaxe qui reflèterait mieux ses caractéristiques. Avec un compilateur en Ruby, CoffeeScript n’apporte pas de méthode ou d’objet particuliers mais il compile directement en pur Javascript. Il offre également des tableaux de compréhension similaire à ceux de Python et fait des déclarations Javascript viables. Son créateur assure que son objectif est aussi de rendre Javascript plus simple et plus sûr : il affirme que “avec CoffeeScript, vous ne pouvez plus accidentellement créer une variable. Cette fonctionnalité amène plus de sureté au langage”.

 

* MDN : Mozilla Developer Network – site : https://developer.mozilla.org/fr/

 

Licence Creative Commons
Cet article est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 France.