vendredi 7 mars 2014

Utiliser Git derrière un proxy avec authentification

Laisser un commentaire

Si vous utilisez Git derrière un proxy voici comment le configurer afin de pouvoir discuter avec le dépôt distant.

$ git config --global http.proxy http://username:password@proxy-server-domain:port
Cela ajoute une entrée dans le fichier de configuration globale de git : ~/.gitconfig
$ view ~/.gitconfig
....
[http]
        proxy = http://username:password@proxy-server-domain:port
Lire la suite...

mercredi 11 septembre 2013

Les fonctions et les fonctions d’ordre supérieur

5 comments

La programmation fonctionnelle a de nombreux attraits dont le traitement réservé aux fonctions. Dans beaucoup de langages de programmation les fonctions ont un statut particulier. Par exemple en Java il est possible de créer un entier, de l’assigner à une variable ou de le passer comme argument à une autre fonction mais on ne peut pas de même avec les fonctions. En revanche les fonctions jouent un rôle central dans la programmation fonctionnelle et ne sont pas traitées comme des citoyens de seconde zone par les langages dits fonctionnels (Haskell, Caml, Clojure etc.). Cela est important pour l’écriture de certains types d’abstractions bien utiles et courantes en développement comme nous le verrons dans la suite mais avant d’aller plus loin définissons une fonction.

C’est quoi une fonction ?

Ce qu’on entend par fonction varie selon les langages de programmation mais la définition que je vais donner ici est suffisante pour les propos de l’article. Une fonction est une transformation qui produit une valeur à partir d’un ensemble de paramètres, les arguments de la fonction. Les choses seront plus claires avec des exemples. Si nous notons par x un nombre entier quelconque. x peut donc prendre comme valeur 0, 1, 2 etc. nous pouvons définir la fonction f comme suit :

Ne vous laissez pas impressionner par la notation. f est le petit nom donné à la fonction, la lettre x à gauche de la flèche désigne l’argument de la fonction et à droite se trouve sa définition. En donnant une valeur spécifique au paramètre, par exemple 1 nous obtenons :

Si x vaut 3 la valeur retournée par la fonction est :
Au vu de ces valeurs il est aisé de comprendre que cette fonction double la valeur qu’on lui passe en paramètre. Renommons la fonction afin de mieux exprimer cette intention :

Le langage Scala est utilisé dans la suite pour illustrer nos propos. Et la fonction double est codée en Scala comme suit :

def double(number: Int) = 2 * number
Dans le code ci-dessus le mot clé def permet de définir une fonction. Il est suivi du nom de la fonction. J’ai choisi, à la place du paramètre x, un nom plus parlant : number. L’annotation Int (pour Integer) spécifie au compilateur que le paramètre number est un entier. Le reste du code est une traduction parfaite du pseudo code.

Les sorties suivantes de la console interactive (REPL) de Scala permettent de tester notre fonction :

$ scala
scala> def double(number: Int) = 2 * number
double: (number: Int)Int
scala> double(3)
res0: Int = 6
scala> double(1)
res1: Int = 2

Une fonction peut avoir plusieurs arguments par exemple la fonction faisant la somme de deux nombres entiers prend deux arguments. Soient x et y les deux entiers dont nous souhaitons faire la somme, la fonction add est définie comme suit :

Cette définition se traduit aisément en Scala de la façon suivante :
def add(x:Int, y:Int) = x + y
Le test de la fonction donne :
$ scala
scala> def add(x:Int, y:Int) = x + y
add: (x: Int, y: Int)Int
scala> add(1, 2)
res0: Int = 3

Et si nous souhaitions définir une fonction qui incrémente un entier nous pouvons réutiliser la fonction add. En effet incrémenter un entier revient à lui ajouter 1 :

def increment(number: Int) = add(number, 1)
En action cela donne:
$ scala
scala> def increment(number: Int) = add(number, 1)
increment: (number: Int)Int
scala> increment(3)
res1: Int = 4
scala> increment(10)
res2: Int = 11

Note : Une propriété importante de chacune des fonctions que nous avons vues jusque là est le fait que la valeur de retour est entièrement déterminée par les arguments de la fonction.

Munis de ces informations passions aux fonctions d’ordre supérieur.

Les fonctions d’ordre supérieur

