oct 3 09

Popularité de Scala (2/2) (TIOBE)

by Laurent Mallet

Après une analyse dans un précédent article réalisée avec l’aide de Google Trends et Job Trends, il peut être judicieux d’étudier les résultats du TIOBE Software Index de septembre 2009 pour en déduire quelques tendances sur Scala:

  • Scala est 32ème de ce classement avec 0.238%;
  • Scala est toute de même devant Erlang et Haskell;
  • Scala est devant groovy et clojure;
  • Ruby et Python sont loin devant (jruby et jpython sont inclus dans Ruby et Python);
  • Java est premier;

Autre élément intéressant, les langages fonctionnels ont le vent en poupe avec une progression de 0.7% par rapport à 2008. Le typage dynamique ou statique n’a quant à lui quasiment pas évolué.

Historique de Scala dans TIOBE:

  • 2004 : Scala n’apparait pas;
  • 2005 : Scala apparait entre la 50 et la 100ème place ( resultat < 0,07%)
  • 2006 : Scala entre la 50 et la 100ème place (langage fonctionnel 1% et langages typés statiques  65%)
  • 2007 : toujours entre 50 et 100 (langage fonctionnel 0.9% et langages typés statiques 59%)
  • jan 2008 : Scala 45ème avec 0.1% (langage fonctionnel 1.8% et langages typés statiques 57%)
  • aujourd’hui Scala 32ème avec 0.238% (langage fonctionnel 2.9% et langages typés statiques 58%)

Lentement mais surement Scala progresse.

Détails :

oct 3 09

Complétion maven pour zsh

by Maxime Biais

A ma grande déception zsh ne complète pas la commande maven. A force de taper des commandes mvn qqhcose, j’en avais assez, j’ai donc fait un petit script pour compléter les commandes que j’utilise le plus souvent avec maven et le plugin Scala :

function mainClasses {
    if [ -d ./src ] ; then
	find ./src/main -type f -iname "*.scala"  -o -iname "*.java" \
             | sed 's?.*src/main/[^/]*/\(.*\)\..*?-DmainClass=\1?' | sed 's+/+.+g'
    fi
}
 
function mainTests {
    if [ -d ./src ] ; then
	find ./src/test -type f -iname "*test*.scala"  -o -iname "*test*.java"  \
             | sed 's?.*src/test/[^/]*/\(.*\)\..*?-Dtest=\1?' | sed 's+/+.+g'
    fi
}
 
function listMavenCompletions {
reply=(archetype:generate compile clean package install test
    test-compile deploy release scala:run scala:cc
    -Dmaven.test.skip=true
    -DarchetypeCatalog=http://www.scala-tools.org/
    `mainClasses`
    `mainTests`
    -q -o
    );
 
}
 
compctl -K listMavenCompletions mvn%

Le script n’est pas idéal mais il permet de compléter les commandes que j’utilise le plus souvent mais aussi les -Dtest= et -DmainClass= automatiquement en listant les fichiers de l’arborescence de votre projet. L’ideal serait d’avoir une option dans maven pour lister les commandes disponibles, mais ça n’existe pas à ma connaissance.

Si vous utilisez d’autres commandes maven, ajouter les dans la liste reply (séparer par des espaces ou saut de lignes).

Vous pouvez copier ce script dans votre ~/.zshrc.

oct 2 09

Interêt du Type Symbol en Scala

by Maxime Biais

Présentation du type Symbol

La classe Symbol est une classe de la bibliothèque standard du langage Scala. Il permet de façon simple de créer un objet unique pour une chaîne de caractères donnée. La comparaison de 2 symbols est une simple comparaison de références. On dit que l’objet est interné.

Pour simplifier son usage, le compilateur Scala reconnait l’instanciation d’un Symbol pour tous les identifiants préfixés par un simple quote '.

Exemple d’utilisation :

Symbol("test") == 'test

Interêt

Les symbols sont des éléments indispensable pour un langage tel Lisp qui les utilise pour représenter toutes sortes d’objet : classe, méthodes, variables, etc… Lisp permet de mélanger code et donnée de façon totalement transparente et des manipuler les uns ou les autres de la même manière. En Lisp, Les symbols sont aussi utilisés par exemple pour imiter des énumérations.

