Le langage Scala n’est pas dénué d’avantages, comme beaucoup d’autres : il est typé (comme C ou Pascal), mais ne force pas à indiquer les types explicitement dans le code (contrairement aux précités, mais comme Python) ; il n’impose pas une verbosité monstre (contrairement à Java), avec une syntaxe orientée productivité (comme Python) ; il est raisonnablement rapide (comme Java, mais nettement moins que C), mais permet d’exploiter le parallélisme très facilement (contrairement à Python).
Par contre, un des inconvénients de Scala est sa vitesse d’exécution, pas toujours suffisante : il faut compter le temps de démarrage de la JVM, puis les optimisations que le moteur JIT peut effectuer sur le code qui lui est soumis, sans oublier que le ramasse-miettes peut venir jouer. La sécurité que le langage offre peut aussi aller à l’encontre de la performance à l’exécution : il est impossible de s’échapper du bac à sable défini, à l’exception de quelques utilisateurs très expérimentés. Finalement, au niveau de l’accès aux bibliothèques natives préexistantes, leur réutilisation est presque impossible — après tout, ces bibliothèques natives pourraient causer des problèmes de sécurité !
Pour résoudre ces problèmes, une équipe de l’EPFL, déjà à l’origine de Scala, a lancé le développement de Scala Native. Ce compilateur Scala exploite LLVM, l’infrastructure de compilateurs derrière Clang, notamment. La syntaxe de cette variante de Scala ne diffère de l’originale que par quelques ajouts, dont l’objectif est de faciliter l’interopérabilité avec des bibliothèques natives, comme des structures C (avec l’annotation @struct sur une classe) ou encore l’allocation de mémoire sur le tas avec des pointeurs :
val x: Double
val y: Double
}
val vec = stackalloc[Vec] // Équivalent à un malloc() en C ou un new en C++ : vec est un pointeur sur le tas.
Pour accéder directement à des fonctions C (comme malloc()), il est aussi possible d’utiliser l’annotation @externe et directement définir la fonction comme utilisable :
def malloc(size: CSize): Ptr[_] = extern
}
val ptr = stdlib.malloc(32)
Au niveau de l’implémentation, le projet Scala Native ne duplique pas l’analyse syntaxique du compilateur, mais l’utilise (ou bien dotty, la prochaine génération du compilateur Scala). Il profite donc d’une base de code bien établie, ainsi que d’optimisations éprouvées dans le contexte du code Scala.
À l’exécution, bien sûr, Scala Native exploite toujours un ramasse-miettes, le classique Boehm, simplement parce qu’il a l’avantage de déjà exister. Les développeurs notent qu’il ne peut que s’améliorer par rapport à cette implémentation générique. La bibliothèque standard Java est partiellement disponible, toute la bibliothèque standard C est accessible.
Ce générateur de code natif depuis Scala n’est pas encore prêt pour le plus grand nombre, il a, à peine, été annoncé ce mois-ci. Ses objectifs ne concernent pas les temps de compilation. Cependant, il montre que le langage Scala veut s’exporter de plus en plus, après un autre générateur de code JavaScript pour utiliser son code dans des navigateurs Web.
Source (dont image) : présentation à Scala NYC.
Voir aussi : le site officiel de Scala Native, le projet sur GitHub.