Une fonction d’ordre supérieur est une fonction qui a au moins l’une des deux caractéristiques suivantes :

  • prend en paramètre une ou plusieurs fonctions
  • sa valeur de retour est une fonction

Les fonctions d’ordre supérieur aident à l’expressivité du code en mettant l’attention sur la tâche à accomplir plutôt que sur la façon de l’accomplir : le code dévient ainsi plus déclaratif. Cela devient plus clair avec un exemple. Considérons la classe Person ci-dessous :

public class Person {
 private final String name;
 private final String email;
 private final int age;

 public Person(String name, String email, int age) {
  this.name = name;
  this.email = email;
  this.age = age;
 }

 public String getName() {
  return name;
 }

 public String getEmail() {
  return email;
 }

 public int getAge() {
  return age;
 }
}
Supposons que vous disposez d’une liste d’objets de type Person sur laquelle vous souhaitez faire différentes opérations : transformation, filtrage etc. Commençons par la transformation de la liste.

Transformation des éléments d’une collection

Voici la liste initiale :

List<Person> persons = Arrays.asList(//
    new Person("Toto", "toto@email.com", 23), //
    new Person("John Doe", "john.doe@email.com", 34), //
    new Person("Mad Max", "mad.max@crazymail.com", 20), //
    new Person("Jane Doe", "jane@email.com", 17));
La première transformation qui nous intéresse est l’extraction des adresses email à partir de la liste des personnes. C’est ce que fait la méthode extractEmails :
public static List<String> extractEmails(List<Person> persons) {
 List<String> emails = new ArrayList<String>();

 for (Person person : persons) {
  emails.add(person.getEmail());
 }

 return emails;
}
Testons ce que cela donne :
System.out.println("Emails = " + extractEmails(persons));
Sortie de la console :
Emails = [toto@email.com, john.doe@email.com, mad.max@crazymail.com, jane@email.com]
On obtient une liste ayant la même taille que la liste des personnes mais ne contenant que les adresses email. Le code de la méthode extractEmails recèle quelques défauts dont la “dilution” de l’intention de la méthode dans du code verbeux.

Avant de voir comment résoudre ces défauts implémentons une autre fonctionnalité : extraire les noms à partir de la liste des personnes :

public static List<String> extractNames(List<Person> persons) {
 List<String> names = new ArrayList<String>();

 for (Person person : persons) {
  names.add(person.getName());
 }

 return names;
}

Cette méthode fait ressortir un autre défaut de notre code : la duplication. Les deux méthodes ne diffèrent véritablement que par la transformation effectuée à chaque itération sur l’élément de la liste initiale. Cette transformation peut être matérialisée par une fonction f qui prend comme argument un objet de type Person et retourne son nom ou son adresse email. Ainsi l’implémentation de l’une ou l’autre de nos fonctions se résume comme suit : "applique la fonction f à chaque élément de la liste initiale et renvoie-moi la liste correspondante."

Nous pouvons schématiser cette phrase de la façon suivante, avec à gauche la liste initiale et à droite la liste obtenue suite à la transformation :

Cela correspond exactement à ce que fait la fonction map. La figure ci-dessous donne le fonctionnement de la méthode map présente sur la classe List de Scala.

Comme mentionné sur la figure la fonction map prend en paramètre une fonction, celle que nous souhaitons appliquer à chaque élément de la liste initiale. Dans notre cas la fonction a comme type Person => String. Nous allons maintenant réimplémenter nos deux méthodes en utilisant la méthode map disponible dans l'API des listes Scala.

Les fonctions extractEmails et extractNames revisitées

Définition de la classe Person :

case class Person(name: String, email: String, age: Int)
Nous définissons d’abord la fonction qui extrait une adresse email à partir d’une instance de Person :
     
def extractEmail(person: Person) = person.email
Puis nous passons cette fonction à la méthode map de la liste afin de récupérer la liste des adresses email.
def extractEmails(persons: List[Person]): List[String] = persons.map(extractEmail)
Sur le même principe voici la définition de la fonction extractNames :
     
def extractName(person: Person) = person.name
def extractNames(persons: List[Person]): List[String] = persons.map(extractName)
Note : Grâce aux fonctions anonymes nous pouvons nous passer des fonctions extractEmail et extractName qui n’ont pas grand intérêt.
   
def extractNames(persons: List[Person]): List[String] = persons.map(p => p.name)
def extractEmails(persons: List[Person]): List[String] = persons.map(p => p.email)