En Scala il est impossible d’utiliser les symbols pour identifier une méthode par exemple (comme ce que l’on ferait en Lisp). Les symbols perdent donc pas mal de leur interêt…

On pourrait se dire qu’en utilisant des symbols comme identifiants, on peut gagner de la place par rapport à des chaînes de caractères, mais alors pourquoi ne pas utiliser directement un enum, ou dans des cas plus évolué une case class ? C’est peut être intéressant pour gagner du temps, cela évite de déclarer un enum. Ou bien une utilisation dans une table de hashage comme identifiants à la place de string, mais là encore même chose, les strings litérales (cad définies via le biais de double quote, "ma chaine") sont internées (voir suite de l’article) et donc cela ne prend pas plus de mémoire et les comparaisons sont aussi rapides.

Et surtout si vous trouvez un avantage majeur à utiliser les Symbols, postez un commentaire, je suis curieux de trouver un vrai cas d’utilisation.

Exemple décompilé

La suite de l’article s’adresse à ceux qui cherchent à voir en détails ce qui se passe dans la machine virtuelle. Le but est de comprendre comment est représenté une string litteral comment le compilateur les interne.

Source d’un exemple tout simple en scala

class SymbolTest {
    def run = {
        "test" == "test"
    }
}

Décompilation avec la commande javap

$ javap -c -verbose scalafr.StringTest

Cette commande produit la sortie suivante (j’ai supprimé les lignes qui ne sont pas pertinentes à la démonstration) :

[...]
// Pool de constantes
const #7 = Asciz	java/lang/Object;
const #8 = class	#7;	//  java/lang/Object
[...]
const #13 = Asciz	test;
const #14 = String	#13;	//  test
const #15 = Asciz	equals;
const #16 = Asciz	(Ljava/lang/Object;)Z;
const #17 = NameAndType	#15:#16;//  equals:(Ljava/lang/Object;)Z
const #18 = Method	#8.#17;	//  java/lang/Object.equals:(Ljava/lang/Object;)Z
[...]
{
public scalafr.StringTest();
[...]
// Code de la méthode run()
public boolean run();
  Code:
   0:	ldc	#14; //String test
   2:	ldc	#14; //String test
   4:	astore_1
   [...]
   17:	aload_1
   18:	invokevirtual	#18; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z
   [...]

La commande ldc prend une référence du pool de constantes et la pose sur la pile d’opérande. Le pool de constantes est représenté au dessus du code, ldc #14va chercher const #14 et la pose sur la pile. La ligne 18 invoque la méthode réprésenté par #18 (dans ce cas, java.lang.Object.equals()) en utilisant les 2 derniers éléments posés sur la pile (les ldc des lignes 19 et 20. On remarque que ces deux ldc charge la même réference de constante : #14 qui représente la chaîne de caractère « test », c’est ça l’internement de string litérales.

Pour aller plus loin :

sept 27 09

Initialiser un nouveau projet Scala avec Maven 2

by Maxime Biais

Introduction

Dans un précédent article, nous vous présentions sbt. Cette fois nous allons voir comment gérer un projet Scala avec maven.

Le plus simple, c’est de démarrer de zéro, et d’initialiser un projet en utilisant un archetype prédéfini. Cet archetype est un template de projet qui contient le minimum pour démarrer :

  • La structure de répertoire de projet
  • Le pom.xml
  • Des fichiers sources quasiment vide (un main(), et un test pour scala-archetype-simple)

Initialisation d’un projet

Pour l’initialisation d’un projet nous allons utiliser le plugin maven archetype (disponible dans le repository officiel de maven). Nous allons passer en paramètre de ce plugin, un lien vers une liste d’archetype : scala-tools (pour le moment, seul site à proposer des archetypes pour Scala).

$ mvn archetype:generate -DarchetypeCatalog=http://scala-tools.org
    [...]
    Choose archetype:
    1: http://scala-tools.org -> scala-archetype-simple (A simple scala project)
    2: http://scala-tools.org -> lift-archetype-blank (A blank/empty liftweb project)
    3: http://scala-tools.org -> lift-archetype-basic (A basic liftweb project (with DB, css, ...))
    Choose a number:  (1/2/3): 1

Le plugin va ensuite vous posez quelques questions pour générer le pom.xml. Sélectionner le projet scala de base (1) à moins que vous soihaitiez faire du lift.

Le projet ainsi initialisé contient déjà quelques dépendances et quelques plugins pratiques pour une bonne gestion d’un projet Scala :

Quelques actions de maven-scala-plugin

Les goal maven classiques sont biensûr fonctionnels (compile, package, release, …).

Le goal scala, propose différentes actions notamment :

  • Lancer une application

    $ mvn scala:run -DmainClass=org.example.MyClass
    
  • Générer la documentation de l’API

    $ mvn scala:doc
    
  • Lancer le mode compilation continue (lance une boucle infinie qui compile toutes les sources qui sont sauvegardées, très pratique si vous développez avec un éditeur de texte simple type emacs ou vi)

    $ mvn scala:cc
    

Note pour les utilisateurs d’emacs : vous pouvez passer en compilation-mode avec cette astuce pour lancer maven, puis lancer mvn scala:cc, je vous conseil aussi d’ajouter cette ligne dans votre .emacs.el : (setq compilation-scroll-output t) pour enclencher le scrolling automatique de la fenetre de compilation. Avec ça (et les ctags pour la complétion), vous pouvez jeter Eclipse et NetBeans ;) . Vous pouvez aussi utiliser le flymake-mode beaucoup plus pratique mais malheuresement un peu lent à cause de l’utilisation de maven en arrière plan.

