Après plusieurs mois d'attente, Scala 2.8 débarque ! Cette toute nouvelle version de Scala comporte comme d'habitude un grand nombre de corrections de bugs ainsi qu'une quantité impressionnante de nouvelles fonctionnalités par rapport à la 2.7.7. Le framework Lift, conçu pour Scala, a lui aussi été récemment mis à jour.
Scala en quelques mots
Scala est un langage de programmation moderne et puissant, qui s'appuie sur la
JVM et permet ainsi d'être entièrement compatible avec tout programme Java déjà écrit. C'est un langage orienté objet qui possède également de nombreux traits issus des langages fonctionnels et concurrents (utilisant des acteurs). Son nom est la concaténation des deux mots anglais "Scalable" et "Language" qui désignent sa capacité à s'adapter aux contraintes d'utilisation. Il a été conçu pour être utilisé sur tous les types de projets, allant des petits scripts aux grands logiciels commerciaux.
Son créateur, Martin Odersky, est un professeur de programmation et chercheur à l'
EPFL. Il a commencé le développement de Scala en 2001 mais il n'a publié la première version que vers la fin de 2003. Parmi les utilisateurs célèbres de Scala on peut citer LinkedIn, Sony Pictures, Siemens, ebay et le réseau social Twitter, initialement conçu en Ruby, qui
a migré vers Scala afin d'améliorer ses performances.
Scala est également fortement typé, ce qui signifie que les vérifications de la cohérence des types sont strictes : par exemple, il n'est pas possible, contrairement à ce que permet PHP, d'utiliser un entier au lieu d'une chaîne de caractères ; il est nécessaire d'effectuer explicitement une conversion. Cette rigueur a été mise en place afin d'éviter de passer sous silence des erreurs importantes dans la conception des programmes. Il est, de plus, statiquement typé : ces vérifications sont effectuées à la compilation et non à l'exécution. Ainsi, si un programme Scala compile, le programmeur est sûr qu'il ne commettra pas d'erreur de type à l'exécution.
Cependant, cela n'implique pas que le type des variables doit être systématiquement explicitement indiqué par le programmeur : le langage profite, en effet, d'un système appelé «
inférence de types », ce qui signifie que le compilateur déduit le type des variables de leur contexte d'utilisation.
Scala possède d'autres fonctionnalités modernes, comme le filtrage des motifs, les fonctions anonymes (connues sous le nom de fonctions lambda dans d'autres langages), les
conversions implicites de classes (un équivalent plus fiable du
monkey patching de Ruby), son support natif d'XML et son système de types bien évolué.
Voici l'algorithme (récursif) du tri rapide d'une liste implémenté en Scala grâce à un
filtrage de motif :
Code : Scala | def triRapide(l:List[Int]): List[Int] = l match{
case Nil => Nil
case (x :: xs) => val (l1, l2) = xs.partition(_ < x)
triRapide(l1) ::: x :: triRapide(l2)
}
|
Un exemple d'utilisation de l'XML dans le langage :
Code : Scala 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | // on met les balises XML dans une variable nommée html
val html =
<html>
<head>
<title>Bienvenue sur le SDZ !</title>
</head>
<body>
<p>Vous devez vous connecter pour acceder au contenu de cette page</p>
</body>
</html>
// et on peut facilement chercher des balises
html \\ "head" //renvoie <head><title>Bienvenue sur le SDZ !</title></head>
html \\ "p" //renvoie <p>Vous devez [...] de cette page</p>
|
Et enfin une méthode qui calcule la somme des éléments d'une liste :
Code : Scala | def somme(l: List[Int]) = l reduceLeft (_ + _)
|
Cette notation, très concise, est très courante
en programmation fonctionnelle. Le symbole _ correspond en fait à
une fonction anonyme, qui sera appliquée à toute la liste par
reduceLeft.
Scala 2.8, les nouveautés
La version 2.8 de Scala a vu le jour le 14 juillet en apportant au langage des ajouts et changements plus ou moins importants.
Nouvelle API de collections
L'organisation des « collections » de Scala (les classes servant de conteneurs, comme les
vecteurs ou les
listes) a été revue dans cette nouvelle version. Elles sont désormais rangées dans le module
scala.collection.
Celui-ci est lui-même découpé en plusieurs catégories :
- Mutable, qui contient les collections susceptibles d'être modifiées ;
- Immutable, pour celles qui ne peuvent pas être modifiées (il faut alors en créer une copie à chaque modification), ce qui permet de les partager entre plusieurs acteurs ;
- Puis enfin, la catégorie generic qui contient des outils pour faciliter l'implémentation de nouvelles collections.
Les différentes collections peuvent posséder certains comportements (définis par ce qu'on appelle des traits) qui précisent la façon dont on les utilise. Par exemple, l'un des principaux traits est
Traversable : celui-ci indique que la collection peut être parcourue à l'aide d'une méthode
foreach qu'elle implémente. Elle est alors éventuellement infinie. Mais certaines collections héritant de ce trait peuvent implémenter d'autres traits, comme
Seq (qui représente les séquences). Celles-ci sont alors obligatoirement finies, et possèdent une méthode
length pour les mesurer. Et ainsi de suite…
Spécialisation des types
Scala se basant sur la
JVM, il doit, à la compilation, faire la différence entre les types dits « primitifs » comme les entiers ou les nombres décimaux, et les véritables objets. Ceci pose un problème quand on veut utiliser des types conteneurs, car ils ne peuvent contenir que des objets, et pas de types primitifs.
Le compilateur réalise alors un
auto-boxing, en stockant ces valeurs primitives dans des objets créés pour l'occasion (les
enveloppeurs,
wrappers en anglais). Mais cette façon de faire a un coût : la création des objets en question.
Dans Scala 2.8, l'annotation
@specialized a été introduite, qui permet, lors de la définition d'une classe, de préciser au compilateur qu'il peut générer plusieurs classes à la compilation, dont certaines seront plus adaptées aux types primitifs, et d'autres aux objets :
Code : Scala | class MyCollection[@specialized A] {
def simplyReturn(x: A) = x
}
|
Cette fonctionnalité a également été introduite dans un certain nombre de classes prédéfinies.
Arguments nommés et arguments par défaut
Beaucoup de langages autorisent la définition de valeurs par défaut pour les arguments, ce qui permet de ne pas les préciser lors de l'appel d'une méthode, ainsi que de préciser leur nom à l'appel (en ignorant l'ordre dans lequel ils ont été définis). Scala permettait jusqu'à présent la surcharge des méthodes selon leur nombre d'opérateurs, ce qui permettait de remplacer cette fonctionnalité.
Cependant, elle a été ajoutée à la version 2.8 du langage pour des raisons de commodité. Il est par exemple possible de faire (ici, dans la console Scala, qui permet d'entrer du code ligne par ligne) :
Code : Console | scala> def f(a: Int = 10, b: String) = println("a: " + a, "b: " + b)
f: (a: Int, b: String)Unit
scala> f(b = "Yo")
(a: 10, b: Yo) |
Nouveau compilateur
Parmi toutes ces nouveautés, le compilateur a eu le droit lui aussi à quelques changements. Sa vitesse a en effet été améliorée d'environ 50 %. De manière générale, les développeurs de Scala ont voulu rendre le compilateur utilisable par d'autres programmes, comme des IDE, pour tester rapidement (pendant l'édition) le programme : par exemple, que sa syntaxe est correcte.
Le greffon pour l'IDE Eclipse a été amélioré pour tirer parti de ce nouveau compilateur. Le
REPL, sorte de ligne de commande permettant de tester du code Scala ligne par ligne, a été revu et permet l'auto-complétion, la navigation dans l'historique des commandes, et peut être utilisé pour le débuggage, en étant lancé depuis un point arbitrairement choisi d'un programme. Enfin, le compilateur sait maintenant gérer
les continuations.
Swing
La bibliothèque graphique de Scala a eu son lot de changements aussi. On note surtout l'ajout du support des événements de la souris et des claviers, l'ajout de quelques nouveaux composants ainsi que l'amélioration de la
documentation sur le sujet.
Swing est en fait un wrapper pour la bibliothèque du langage Java qui porte le même nom, mais Scala profite des diverses fonctionnalités qu'il offre (notamment le filtrage des motifs) pour faciliter l'utilisation de ce framework géant, surtout en ce qui concerne la gestion des événements qui est devenue un jeu d'enfants :
Code : Scala | reactions += {
case ButtonClicked(b) => //
case KeyPressed(a, b, c, d) => //
case MouseMoved(a, b, c) => //
}
|
Le framework Lift
Lift est un framework web destiné à être utilisé avec le langage Scala et la machine virtuelle Java. Il consiste en un ensemble de composants facilitant le développement de sites et applications web. Il existe beaucoup de frameworks web, comme
Django ou
Ruby on Rails, mais l'équipe de Lift met en avant plusieurs atouts, parmi lesquels :
- Un déploiement vers les conteneurs d'application JEE les plus répandus, voir à ce sujet le tutoriel du site ;
- puisque les sites et applications Web développés avec Lift tournent sur la JVM, ils bénéficient de ses performances et de son extensibilité (scalability en anglais)
- le typage de Scala et sa nature fonctionnelle permettent d'obtenir des applications fiables, avec lesquelles le risque de bugs est peu élevé, les incohérences de type et certains effets de bord non voulus étant évités à la compilation
- Lift permet une utilisation transparente de AJAX et de Comet (où, au lieu de l'approche traditionnelle où le client demande des données au serveur, c'est le serveur qui informe le client que des données sont disponibles), de même que le framework web Nitrogen.
Lift s'appuie donc sur Scala pour faire des applications web riches (du même genre que celles pour lesquelles Ruby on Rails est utilisé), tout en assurant de meilleures performances et une plus grande fiabilité.
Lift 2.0
Le 30 juin, une deuxième version majeure du framework a été annoncée. Elle comporte plusieurs améliorations mineures, comme de meilleures performances ou des messages d'erreur plus clairs. De plus, le framework supporte maintenant nativement les bases de données NoSQL
MongoDB et
CouchDB, ainsi que des services clefs pour les entreprises comme
LDAP ou
JTA.
De plus, le support de
REST a été amélioré, ainsi que celui de JSON (une représentation textuelle des objets JavaScript), ce qui permet non seulement de convertir facilement des objets Scala vers JSON et inversement, mais également de réutiliser le langage spécialisé pour JSON comme langage de requêtes avec les deux bases de données mentionnées précédemment. Par exemple, on peut écrire
Person.findAll(("name" -> "joe") ~ ("age" -> 27)) pour effectuer une requête dans la base de données.
Enfin, un nouveau mécanisme de communication avec l'utilisateur a été rajouté : les
screens et les
wizards. Ceux-ci permettent une approche plus déclarative et proche
de la programmation fonctionnelle, et permettent non seulement de faire abstraction de la présentation (vue) et de l'état (modèle) de la communication avec l'utilisateur. Le code est écrit de la façon suivante :
Code : Scala | object DemanderParfum extends LiftScreen {
val gout = field(S ? "Quel est votre parfum de glace préféré", "")
def finish() {
S.notice("Moi aussi j'aime les glaces au "+gout.is+" !")
}
}
|
et peut alors être utilisé dans les templates de Lift par la simple balise
<lift:DemanderParfum/>, ou testé en local (sans serveur web). Mais il est également possible de s'assurer que l'entrée de l'utilisateur vérifie certaines conditions, en les rajoutant dans la méthode
field :
Code : Scala | object DemanderParfum extends LiftScreen {
val gout = field(S ? "Quel est votre parfum de glace préféré", "",
trim,
valMinLen(2, "Le nom est trop court"),
valMaxLen(40, "Le nom est trop long"))
def finish() {
S.notice("Moi aussi j'aime les glaces au "+gout.is+" !")
}
}
|
Beaucoup d'autres fonctionnalités sont disponibles, mais cet éventail suffit à montrer que Lift, comme Scala, est à la recherche d'idées nouvelles pour le web, qui peuvent conduire à une plus grande concision du code, donc à plus de simplicité, sans pour autant sacrifier les performances.
Liens utiles
53 Participations
Connectez-vous !
Connectez-vous !
Revenir à la liste des news