Qu'avons-nous gagné par rapport à avant ? Le code est plus expressif en éliminant le bruit et en mettant l’accent sur l’intention du code : "mapper chaque élément de la liste sur son application à la fonction que nous passons à la méthode map". Les fonctions d’ordre supérieur rendent pratique une autre opération courante sur les collections : le filtrage.

Filtrer une collection

Nous disposons d’une liste de nombres entiers allant de 1 à 15 et nous souhaitons filtrer cette liste en éliminant tous les éléments qui ne sont pas des multiples de 3. Ce genre d’opération est résolu en programmation fonctionnelle avec la fonction d’ordre supérieur filter. Elle prend en arguments une liste et un prédicat, une fonction qui retourne "vrai" ou "faux". Dans notre exemple le prédicat retourne “vrai” si son argument est un multiple de 3 et "faux" dans le cas contraire. Scala étant un langage orienté-objet filter est une méthode de List. Voici la définition du prédicat :

scala> def isMultipleOfThree(number: Int) = number % 3 == 0
isMultipleOfThree: (number: Int)Boolean
scala> isMultipleOfThree(2)
res0: Boolean = false
scala> isMultipleOfThree(6)
res1: Boolean = true
Et la liste de nombres :
scala> val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
numbers: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
Le filtrage s’effectue simplement en passant la fonction isMultipleOfThree à la méthode filter de la liste de nombres :
scala> val multiplesOfThree = numbers.filter(isMultipleOfThree)
multiplesOfThree: List[Int] = List(3, 6, 9, 12, 15)
Ceci peut être réécrit en remplaçant isMultipleOfThree par une fonction anonyme :
scala> numbers.filter(number => number % 3 == 0)
res2: List[Int] = List(3, 6, 9, 12, 15)
Nous allons maintenant combiner filter et map.

Combiner filter et map

Nous souhaitons obtenir la somme des doubles des multiples de 3 compris entre 1 et 15. Cela correspond à une opération de filtrage (suppression des nombres non multiples de 3) suivie d’une transformation des éléments (doublement des éléments des éléments restants) et enfin une opération de réduction (la sommation). On y arrive aisément avec le code suivant :

scala> val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
numbers: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
scala> numbers.filter(number => number % 3 == 0).map(number => number * 2).sum
res7: Int = 90
Il nous reste une dernière fonction d’ordre supérieur à découvrir avant de conclure cet article : la fonction fold.

La fonction fold, le couteau suisse

La fonction fold est un véritable couteau suisse. Elle réduit les éléments d’une liste en une valeur. Cette fonction existe en deux versions : l’une (foldLeft) parcourt la liste de la gauche vers la droite et l’autre de la droite vers la gauche (foldRight). Nous allons plutôt utiliser la première dont voici la signature :

def foldLeft[B](z: B)(f: (B, A) ⇒ B): B
C’est une fonction curryfiée. Elle prend une valeur initiale de type B, désignée par z et une fonction f prenant deux arguments de types A (le type des éléments de la liste) et B. Pour chaque élément de la liste la fonction f est invoquée. f est invoquée avec la valeur initiale z fournie à la méthode foldLeft. Puis la valeur résultante est passée avec le deuxième élément de la liste à la fonction f. Ce processus continue avec tous les éléments de la liste. Pensez à lire cet article si vous souhaitez en savoir davantage. Place à l’action ! Afin de comprendre comment fonctionne foldLeft nous allons résoudre trois petits problèmes. Le premier problème consiste à faire la somme des éléments d’une liste d’entiers. La valeur initiale dans le cas de la somme est 0 (l’élément neutre de l’addition) et la fonction f additionne ces deux paramètres. Voici ce que cela donne dans le REPL :
scala> val nums = List(1, 2, 3, 4)
nums: List[Int] = List(1, 2, 3, 4)
scala> val sum = nums.foldLeft(0)((acc, num) => acc + num)
sum: Int = 10     
scala> val nums2 = List(1, 3, 5, 7)
nums2: List[Int] = List(1, 3, 5, 7)
scala> val sum2 = nums2.foldLeft(0)((acc, num) => acc + num)
sum2: Int = 16
Simple non ?! Ne nous arrêtons pas en si bon chemin continuons sur le deuxième problème : faire le produit des éléments d'une liste. La valeur initiale passée à foldLeft dans ce cas est l’élément neutre de la multiplication à savoir 1. Quant à la fonction à passer foldLeft elle fait le produit de ces deux paramètres.
     