Je n’ai rien contre Eclipse ou Netbeans, mais mon process emacs ne dépasse jamais 30Mo de RAM et il ne s’arrête pas inopinément.

Plus de détails sur la page de documentation de maven-scala-plugin.

Ajouter des dépendances

C’est du maven classique. Pour ajouter une dépendance, éditer votre fichier pom.xml et ajouter les groupId / artifactId / version dont vous avez besoin dans project->dependencies. Si je veux par exemple ajouter la dépendance vers scalacheck, il me suffit d’ajouter :

<dependencies> 
[...] 
  <dependency> 
    <groupid>org.scala-tools.testing</groupid> 
    <artifactid>scalacheck</artifactid>
    <version>1.5</version>
  </dependency>
[...]
</dependencies>

Note : ScalaCheck est disponible sur le repository maven scala-tools (ajouté par défaut à l’initiation du projet avec l’archetype scala-archetype-simple).

Démonstration

Une démonstration de l’utilisation de mvn dans emacs, en utilisant mvn archetype:generate pour initialiser un projet exemple.

sept 25 09

sbt : Scala Build Tool ou comment compiler son projet Scala

by Maxime Biais

Introduction

sbt signifie Scala Build Tool. Encore un outils de compilation ? ant, maven ne suffisent pas ?

sbt se veut non intrusif : vous pouvez l’utiliser sans modifier la disposition de votre projet, uniquement en modifiant un descripteur (ce descripteur est écrit en Scala, un peu comme scons pour Python ou rake en Ruby). Pour cela il se base sur le même format de projet que maven.

src/
  main/
    resources/  # Fichiers à inclure dans le jar principal
    scala/      # Sources Scala
    java/       # Sources Java
  test/
    resources   # Fichiers à inclire dans le jar de test
    scala/      # Sources de Test Scala
    java/       # Sources de Test Java

Son principal intérêt est d’intégrer des outils liés à Scala sans avoir besoin de configurer quoique ce soit:

  • Génération de documentation avec scaladoc.
  • Tests unitaires avec ScalaTest.
  • Génération de tests unitaires avec ScalaCheck.
  • Intégration de specs, framework de behavior driven development.

sbt se base sur maven par défaut pour gérer les dépendances.

Installer sbt

Malheuresement sbt n’est pas packagé dans sbaz. Il vous faudra le télécharger et l’installer à la main.

Pour cela, rien de plus simple, télécharger la dernière version de sbt-launcher.jar sur la page de téléchargement de sbt.

Puis créer un script shell dans votre PATH, chez moi ça donne ça :

