21 mars 2008
Imprimer ce billet

Introduction à Scala

Depuis quelque temps, Scala fait beaucoup parler de lui ... et les avis sont plutôt partagés. Ce billet inaugure une série destinée à présenter ce langage de programmation multi-paradigmes.

Scala est un langage de programmation visant à concilier les paradigmes objets et fonctionnels au travers d'un langage qui se veut plus simple et élégant.

Après une rapide présentation des principes de Scala, ce billet traitera du mécanisme d'inférence en Scala.

Principes de Scala

En opposition à la programmation impérative, le modèle de programmation fonctionnelle propose de s'affranchir de la notion d'état et d'écrire un programme comme une imbrication de fonctions. Une fonction est ici considéré comme un élément possédant plusieurs paramètres d'entrée et un et un seul paramètre de sortie. La façon de concevoir les algorithmes dans le paradigme fonctionnel est donc différente de ce à quoi la plupart d'entre nous sommes habitués et risque d'en rebuter plus d'un.
Néanmoins, Scala permet de concilier ce mode de programmation avec la programmation orientée objet. On y retrouve notamment les notions de classes, et l'interaction avec le langage Java. L'objectif de Scala est de tirer parti du meilleur des deux mondes :

  • Moindre verbosité et meilleure gestion de la mémoire d'un côté ;
  • Structuration des données et richesse des APIs de l'autre.

Parmi les notions de Scala, nous retiendrons les suivantes :

  • Plus de constructeur : une économie sur l'instanciation est faite (pas besoin de "new").
  • Le type d'une variable peut être inféré, ainsi le type peut être omis à certains endroits.
  • Possibilité de faire des "mixin class" : les mixins Scala sont similaires aux interfaces Java dans le sens où celles-ci définissent des contrats à implémenter. La différence réside dans le fait qu'il est possible de définir des implémentations par défaut (notion de classes abstraites) pour les méthodes du mixin. Il est ainsi possible de faire de l'héritage multiple.
  • Le compilateur Scala génère des .class pouvant être exécutés dans une JVM.
  • Interaction avec Java : par exemple, toutes les classes de java.lang sont importées par défaut et il est possible d'en importer d'autres explicitement.

Le mécanisme d'inférence

En Scala, la déclaration d'une variable se fait de la manière suivante variable:Type :

var myStr:String = 'xebia'

Scala possède le mécanisme d'inférence et donc il est possible d'écrire cette déclaration de la manière suivante :

var myStr = 'xebia'

La construction d'une liste :

val listStr: Array[String] = new Array[String](4)

Ici la variable listeStr est de type Array[String] et est initialisé avec une longueur de 4. Néanmoins, Scala permet de simplifier cette déclaration (mécanisme d'inférence) et nous avons alors :

val listStr = new Array[String](4)

Au passage nous avons un concept important du mot clé val en Scala. Lorsqu'une variable est définie avec val, celle-ci ne peut pas être réassignée (ie listStr sera toujours un Array[String]). Néanmoins, l'objet auquel elle se réfère peut être mutable (ie les éléments de la liste peuvent être modifiés).

Ensuite le remplissage de la liste :

listStr(0) = "Bonjour"
listStr(1) = "Hello"
listStr(2) = "Guten Tag"

Le parcours de cette liste se fait de la manière suivante :

for (i <- 0 until listStr.length)
    println(listStr(i))

On parcourt la liste jusqu'à sa longueur (listeStr.length) et on affiche les éléments de la liste.

A travers ces exemples, nous remarquerons que la manipulation des listes se fait par le biais de parenthèses et non de crochet (ie Java). Cela est un autre concept de Scala. La magie réside dans le fait que lorsque des parenthèses sont appliquées à une variable, Scala va les « transformer » en appel de méthodes. Ainsi si nous reprenons les exemples précédents Scala fera :

listStr.update(0,"Bonjour")
listStr.update(1,"Hello")
listStr.update(2,"Guten Tag")

for (i <- 0 until listStr.length)
    println(listStr.apply(i))

Il est tout à fait possible d'écrire directement ce code, mais le langage Scala permet de simplifier l'écriture de code sans que des problèmes de performances interviennent.

Enfin pour finir un exemple avec une HashMap :

val factories = new HashMap[Int, String]
factories += 1-> "Xebia Hollande"
factories += 2-> "Xebia France"
factories += 3-> "Xebia Inde"
factories += 4-> "Xebia Groupe"
println(factories(2))

La première ligne signifie que la variable "factories" sera une HashMap avec des clés de type Int et des valeurs de type String.

Ensuite l'opérateur += permet d'ajouter les clés/valeurs avec la méthode ->. Cela peut donc s'écrire :

1.->("Xebia Hollande")

Ici cela signifie que la méthode -> est appelée sur un Int dont la valeur est 1 et prenant en paramètre un String de valeur "Xebia Hollande".

Conclusion

Cette introduction a permis de voir un des concepts clés du langage Scala, le mécanisme d'inférence. Celui-ci permet donc d'avoir une programmation simplifiée tout en ne négligeant pas la performance. Scala ne semble pas si complexe qu'il semblerait l'être, preuve en est les exemples de cet article, où l'on voit qu'il est possible de programmer comme en Java avec une simplification syntaxique. Bien entendu, Scala permet une écriture « moins objet » et plus fonctionnelle et le but de cet article est de poser les bases. D'autres articles suivront avec des notions plus complexes sur le langage Scala.

Références :

Mots-clefs :,