scala> val nums = List(1, 2, 3, 4)
nums: List[Int] = List(1, 2, 3, 4)
scala> val prod = nums.foldLeft(1)((acc, num) => acc * num)
prod: Int = 24
scala> val nums2 = List(1, 3, 5, 7)
nums2: List[Int] = List(1, 3, 5, 7)
scala> val prod2 = nums2.foldLeft(1)((acc, num) => acc * num)
prod2: Int = 105
So far so good! Maintenant résolvons le dernier exercice pour la route. Il s’agit de construire à partir d’une liste d’entiers une map dont les clés sont les éléments pairs de la liste et les valeurs leurs doubles. Voyons un exemple afin de clarifier les choses :
List(7, 2, 10, 3, 6) -> Map(2 -> 4, 10 -> 20, 6 -> 12)
La valeur initiale est une map vide. La fonction passée à foldLeft prend une map et un entier. Si l’entier est pair son double est mappé sur sa valeur. La fonction retourne la map résultante.
    
scala> val nums = List(1, 2, 3, 4)
nums: List[Int] = List(1, 2, 3, 4)

scala> val evenDoubled = nums.foldLeft(Map[Int, Int]()) { (acc, num) =>
| if (num % 2 == 0) acc + ((num, 2 * num)) else acc
| }
evenDoubled: scala.collection.immutable.Map[Int,Int] = Map(2 -> 4, 4 -> 8)

Pour conclure

Nous arrivons à la fin de cette introduction aux fonctions d’ordre supérieur. Elles sont particulièrement adaptées aux traitements sur des collections. Mais leur usage va au-delà des collections. Consultez la liste de références ci-dessous pour aller loin.

Références

Lire la suite...

lundi 9 septembre 2013

[Intro à Scala 2] Premiers pas avec Scala

Laisser un commentaire

Après une introduction générale à Scala et à son écosystème dans le premier article, nous allons installer Scala puis écrire nos premières lignes de code Scala afin de nous familiariser avec le REPL.

Télécharger Scala

Pour fonctionner Scala a besoin de Java. Vous devez donc vous assurer que Java est installé sur votre machine avant de procéder à l’installation de Scala. Dans cette série d’articles nous utiliserons la version 2.10.2 de Scala et cela requiert au moins la version 1.6 de Java. Commencez d’abord par vérifier la disponible de Java sur votre système avec la commande suivante :

$ java -version

En exécutant cette commande sur ma machine j’obtiens la sortie suivante :

$ java -version
java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457-11M4509)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)

Vous devez avoir une sortie similaire si Java est installé sur votre machine sinon rendez-vous à l’adresse http://www.java.com pour le télécharger.

Maintenant que vous avez installé Java procédons à l’installation de Scala. En fonction de votre plate-forme elle ne se fera pas de la même manière.

Windows

Allez à l’adresse http://www.scala-lang.org/download/2.10.2.html et cliquez sur le lien nommé scala-2.10.2.msi. Cela va télécharger un fichier qui permet d’installer Scala sur votre machine Windows. Une fois le téléchargement terminé il suffit de cliquer dessus et de suivre les différentes étapes de l’installation. Une fois l’installation terminée vous pouvez vérifier si cela a marché avec la commande :

$ scala -version

Vous obtiendrez une sortie similaire à :

$ scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL

Unix/Linux, Mac OS X et Cygwin

Téléchargez le fichier archive disponible à l’adresse http://www.scala-lang.org/files/archive/scala-2.10.2.tgz puis extrayez-le à l’endroit de votre choix. Sur ma machine je vais l’installer dans /usr/local/share.

$ cd /usr/local/share/
$ sudo wget http://www.scala-lang.org/files/archive/scala-2.10.2.tgz

Une fois le téléchargement terminé j’extrais les fichiers :

$ tar xvfz scala-2.10.2.tgz

Histoire de ne pas lier mon installation à une version particulière je crée un lien symbolique vers le dossier scala-2.10.2.

$ sudo ln -s /usr/local/share/scala-2.10.2 /usr/local/share/scala

Ensuite éditez par exemple votre fichier .bashrc pour lui ajouter les lignes suivantes :

SCALA_HOME=/usr/local/share/scala
export PATH=$PATH:$SCALA_HOME/bin