$ echo $PATH
/sw/bin:/sw/sbin:/Users/max/dist/sbin
$ wget http://simple-build-tool.googlecode.com/files/sbt-launcher-0.5.4.jar -O /Users/max/dist/sbin/sbt-launcher.jar
$ echo 'java -Xmx512M -jar `dirname $0`/sbt-launcher.jar "$@"' > /Users/max/dist/sbin/sbt
$ chmod +x /Users/max/dist/sbin/sbt

sbt est installé, vous pouvez le l’utiliser.

Utiliser sbt

sbt se lance en mode interactif ou en mode batch. Le mode batch permet de lancer une suite de tâches les unes à la suite des autres. Le mode interactif lance un shell particulier vous permettant de taper des commandes particulières (tâches ou autres).

Lorsque vous lancer sbt dans un répertoire qui ne contient pas les descripteurs, il va vous proposer de créer une structure de projet.

Créer un projet

Lancer sbt sans arguments dans le répertoire où vous souhaitez créer votre projet:

$ mkdir sbttest
$ sbt
Project does not exist, create new project? (y/N/s) : y
Name: SbtTest
Organization []: scala-fr
Version [1.0]: 
Scala version [2.7.5]: 
sbt version [0.5.3]: 
[...]
[success] Successfully initialized directory structure.

Voilà, la structure de projet est créée, voici à quoi elle ressemble :

