Dart — Un langage de programmation qui pourrait vous plaire.
Note: Cet article est le même que j’ai écrit sur medium.
Dart est un langage de programmation orienté-objet à ramasse-miettes maintenu par Google et présenté au grand public pour la première fois en Octobre 2011. Conçu pour créer des applications clientes multiplateformes, il peut aussi bien être utilisé pour créer des serveurs web. Son objectif est d’offrir le langage de programmation le plus productif pour le développement multiplateforme, associé à une plate-forme d’exécution flexible et rapide pour les frameworks d’applications.
Ce langage constitue la base principale du SDK Flutter. Il prend en charge de nombreuses taches de développement de bases telles que le formatage, l’analyse et les tests. Son optimisation pour le rendu et le développement d’ applications a rendu possible le rafraîchissement à chaud dans Flutter (hot reload en anglais).
Dans cet article nous ferons un léger tour de ce langage de programmation en essayant de vous montrer au mieux ses points forts et ses limites.
Domaine d’utilisation
Au tout début, le langage Dart était conçu pour créer de larges et complexes applications web en misant sur sa capacité à précompiler son code en JavaScript pour pouvoir s’exécuter sur les navigateurs web modernes, en utilisant un compilateur source-source (ou transcompilateur). Au fil du temps, le langage a suivi une évolution époustouflante et a ouvert ses portes à bien d’autres domaines d’applications.
Ainsi, le langage Dart peut être utilisé dans plusieurs domaines dont les plus connus sont les suivants:
— En utilisant le framework Flutter:
-
Développement d’applications mobiles: Avec Flutter, vous pouvez créer des applications mobiles fluide pour IOS et Android à partir d’une seule base de code Dart.
-
Développement de site web et applications de bureau: Le même code utilisé pour le développement mobile peut être étendu pour pouvoir rendre de très beau sites web et applications de bureau
-
Développement d’application pour les systèmes embarqués supportant Android
-
Développement de jeux: Ce langage optimisé pour les rendus UI vous donne la possibilité de créer des jeux fluides et complexe à partir de peu de code. Vous pouvez regarder ce tuto pour en savoir plus.
— Mais aussi:
-
Vous pouvez l’utiliser pour créer des serveurs web performants: Pour plus d’informations sur la création et le déploiement des serveurs écrits en Dart, suivez la documentation officielle.
-
Créer des applications en ligne de commande: grâce à la machine virtuelle (VM) autonome de Dart, vous pouvez créer des applications en ligne de commandes performantes et CLI en utilisant ce langage qui dispose des nombreuses librairies et paquets (natifs) pour cela tels que dart:io et le paquet args.
Aussi, Google l’utilise a de nombreuse fins. Par exemple, l’application Stadia pour les télévisions Android a été écrite en Dart, pareil pour les applications Google Pay et Google Ads. Pour plus de d’informations sur les domaines d’applications de ce langage, je vous recommande de suivre le Dart developers summit de 2015 qui fut tenu par les créateurs du langage.
Avantages et points forts de Dart
Lorsqu’on parle de Dart on a tendance à le comparer (ou l’assimiler) à d’autres langages de programmation tels que JavaScript, Java ou le C++. Il serait donc impossible pour moi de le présenter en ignorant ses avantages et ses points forts car, il en a pleins. Parmi ces avantages nous pouvons citer:
-
Facile à apprendre: lorsque je découvrais ce langage, mes notions de programmations étaient encore très limitées, c’est avec grande surprise que je me suis rendu compte que cela ne m’empêchait pas de concevoir rapidement de petites applications qui me rendait heureux. D’ailleurs ce langage a été conçu pour rester simple tout en étant performant.
-
Autonome (ou stand-alone): Ainsi, Dart ne dépend d’aucune librairie, dépendance ou autre logiciel pour fonctionner parfaitement sur votre ordinateur.
-
Parfaite implémentation des concepts de la POO: Dart est un langage orienté-objet, un paradigme qui diffère des autres car vous permets d’utiliser héritage et extensibilité pour la réutilisation du code et met à votre disposition ses deux principaux éléments: les classes et les objets. Mais encore, contrairement à Java, Dart supporte les mixin, donnant la possibilité à une classe d’hériter des fonctionnalités d’autres classes sans forcement avoir des liens avec ces classes. Une fonctionnalité similaire à l’héritage multiple et en écriture simplifiée.
-
Typage par inférence: Le typage en Dart se fait de manière statique, pour une meilleur gestion des erreurs de type lors de l’exécution des programmes (runtime errors) contrairement aux langages à typage dynamique tels que Python, JavaScript, PHP. Cependant, Dart supporte aussi le typage par inférence qui nous permettra de ne pas spécifier si on le souhaite le type de la variable/fonction lors de sa déclaration (choix simple mais moins optimale). Cela n’empêche pas le check de type au moment de la compilation, nous protégeant ainsi des erreurs de types, très tôt. D’ailleurs, dans la plus part des IDE, il vous suffira d’essayer d’assigner un type à un autre pour qu’il y ait des traits de soulignements rouges partout partout (lol).
-
De nombreux types et fonctionnalités utiles intégrés: Dart dispose de nombreux types utiles et de nombreuses fonctionnalités intégrées tels que les extensions sur type, les énumérations, et la programmation asynchrone (Dart est un langage qui la supporte très bien, nous verrons pourquoi plus tard).
-
Supporte l’initialisation tardive/paresseuse et la sécurité nulle: L’initialisation paresseuse est un modèle de conception (design patterns en anglais) rependu parmi les langages de programmations qui donne la possibilité à une variable de n’être initialisée qu’au premier besoin. Ceci est un plus pour la gestion de la mémoire lors de l’exécution des programmes. A coté, Dart supporte la sécurité nulle. Cette fonctionnalité permet de prévenir les erreurs dues aux tentatives non intentionnelles d’accès ou d’usage d’une variable contenant la valeur nulle lors de l’exécution d’un programme. En Dart, les variables sont “non nullables” par défaut, vous pouvez ainsi attribuer la “nullabilité” (humm…) à une variable/fonction lors de sa déclaration en ajoutant après son type le symbole
?
. exemple:String? str = null;
EcrireString str = null
; ne vous retournera rien d’autre qu’une erreur très grave vous signalant que le type null n’est pas un sous-type du typeString
. -
S’exécute à de très haute performance: Cela vous surprendra sans doute mais sachez que Dart produit un code JavaScript plus petit et plus rapide sur les navigateurs web grâce à son inférenceur de type global. En analysant l’intégralité du programme, le compilateur peut éliminer les renflouements et les vérifications redondantes, ce qui se traduit par un code qui s’exécute plus rapidement sur les moteurs JavaScript modernes.
-
De nombreux outils utiles au développement: Choisir Dart comme langage de programmation c’est se simplifier la vie dans le sens ou il met à notre disposition des outils très utiles lors du développement de nos applications. Citons entre autres:
- le Plugin Dart adapté a de nombreux editeurs tels que Vs Code, les IDE de JetBrains, Emacs, Eclipse et Vim.
- Dart DevTools, qui est une suite d’outils pour le debugging et le monitoring de performance.
- DartPad, qui est un outil open-source, utile pour tester des bouts de codes Dart sans avoir à l’installer le SDK sur votre machine.
- Pub, qui est le gestionnaire officiel de paquets. Et pleins d’autres outils utiles pour le débogage, les tests, l’analyse et la gestion d’erreurs.
-
Dart est portable: Comme le c++, Dart est un langage de programmation portable, une fois le programme écrit, il n’a pas besoin d’ être reconfiguré pour pouvoir s’exécuter sur d’autres systèmes d’exploitation.
-
Enfin, la documentation et la communauté: De tous les langages de programmations que j’ai eu à explorer, Dart a l’une des meilleurs documentation en ligne et l’une des communautés les plus actives, aussi bien sur les réseaux sociaux que sur les sites notoires tels que GitHub et StackOverFlow. Ainsi, les débutants retrouvent facilement leurs repères une fois égarés et bénéficient fortement du soutien des plus expérimentés. Nous ne diront jamais assez merci à Lars Bak, Kasper Lund et Google, pour ce beau langage qu’est Dart.
Plus profondément, comment est ce que fonctionne le langage Dart?
Cette partie de l’article a pu être écrite grâce à de nombreuses ressources que je ne pourrai toutes citer, dont la principale est celle ci par Vyacheslav Egorov (@v.e.egorov sur medium). Ingénieur logiciel chez Google, Il se concentre principalement sur la technologie derrière les machines virtuelles et les compilateurs, contribuant au moteur JavaScript V8 et à Dart VM.
Si vous êtes arrivés jusque là, c’est que vous portez vraiment de l’intérêt à ce langage de programmation et ça tombe bien, la suite est encore plus intéressante et sera pleine de surprises. Nous essayerons de répondre à la question posée en découpant le fonctionnement globale de Dart en des blocs décrivant les parties essentiels de son fonctionnement (ce sur quoi il repose).
Une machine virtuelle:
Le fonctionnement de Dart repose sur une machine virtuelle communément appelée Dart VM. Cette machine virtuelle est une collection de composants permettant d’exécuter le code Dart de manière native ou de le transcompiler en JavaScript grâce aux compilateurs Dart Dev Compiler et Dart2Js. En gros, cette machine virtuelle dont la majeur partie fait appel à des programmes écrits en c++ est composée de:
- un système d’exécution, qui lui même est composé du système ramasse-miettes et celui des snapshots (plus bas).
- des méthodes natives des bibliothèques principales
- des composants de développement liés à l’expérience accessibles via le protocole de service ( Débogueur, Profilage (exécution comme en production, mais avec le strict minimum pour le débogage), rafraîchissement à chaud, etc.)
- les pipelines de compilation Just-in-Time (JIT) et Ahead-of-Time (AOT)
- l’interpréteur et le simulateur ARM
Comment Dart VM exécute le code:
Optimisé un compilateur c’est l’art de prendre des raccourcis Vyacheslav Egorov — Strange Loop 2013.
La plupart des appareils modernes ont des processeurs multicœurs. Pour tirer parti de tous ces cœurs, les développeurs utilisent parfois des threads à mémoire partagée exécutés simultanément. Cependant, la simultanéité d’état partagé est sujette aux erreurs et peut conduire à un code compliqué. Au lieu de threads, tout le code Dart s’exécute à l’intérieur d’isolats. Chaque isolat a sa propre pile de mémoire, garantissant qu’aucun état d’un isolat n’est accessible à partir d’un autre isolat. Comme il n’y a pas de mémoire partagée, vous n’avez pas à vous soucier des mutex ou des locks pour limiter l’accès a la mémoire lorsque des ressources sont partagées. En utilisant des isolats, votre code Dart peut effectuer plusieurs tâches indépendantes à la fois, en utilisant des cœurs de processeur supplémentaires s’ils sont disponibles. Les isolats sont comme des threads ou des processus, mais chaque isolat a sa propre mémoire et un seul thread exécutant une boucle d’événement.
Dart exécute son code source de différentes manières. Les deux principales sont:
-
l’exécution du compilateur à partir du code source ou du kernel en utilisant le JIT (Just In Time compilation). Cette méthode consiste en la compilation du code à la volée, lors de l’exécution du programme, c’est la recompilation incrémentale. L’un des avantages de cette méthode peut être le rafraîchissement à chaud et l’un de ces inconvénients, un long temps d’attente lors du démarrage.
-
la seconde méthode d’exécution des programmes écrit en Dart se fait à partir des snapshots, en utilisant AOT (compilation Ahead Of Time). Notre machine a la capacité de convertir un objet en flux d’octets pour le stocker ou le transmettre à la mémoire, dans le but d’enregistrer l’état d’un objet afin de pouvoir le recréer si nécessaire. C’est la sérialisation. En Dart les objets stockées sont des piles d’isolats ou plus précisément le graphique d’objet résidant dans la pile, ils sont stockées dans un instantané binaire appelé snapshot. L’instantané peut ensuite être utilisé pour recréer le même état lors du démarrage des isolats de la machine.
Si vous souhaitez en savoir à propos de ces deux modes d’execution des programmes Dart je vous propose cet article de Vyacheslav Egorov.
Je me garderai d’entrer dans les profondeurs de la compilation des programmes écrit en Dart dans cet article vu que là n’était pas le principal objet de mes recherches sur ce langage.
L’asynchrone en Dart
Lors de la suspension d’une fonction, son état d’exécution local (variables locales et temporaires) est sauvegardé et le contrôle est rendu en appelant la fonction suspendue. Lors de la reprise d’une fonction, son état d’exécution local est restauré et l’exécution se poursuit dans la fonction «suspendable» à partir du point où elle a été suspendue.
Afin de minimiser la taille du code, l’implémentation est construite à l’aide d’une variété de stubs — des extraits réutilisables de code machine générés par la VM/AOT. La logique Dart de haut niveau utilisée pour implémenter des fonctions pouvant être suspendues (telles que la gestion de Futures/Streams/Iterators) est prise en compte dans les méthodes Dart d’assistance dans la bibliothèque principale. Pour plus d’informations a ce sujet, je vous propose cet article, qui explique comment cette fonctionnalité est implémentée au langage.
Pour conclure cette section, nous devons retenir que l’environnement d’exécution des programmes Dart a été conçu pour être performant et simple, donnant la possibilité au langage d’être précompilé en JavaScript pour le web ou en code machine ARM ou x64 natif permettant à vos applications d’être exécutées de manière rapide et fluide.
Attention
Le langage Dart est un langage relativement nouveau. Bien que cela ne l’empêche pas d’être assez mature, vous devriez savoir que la majeur partie de ses fonctionnalités est encore en développement tels que Dart2Js ou la machine virtuelle dans son ensemble, Des milliers de personnes y travaillent tous les jours afin de le rendre meilleur.
Conclusion
Le langage Dart est un langage de programmation de premier choix lors de la conception d’applications performantes coté client. Peu verbeux et efficace, il est facile à prendre en main et est soutenu par une communauté énorme sur l’étendu du web. C’est pourquoi moi en tant que développeur mobile, et de nombreuses autres entreprises dans le monde telles que Alibaba, Ebay, Toyota, Rive, ByteDance ou BMW, avons choisi Dart pour l’aventure, la performance et avons fait de lui notre quotidien. Merci à toute la communauté et au valeureuses personnes qui ont conduit ce langage jusque là.