Enfin vous pouvez vérifier l’installation comme suit :

$ source ~/.bashrc
$ scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL

Que contient l’installation de Scala ?

Faisons le tour du propriétaire pour comprendre ce que contient notre installation de Scala. Pour cela je me place dans le dossier où est installé Scala puis je lance la commande tree :

$ cd /usr/local/share/scala
$ tree -d -L 2

Cela me donne la structure suivante :

$ tree -d -L 2
.
├── bin
├── doc
│   └── tools
├── examples
│   ├── actors
│   ├── monads
│   ├── parsing
│   ├── tcpoly
│   └── xml
├── lib
├── man
│   └── man1
├── misc
│   └── scala-devel
└── src

15 directories

Voici une brève description des dossiers ci-dessus :

  • bin : Ce dossier contient les programmes exécutables comme le compilateur de Scala scalac, le dé-compilateur scalap ou l'interpréteur scala. Lors de l’installation ce dossier a été ajouté au chemin où le système d’exploitation cherche les commandes que nous tapons dans le terminal. Ainsi nous n’avons pas besoin de taper le chemin complet des exécutables.
  • doc : Ce dossier contient de la documentation sur les commandes localisées dans le repertoire bin.
  • examples : Ici vous trouverez des exemples de programmes écrits en Scala. Faites-y un tour afin de voir à quoi ressemble la syntaxe de Scala ou pour trouver de l’inspiration.
  • lib : C’est là que résident les librairies c’est-à-dire un ensemble de fonctions et de classes prêtes à l’emploi que vous pouvez utiliser pour écrire vos propres programmes.
  • man : Le contenu de ce dossier est utilisé par la commande man qui affiche l’aide sur des commandes comme scala ou scalac. Essayez ça :
    $ man scala
    
  • src : Le code source de Scala et des librairies se trouvent ici.
  • misc : Ce dossier est, j’ai envie de dire, sans grand intérêt pour nous. A ce jour il contient le plugin pour la contituation.

Premiers pas avec l’interpréteur de Scala ou le REPL

Comme vous allez vous en rendre l’interpréteur de Scala est un outil puissant pour expérimenter des choses et accélérer son apprentissage du langage. Vous avez un doute et hop lancez l’interpréteur pour le lever ! Vous avez une idée et hop l’interpréteur est là pour la tester.

Et pour lancer l’interpréteur rien de plus simple que de taper la commande scala dans une console :

$ scala
Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_51).
Type in expressions to have them evaluated.
Type :help for more information.
scala>

Vous voilà dans l’interpréteur prêt à taper des commandes. Tapez un nombre et appuyez sur la touche Enter du clavier pour voir.

scala> 20
res0: Int = 20

Le nombre 20 sur la première ligne correspond à ce que j’ai tapé et la deuxième ligne à ce que me répond l’interpréteur. Que s’est-il passé ? L’interpréteur a récupéré ce que j’ai tapé (ici 20), l’a évalué puis a affiché le résultat en lui donnant le nom res0 (pour résultat numéro 0) et la valeur 20. Désormais res0 contient le nombre 20. Pour vous en convraincre tapez res0 dans l’interpréteur :

scala> res0
res1: Int = 20

Note : Notez que le nom res0 est suivi de “: Int”. Cette annotation nous précise que le nom res0 contient un entier. Nous reviendrons sur ce point dans la suite.

Recommençons avec une opération un peu plus compliquée : l’addition de deux nombres, par exemple 2 + 7.

scala> 2 + 7
res2: Int = 9

Là encore le REPL a évalué ce que nous avons tapé puis a affiché le résultat.

Il est aussi possible de réutiliser le résultat d’une opération précédente :

scala> res2 + 2
res3: Int = 11
scala> res3 - 8
res4: Int = 3

En dehors du code Scala l’interpréteur de Scala accepte aussi d’autres commandes dont la plus importante est :help. Elle vous listera la liste des commandes disponibles. Pour l’instant je mets l’accent sur trois commandes seulement dont voici la description :

  • :cp : Cette commande vous permet d’utiliser depuis le REPL du code situé dans un fichier archive Java (avec l’extension .jar) ou dans un répertoire.
  • :quit : Celle-là est utilisée pour quitter le REPL. Eh oui il faut pouvoir en sortir !
  • :paste : Cette commande s’avère assez pratique quand on écrit du code sur plusieurs lignes dans le REPL.