$ \tree
|-- lib
|-- project
|   |-- boot
|   |   `-- scala-2.7.5
|   |       |-- lib
|   |       |   |-- scala-compiler.jar
|   |       |   `-- scala-library.jar
|   |       |-- sbt-0.5.3
|   |       |   |-- ivy-2.0.0.jar
|   |       |   |-- jsch-0.1.31.jar
|   |       |   `-- sbt_2.7.5-0.5.3.jar
|   |       `-- update.log
|   `-- build.properties
|-- src
|   |-- main
|   |   |-- resources
|   |   `-- scala
|   `-- test
|       |-- resources
|       `-- scala
`-- target

Mode interactif

Si vous le lancer sans arguments dans un répertoire projet, il démarre en mode interactif:

$ sbt
[info] Building project xxx 0.1 using XXX
[info]    with sbt 0.4.6 and Scala 2.7.4
[info] No actions specified, interactive session started. Execute 'help' for more information.
>

Un shell sbt est ouvert, vous pouvez tapez vos commandes.

Mode batch

En mode batch vous lancer directement les tâches (Consulter la liste exhaustive des tâches)

Exemple, je viens d’écrire du code (un simple println("hey !")dans le fichier src/main/scala/sbttest.scala, je lance la tâche run:

$ sbt run
[info] Building project SbtTest 1.0 using sbt.DefaultProject
[info]    with sbt 0.5.3 and Scala 2.7.5
...
[info] == compile ==
...
[info] == run ==
[info] Running RunSbtTest ...
hey !
...
[info] Total build time: 1 s

On s’aperçoit que la tâche run dépend de la tâche compile, et ça tombe bien ;) . Vous venez de compiler et de lancer votre premier projet Scala avec sbt et son projet par défaut (sbt.DefaultProject).

Conclusion

Ca sera tout pour cet article, il y a pas mal de possibilités qui n’ont pas été abordées ici. Elles le seront sûrement un peu plus en détails dans les futurs articles.

En apparence sbt simplifie tout. Pour les projets Scala simple, il sera sûrement parfaitement adapté, mais dès que vous commencez à dévier du chemin classique, ça devient plus complexe et mal documenté; c’est là que les ennuis commencent.

Même si vous avez l’habitude, et préférez utiliser maven; si vous êtes développeur Scala, vous aurez sûrement besoin d’installer sbt pour compiler des projets tiers. Ce sera une bonne occasion pour apprendre quelques commandes, le tester et vous en faire votre opinion.

En savoir plus:

sept 25 09

Popularité de Scala (1/2)

by Maxime Biais

Une question que je me pose en ce moment est de savoir si Scala est populaire, combien de développeurs l’utilisent au jour le jour, combien d’employés font du Scala dans leurs entreprises. Est-ce que la tendance grimpe ou tombe ?

Google trends permet de comparer des volumes de recherche sur un ensemble de mot clés. Les résultats comparatifs entre les principaux langages de JVM (parmis scala, jython, jrubyn clojure et groovy), donnent groovy en tête et scala en deuxième (le rapport entre groovy et scala est quasiment de 3 en moyenne sur les 12 derniers mois).

Graphique comparant Scala, Clojure, Jython, Jruby et Groovy

D’après le site officiel, Scala est utilisé chez Twitter, EDF Trading, Siemens pour les plus gros. En ce qui concerne les offres d’emplois jobtrends nous montre que Scala reste très discret par rapport à Jython et Groovy

scala clojure jython jruby groovy jobtrends comparison chart

Je ferais un autre article dans quelques mois pour voir s’il y a eut du changement.

sept 24 09

sbaz : Scala Bazaar System, gestionnaire de paquets

by Maxime Biais

Introduction

Le Scala Bazaar System, surnommé sbaz, est un gestionnaire de paquets permettant d’automatiser la tâche de maintenance d’une installation Scala. Cela permet:

  • De mettre à jour son installation et les dépendances
  • D’installer les bibliothèques enregistrées dans la base et leur dépendances
  • De partager vos propres bibliothèques

Quelques commandes

Après avoir installé Scala (voir la page télécharger), un environnement de base est installé, comprenant scalac (le compilateur Scala), la bibliothèque standard, sbaz et scalap (un inspecteur de fichiers class Scala permettant de lire les fichiers générés par le compilateur scalac). Pour vérifier votre installation vous pouvez taper la commande sbaz installed

$ sbaz installed
base/1.9
sbaz/1.25tmp
sbaz-setup/1.0
scala/2.7.5.final
scala-devel/2.7.5.final
scala-library/2.7.5.final
scala-tool-support/2.7.5.final
7 packages installed

sbaz help vous liste les possibilités offertes par sbaz. Parmis les commandes les plus souvent utilisées on trouve :

$ sbaz help
available - list the available packages for installation
[...]
install - install a package
installed - list the packages that are installed
[...]
showuniverse - show the active universe
update - update the list of available packages
upgrade - upgrade all possible packages

Par exemple, je viens de trouver ScalaCheck, une bibliothèque permettant de générer des tests unitaires (suivez le blog, un article devrait bientôt arriver à propos de ScalaCheck). Je lance la commande :

$ sbaz available | grep check
scalacheck (1.5, 1.4, 1.3, ...)

Parfait ! La bibliothèque est packagée dans scala-dev (l’univers par défaut), je peux l’installer directement en faisant :

$ sudo sbaz install scalacheck
planning to install: scalacheck/1.5
Installing...

Et voilà, je peux maintenant utiliser scalacheck.

Pour mettre à jour son installation Scala, rien de plus simple. Il suffit de :

  1. Mettre à jour sa liste de paquets (update)
  2. Mettre à jour sa distribution (upgrade)
$ sudo sbaz update
Updated the list of available packages.
$ sudo sbaz upgrade
Refreshing list of available packages...
Planning to install scala/2.7.6.final...
Planning to install scala-devel/2.7.6.final...
Planning to install scala-library/2.7.6.final...
Planning to install scala-tool-support/2.7.6.final...
Installing...

Je viens de passer en version 2.7.6.

Les univers

Les univers sont des lieux de dépôts (repository) de paquets. Ils doivent assurer que les dépendances entre les paquets et leurs versions sont consistantes. Chaque installation sbaz est lié à un univers actif duquel les paquets sont téléchargés. Il existe 2 univers officiels :

Pour connaître l’univers actif de votre installation taper la commande sbaz showuniverse

$ sbaz showuniverse
SimpleUniverse "scala-dev" (http://scala-webapps.epfl.ch/sbaz/scala-dev)

Dans mon cas, je suis sur la version stable.

Pour changer d’univers il faut utiliser la commande sbaz setuniverse. Commande à qui il faut donner en paramètre un fichier descripteur qui contient les informations de l’univers que vous souhaitez rendre actif. J’aurais aimé pouvoir lui donner directement une URL qui pointe vers ce descripteur, mais ce n’est à priori pas possible.

Example de fichier descripteur :

<simpleuniverse>
  <name>lamp-rc</name>
  <description>
    Scala release candidates
  </description>
  <location>http://scala-webapps.epfl.ch/sbaz/lamp-rc</location>
</simpleuniverse>

Note : les descripteurs pour scala-dev et lamp-rc sont disponibles dans votre SCALA_HOME ($SCALA_HOME/misc/sbaz/descriptors/lamp-rc et $SCALA_HOME/misc/sbaz/descriptors/scala-dev).

Changement d’univers vers lamp-rc :

$ sudo sbaz setuniverse $SCALA_HOME/misc/sbaz/descriptors/lamp-rc
Password:
Universe established.
$ sbaz available
sudo sbaz available
scala (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scala-android (2.7.0-RC3, 2.7.0-RC2, 2.7.0-RC1, ...)
scala-cldc (2.7.0-RC3, 2.7.0-RC2, 2.7.0-RC1, ...)
scala-devel (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scala-devel-docs (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scala-documentation (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scala-library (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scala-msil (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scala-swing (0.1)
scala-test (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scala-tool-support (2.7.4.RC1, 2.7.3.RC2, 2.7.3.RC1, ...)
scalap (2.7.1.RC2, 2.7.1.RC1, 2.7.0-RC3, ...)
12 package names
145 total packages

Pour revenir à l’univers stable:

$ sudo sbaz setuniverse $SCALA_HOME/misc/sbaz/descriptors/scala-dev
Password:
Universe established

Plus d’informations sur le site de sbaz.

sept 24 09

Environnement de développement Scala

by Maxime Biais

Il existe des plugins Scala pour les Environnement de Développement Intégrés (IDE) les plus connus :

  • Plugin Eclipse : C’est à mon avis la moins mauvaise solution. Eclipse n’est pas un trop mauvais IDE mais le plugin Scala n’est pas très stable (complétion de code assez aléatoire).
  • Plugin NetBeans : Je suis un peu hermétique à NetBeans, j’ai du mal à m’y mettre, mais objectivement j’ai l’impression que le plugin Scala fonctionne mieux que celui d’Eclipse. Les utilisateurs de NetBeans seront sûrement séduit par cette solution. Vous pouvez suivre son développement sur le blog de Caoyuan.
  • Plugin Intellij IDEA : Je n’ai pas testé mais il a de très mauvaises critiques ici et .

Pour ceux qui n’aiment pas les IDE, il existe des plugins de colorisation de code pour la plupart des éditeurs texte. TextMate et Emacs s’en sortent un peu mieux en offrant des Snippets (via YASnippet pour Emacs)  permettant de gagner un peu en productivité en laissant l’éditeur écrire pour soit. Pas de completion de code avancé ni pour l’un, ni pour l’autre.

sept 22 09

Hello World en Scala

by Maxime Biais

Un exemple de code Scala très simple:

 object HelloWorld extends Application {
   println("Hello, world!")
 }

Quelques détails:

  • object signifie que l’on souhaite créer une classe qui ne pourra être instanciée qu’une seule fois (une sorte de singleton)
  • extends Application permet d’hériter du trait Application (un trait est une classe virtuelle non pure, plus de détails dans un prochain post)

Plus de détails dans la traduction du tutoriel Scala pour les développeurs Java.

sept 22 09

Présentation de Scala

by Maxime Biais

D’après l’article Wikipédia à propos de Scala:

Scala est un langage de programmation multi-paradigme conçu à l’EPFL pour exprimer les modèles de programmation courants dans une forme concise et élégante. Son nom vient de l’anglais Scalable language qui signifie à peu près « langage adaptable » ou « langage qui peut être mis à l’échelle ».

Scala intègre les paradigmes de programmation orientée objet et de programmation fonctionnelle, avec un typage statique. Il concilie ainsi ces deux paradigmes habituellement opposés (à de rares exceptions près, telle que le langage OCaml) et offre au développeur la possibilité de choisir le paradigme le plus approprié à son problème.

Il est prévu pour être compilé en bytecode Java (exécutable sur la JVM), ou .Net. Ces deux plateformes sont supportées officiellement, mais d’autres plateformes pourront potentiellement être supportées dans le futur.