Scala est un langage de programmation très évolué. Il se compile en bytecode Java ou en .Net. La compatibilité avec Java est telle qu'il est possible d'utiliser des classes écrites en Java à partir de Scala et vice-versa.
Ce langage intègre de façon naturelle des fonctionnalités issues des langages orientés-objets et des langages fonctionnels. Les apports de la programmation fonctionnelle aux langages objets, plus répandus, sont multiples et deviennent rapidement indispensables une fois qu'on y est habitué.
En particulier, il est maintenant possible d'écrire des codes à la fois très concis, comme en Ruby ou Python, tout en ayant beaucoup plus de sûreté grâce à un typage statique fort. Cela est rendu possible grâce à un système très avancé de gestion et d'inférence des types.
Plus d'infos sur cette nouvelle version dans la suite de la dépêche.
NdM : Le code source de Scala est sous une licence propre au projet mais semblable à la licence BSD. Les nouveautés de la version 2.8.0
- Nouvelle bibliothèque de collections
- Nouvelle implémentation des tableaux (Array[T])
- Spécialisation
- Valeurs par défaut et arguments nommés
- Package objects
- les packages peuvent contenir des classes et des objets
- les objets peuvent contenir des objets, des classes, des alias de type, des méthodes statiques et des champs
- Diverses améliorations dans Scala Swing
- Améliorations de REPL
- Amélioration des parsers combinators
- Support des continuations
- Conclusion
- Annonce officielle de la sortie (3 clics)
- Site officiel (11 clics)
- Tutorial Scala pour programmeurs Java (20 clics)
- Licence Scala (type BSD) (1 clic)
La bibliothèque de collections fournie avec Scala a été modifiée en profondeur afin d'éviter les redondances de code et pour faciliter l'intégration de nouvelles collections.
Certaines méthodes prennent maintenant un constructeur de collection en argument implicite ce qui est transparent pour l'utilisateur dans la majorité des cas et permet de faire des choses comme ça :
scala> val mymap = Map(1 -> "a", 2 -> "b") //On crée une table de hash
mymap: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,a), (2,b))
scala> mymap.map(_._1) //On récupère la clé de chaque couple dans mymap
res13: scala.collection.immutable.Iterable[Int] = List(1, 2)
scala> mymap.map(_.swap) //On inverse chaque couple clé -> valeur dans mymap
res15: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,1), (b,2))
Ici on voit que le type de la collection renvoyée par la méthode "map" est différent (List[Int] ou Map[String,Int]) suivant la fonction passée en paramètre (_._1 ou _.swap). Le type le plus adapté est automatiquement choisi !
Supposons que l'on souhaite forcer le type de retour et obtenir une collection de type Vector[Int] en appliquant la fonction _._1 :
scala> val b : Vector[Int] = mymap.map(_._1)
:10: error: type mismatch;
found : scala.collection.immutable.Iterable[Int]
required: Vector[Int]
val b : Vector[Int] = mymap.map(_._1)
Ça n'est pas accepté, à juste titre, par le compilateur car dans ce cas "map" renvoie une List[Int] et non un Vector[Int]. On peut toujours convertir une List[A] en Vector[A] mais ce n'est pas efficace. Le plus efficace est de faire :
scala> import scala.collection.breakOut
import scala.collection.breakOut
scala> val b : Vector[Int] = mymap.map(_._1)(breakOut)
b: Vector[Int] = Vector(1, 2)
"breakOut", une fonction générique comme une autre (rien n'a été ajouté au compilateur), va automatiquement passer à la fonction "map" le constructeur permettant de créer un Vector[Int]. Tout ça de façon statique et type-safe grâce à l'inférence du type de breakOut avec comme contrainte le type de b (Vector[Int]).
Je ne rentre pas dans les détails, ceux qui sont intéressés pourront regarder ici : http://www.scala-lang.org/sid/7
Java fait la distinction entre les types primitifs (int, double...) et les types objets (qui ont tous pour ancètre commun la classe Object). Quand on utilise des types génériques, le code généré remplace le type générique par le type ancètre commun le plus proche. Sans contrainte sur le type générique, le code généré utilise la classe Object par défaut.
Exemple : class Vector[A]
La classe Vector prend un type (A) en argument. Comme celui-ci n'est pas contraint, le code généré considerera le type A comme étant la classe Object.
Un problème se pose dans le cas des types primitifs : ils n'héritent pas de la classe Object. Pour qu'on puisse créer un vecteur d'entiers, le compilateur fait ce qu'on appelle de l'auto-boxing (et de l'auto-unboxing) : il crée un objet qui englobe le type primitif et c'est cet objet qui est utilisé (car il hérite bien de Object).
Le problème de cette méthode est qu'elle est plus lente car elle implique la création et la destruction de nombreux objets. C'est ici que la spécialisation devient utile. En écrivant :
class Vector[@specialized A]
Une classe Vector sera créée pour chaque type primitif en plus de celle habituelle utilisant un objet. Ces classes spécifiques seront utilisées par le compilateur lorsqu'il le pourra, ce qui devrait améliorer grandement les performances.
La bibliothèque standard de Scala commence progressivement à utiliser la spécialisation.
Il est maintenant possible de spécifier des valeurs par défaut pour les arguments de méthodes :
scala> def f(a: Int = 10, b: String) = printf("a: %d, b: %s \n", a, b)
f: (a: Int,b: String)Unit
Et il est possible de spécifier les arguments à partir de leur nom :
scala> f(b = "Yo")
a: 10, b: Yo
Ça devrait permettre de remplacer de nombreux cas où la surcharge était utilisée pour obtenir des valeurs par défaut :
def g(a:Int, b:Int, c:Int)
def g(a:Int, b:Int) = g(a,b,10)
devient
def g(a:Int, b:int, c:Int = 10)
En Scala, les classes ne peuvent pas contenir de méthodes statiques comme en Java. À la place elles ont un "companion object" qui est un singleton dont les méthodes sont statiques. Avant Scala 2.8, la situation était la suivante :
package object mon.nom.de.package
Scala Swing est un ensemble de classes qui englobent les classes de Swing. Tout est type-safe et beaucoup plus naturel qu'en Java. Exemple :
import swing._
val w = new MainFrame {
title = "Scala demo"
contents = new Button {
text = "Pouche mi!"
}
}
w.visible = true
La gestion des événements se fait naturellement avec du pattern-matching :
listenTo(mouse)
reactions += {
case e: MouseClicked => println("Clic à la position "+e.point)
}
REPL (Read-Evaluate-Print Loop) est une sorte de shell pour Scala, l'équivalent de irb pour Ruby ou ghci pour Haskell. Les exemples de cette dépêche qui comportent le préfixe "scala>" sont des extraits de sessions REPL.
Ce dernier supporte maintenant la complétion (touche tabulation).
Scala dispose d'une bibliothèque permettant de créer très facilement des parsers (un peu à la Flex/Bison) directement en Scala. Avec le support des Packrat parser combinators, les grammaires récursives à gauche sont dorénavant supportées.
Un plugin pour le support des continuations est maintenant intégré à la distribution standard. Comme c'est un sujet un peu complexe et qui n'intéressera pas tout le monde, je renvoie ceux qui sont intéressés à http://www.scala-lang.org/node/2096
Beaucoup de choses nouvelles dans cette version qui a mis des mois avant de sortir. Les prochaines versions devraient sortir à intervalles plus réguliers et plus courts.
À noter aussi que Martin Oderksy, le créateur de Scala (et accessoirement des "generics" et du compilateur de référence de Java 1.5), a annoncé qu'il allait fonder une entreprise faisant du support pour les utilisateurs de Scala.
Je recommande vivement à tous les développeurs d'essayer Scala. N'hésitez pas à poser des questions dans les commentaires.
# Paris Scala User Group
Posté par Fanf (site web personnel) . Évalué à 3.
La prochaine réunion devrait avoir lieux en septembre. Le contenu de la présentation n'est pas encore fixé, mais elle concernera sûrement cette nouvelle version de Scala (peut être une présentation du nouveau framework de collections ?)
# Licence
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 8.
Dans la BSD :
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Dans la licence de Scala :
Permission to use, copy, modify, and distribute this software in source
or binary form for any purpose with or without fee is hereby granted,
provided that the following conditions are met:
À part ça, je n'ai vu aucune différence. Je me demande ce qui a pu pousser le ou les auteurs à changer cette formulation.
[^] # Re: Licence
Posté par hsyl20 (site web personnel) . Évalué à 1.
http://scala-programming-language.1934581.n4.nabble.com/Scal(...)
PS : oui j'ai fait une faute à "license"
# groovy
Posté par gc (site web personnel) . Évalué à 4.
Sur la page wikipedia de Groovy je peux lire du concepteur de Groovy : "I can honestly say if someone had shown me the Programming in Scala book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy."
[^] # Re: groovy
Posté par Nicolas Dumoulin (site web personnel) . Évalué à 2.
Grooy est un dérivé du Java.
Scala est un nouveau langage avec de nouveaux concepts très profonds.
[^] # Re: groovy
Posté par Victor . Évalué à -3.
« I can honestly say if someone had shown me the Programming Scala book by by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy. »
http://java.dzone.com/articles/scala-long-term-replacement
[^] # Re: groovy
Posté par claudex . Évalué à 6.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: groovy
Posté par Victor . Évalué à 0.
Désolé pour le bruit !
# -> et autres symboles
Posté par Nicolas Évrard (site web personnel, Mastodon) . Évalué à 1.
Ce serait pas plus simple (même si alors ça ressemble fort à du python/ruby) d'écrire ceci:
val mymap = Map((1, "a"), (2, "b"))
(Le pire dans ce cas étant que c'est ce qui est affiché par l'interpréteur).
[^] # Re: -> et autres symboles
Posté par Sphax . Évalué à 3.
scala> val mymap = Map(1 -> "a", 2 -> "b")
mymap: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,a), (2,b))
scala> val mymap = Map( (1, "a"), (2, "b") )
mymap: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,a), (2,b))
[^] # Re: -> et autres symboles
Posté par hsyl20 (site web personnel) . Évalué à 2.
Par exemple : http://github.com/scalaz/scalaz/blob/master/example/src/main(...)
"<*" c'est quand même mieux que "applicativeFunctorWithAnAnonymousLeft"
Ça demande un temps d'adaptation mais c'est la même démarche que pour les autres sciences : il y a des notations spécifiques au domaine concerné.
Dans le cas de Map, c'est quand même plus clair de montrer que "b" est associé à la clé "a" avec "a -> b" qu'avec "(a,b)". Si j'avais à représenter une association unidirectionnelle entre deux entités sur une feuille, j'utiliserais plus naturellement une flèche qu'un tuple.
# ceux qui connaissent le Ruby devraient plutôt regarder Mirah
Posté par rvalyi . Évalué à 3.
venant de Java puis Ruby/Python, y'a pas longtemps je m'étais posé la question de me lancer sur Scala pour avoir du code rapide mais concis justement.
Mais j'avais conclu que l'effort d'apprentissage était important. Au contraire, connaissant Ruby et Python, j'avais alors vu que le leader de JRuby, Charles Headius Nutter http://blog.headius.com/ avait lancé un "dérivé" de JRuby, avec aussi la syntax de Ruby mais statique et aussi rapide que Java, tout comme Scala.
Récemment, ce langage à été renommé Mirah, je ne saurai que trop de recommander, des tronches de chez Google sont aussi sur le coup pour développer des applis sur AppEngine... Certes récent, mais léger et bati sur du solide, avec des leaders qui ont fait leurs preuves et promis à un brillant avenir:
http://www.mirah.org/
A bon entendeur...
Raphaël Valyi
Founder and ERP Consultant
http://www.akretion.com
# scala <> java pas tout à fait compatibles
Posté par grenlibre . Évalué à 1.
Malheureusement, ce n'est pas tout à fait vrai :
"En Scala, les classes ne peuvent pas contenir de méthodes statiques comme en Java. À la place elles ont un "companion object" qui est un singleton dont les méthodes sont statiques."
Il n'est pas possible d'accéder à une méthode statique java, ce qui réduit la compatibilité de certaines bibliothèques.
[^] # Re: scala <> java pas tout à fait compatibles
Posté par ndesmoul . Évalué à 2.
Il est bien évidemment possible d'appeler une méthode statique Java depuis Scala.
Et inversement, les méthodes du "compagnion object" de scala sont vues depuis Java comme des méthodes statiques classiques. Il n'y a aucun problème à ce niveau.
En ce qui concerne la compatibilité Java/Scala, il est même possible d'avoir une classe Java héritant d'une classe Scala, héritant d'une classe Java, ...
Pour autant il peut y avoir certains problèmes de compatibilité si on utilise certaines possibilités du langage Scala, qui n'ont pas d'équivalent en Java (les "traits" par exemples).
[^] # Re: scala <> java pas tout à fait compatibles
Posté par grenlibre . Évalué à 1.
À l'époque que j'avais testé je pouvais lister les méthodes statiques mais pas les utiliser.
Est-ce résolu depuis peu sur scala ?
[^] # Re: scala <> java pas tout à fait compatibles
Posté par ndesmoul . Évalué à 2.
C'est bien la première fois que j'entend parler d'un problème pour appeler des méthodes statiques depuis Scala.
Tu peux facilement faire le test avec un petit programme Scala (en appelant par exemple System.currentTimeMillis() ).
À mon avis le problème provenait plutôt du module scala de ton framework, ou d'un problème de configuration.
# Que du bonheur
Posté par GTof . Évalué à 2.
[^] # Re: Que du bonheur
Posté par hsyl20 (site web personnel) . Évalué à 1.
http://lampsvn.epfl.ch/trac/scala/browser/compiler-plugins/c(...)
Il y a aussi un exemple ici : http://scala-programming-language.1934581.n4.nabble.com/Deli(...)
Que j'ai plus ou moins expliqué en français ici : http://www.hsyl20.fr/home/?q=node/35
# Rétrospective
Posté par benoar . Évalué à 2.
Depuis, le langage a beaucoup gagné en audience, et j'ai pu rencontrer M. Odersky au FOSDEM.
Longue vie à Scala !
[^] # Re: Rétrospective
Posté par hsyl20 (site web personnel) . Évalué à 1.
Un article de Van Roy :
http://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf
Le livre (dont l'article précédent est un résumé) :
http://www.info.ucl.ac.be/~pvr/book.html
qui a apparemment été traduit en français :
http://www.info.ucl.ac.be/~pvr/coursfrancais.html
Le sigle CTM utilisé parfois sur LTU (Lambda The Ultimate) fait référence à ce livre.
Programming Language Pragmatics (PLP sur LTU) :
http://www.cs.rochester.edu/~scott/pragmatics/
[^] # Re: Rétrospective
Posté par benoar . Évalué à 2.
# A Scala, je prefere...
Posté par zaurus (site web personnel) . Évalué à 1.
Et si je ne veux pas de typage fort, alors je fais du Python,
tout simplement. :)
[^] # Re: A Scala, je prefere...
Posté par ZankFrappa . Évalué à 1.
Je dis ça même si, comme toi et beaucoup de gens sans doute, je préfère ces langages et les personnes qui écrivent à leur sujet.
[^] # Re: A Scala, je prefere...
Posté par V . Évalué à 3.
Cela me fait penser à Linux il y a 10 ans : « ce n'est pas fait pour être utilisé dans le monde réel, c'est un truc d'universitaires, si les entreprises ne l'utilisent pas, ça veut bien dire que ce n'est pas sérieux, etc. ».
[^] # Re: A Scala, je prefere...
Posté par ZankFrappa . Évalué à 1.
OCaml n'a pas le soutien industriel nécessaire. C'est malheureux, mais c'est vrai.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.