Même si le REPL est symphatique comme calculatrice elle peut faire bien plus comme afficher un message sur l’écran par exemple.

scala> println("Bonjour ! Ça se passe bien jusque là ?")
Bonjour ! Ça se passe bien jusque là ?

Essayez la même chose chez vous, n’hésitez pas à changer le message. Ici nous avons utilisé la fonction println pour afficher notre message à l’écran. Nous verrons dans la suite ce qu’est une fonction mais si vous êtes pressé de le savoir lisez cet article.

Résumé et programme pour la suite

Mine de rien nous avons déjà fait beaucoup de choses. Nous avons installé Scala, appris à lancer le REPL et à le faire exécuter du code Scala pour nous. Dans le prochain article nous nous baserons sur ces connaissances pour apprendre de nouveaux concepts et nous initier à la syntaxe de Scala.

Lire la suite...

samedi 7 septembre 2013

Introduction à Scala - Episode 1

Laisser un commentaire

Scala est un langage qui a du caractère. Il fait réagir du monde; ceux qui l’ont essayé et l’ adorent, ceux qui ne l’ont jamais essayé mais le détestent et les autres. Parmi ce beau monde les plus étonnants sont ceux qui veulent accuser Scala des travers des langages (comme le C++) qu’ils ont aimé détester. Au lieu de vous laisser influencer par les autres essayez par vous-même ce langage qui a fait le pari audacieux de marier les paradigmes fonctionnel et orienté objet.

A propos de cette série d’articles

Je souhaite à travers une série d’articles introduire le langage de programmation Scala. Cela a un double intérêt pour moi. D’une part ce sera l’occasion pour moi d’approfondir ma connaissance du langage et d’autre part j'accompagne les premiers pas de ceux qui souhaitent l’apprendre.

D’où vient Scala et que propose-t-il ?

Scala est un langage de programmation créé par Martin Ordersky professeur à l’École Polytechnique Fédérale de Lausane EPFL en Suisse. Sa première version est rendue publique en 2003. Son nom vient de l’abréviation de “scalable language” signifiant qu’il est capable de s’adapter aux contraintes de passage à l’échelle (scalabilité) du développeur en lui fournissant des “abstractions” et des constructions à cet effet. La particularité de Scala est qu’il intègre à la fois les paradigmes de programmation fonctionnel et orienté objet. Il est statiquement typé et s’exécute sur la machine virtuelle Java (JVM).

Dans la suite de la série je reviendrai plus en détail sur ces deux paradigmes. Le point clé de ce mariage entre les paradigmes orienté objet et fonctionnel est qu’il vous offre plus d’options pour résoudre vos problèmes. Les différentes possibilités d’extension du langage facilitent l’expression de logiques métier complexes et de produire du code qui s’intègrent d’une manière élégante au reste du langage. La bibliothèque standard de Scala est un bon exemple de cette puissance expressive.

Un autre aspect de Scala est qu’il dispose d’une inférence de type qui allège le code et en réduit fortement la verbosité. C’est agréable et on a parfois l’impression de travailler avec un langage dynamique.

Scala vient avec un interpréteur qui porte le doux nom de REPL pour Read-Eval-Print-Loop. Comme vous l’avez peut-être deviné le REPL vous laisse taper du code dans une console, l’évalue, affiche le résultat et attend de nouveau que vous tapiez quelque chose. Vous pouvez vous servir du REPL pour tester rapidement vos idées et faire du prototypage. Il est idéal pour apprendre le langage et nous ne manquerons pas de nous en servir pour cela.

Quel écosystème pour Scala ?

La plate-forme Java est aujourd’hui très mature et bien introduite en entreprise. Les outils et les librairies sont nombreuses et matures. En outre les développeurs Java se comptent en milliers. Scala tire pleinement partie de cette maturité et de la puissance qu’elle confère à Java en s’intégrant facilement avec le langage Java. Un programme écrit en Scala peut accéder à n’importe quel code écrit en Java et tourne, après compilation, sur la machine virtuelle Java.

Au-delà de la force que lui confère Java, l’écosystème de Scala compte de nombreux projets et outils emblématiques dont voici quelques uns :

  • Akka : Akka propose un ensemble d’outils pour créer des applications concurrentes et distribuées. Il utilise les acteurs comme modèle de programmation.
  • Play : Un framework pour la création d’applications web
  • Scalding : Une librairie Scala qui rend facile la spécification des tâches Hadoop.
  • Specs2 et ScalaTest : Des librairies de test populaires écrits en Scala.
  • Spray : Basé sur Akka, Spray propose des interfaces de programmation (API) pour écrire des applications HTTP performantes

Les outils, les outils !

Commençons par les outils de build. Un projet Scala peut être buildé par les outils de build majeurs en Java : Maven, Gradle et Apache buildr. En outre il existe un autre outil, SBT (Simple Build Tool), écrit en Scala pour builder des projets Scala et Java. SBT est utilisé par des projets comme Akka, Play, Spray etc.

Eclipse, Netbeans et Intellij ont des plugins pour l’intégration Scala. Il est aussi possible d’utiliser d’autres environnement comme Sublime Text, emacs, vim etc.

Autres ressources pour apprendre à programmer en Scala

Il existe d’autres ressources disponibles gratuitement sur Internet pour apprendre à programmer en Scala. Voici une liste non exhaustive de certaines de ces ressources :

  • http://docs.scala-lang.org : Un site plutôt bien fait et assez complet pour apprendre le langage. Vous y trouvez une quantité incroyable d’information.
  • La première édition du livre écrit par Odersky, créateur de Scala, est en accès libre en ligne à cette adresse : http://www.artima.com/pins1ed/.
  • Scala School par Twitter : Twitter a publié une introduction rapide à Scala. Vous pouvez y jeter un coup d'oeil en allant à l’adresse http://twitter.github.io/scala_school/.
  • Martin Odersky donne un cours d’introduction à la programmation fonctionnelle à travers Scala sur https://www.coursera.org. Environ 50 000 personnes se sont inscrites à la première édition du cours. Faites sur un tour sur coursera afin de vous renseigner sur les éditions à venir.

J’ai besoin de vous !

N’hésitez pas à réagir à ce que j’écris ici ou à me corriger à travers les commentaires et à me faire des suggestions sur le contenu et la forme des articles.

C’est quoi la suite ?

Dans le prochain nous allons installer Scala et faire nos premiers avec le REPL. Ce sera pour vous l’occasion d’écrire du code Scala.

Le deuxième article a été publié.

Lire la suite...

dimanche 20 janvier 2013

Installer Scala sous Linux

Laisser un commentaire

Dans ce court post je partage comment j'installe Scala sur mon PC tournant sous Ubuntu. Commencez d'abord par télécharger depuis le site web de Scala le fichier archive (au format .tgz) de la dernière version du langage : http://www.scala-lang.org/downloads. La version actuelle de Scala est la 2.10 et c’est celle que nous allons installer.

Voici comment l'obtenir via la ligne de commande :

$ wget http://www.scala-lang.org/downloads/distrib/files/scala-2.10.0.tgz
Ensuite nous extrayons le contenu du fichier archive :
$ tar xvfz scala-2.10.0.tgz
Les fichiers sont extraits dans le dossier scala-2.10.0. La sortie suivante de la commande tree montre la structure des fichiers.
$ cd scala-2.10.0
$ tree -L 1
.
├── bin
├── doc
├── examples
├── lib
├── man
├── misc
└── src

Les exécutables se trouvent dans le dossier bin et les librairies dans le dossier lib. Sur mon ordinateur les fichiers se trouvent dans ~/tools/scala-2.10.0 sur lequel j’ai créé le lien symbolique /opt/scala puisque je souhaite pouvoir changer facilement de version de Scala.

$ sudo ln -s ~/tools/scala/scala-2.10.0 /opt/scala

Vérifions l’installation en affichant la version de Scala :

$ /opt/scala/bin/scala -version
Scala code runner version 2.10.0 -- Copyright 2002-2012, LAMP/EPFL
Ça marche mais ce n’est pas pratique de taper le chemin complet de la commande à chaque lancement de l’interpréteur Scala. Afin de corriger cela j’ajoute le dossier /opt/scala/bin au chemin du système avec la commande suivante :
$ export PATH=$PATH:/opt/scala/bin
En mettant la ligne précédente dans le fichier .bashrc les exécutables se trouvant dans /opt/scala/bin seront ajoutés au chemin du système à l’ouverture d’une session.
$ scala
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.
scala> println ("Now go play with Scala !")
Now go play with Scala !

Lire la suite...