Scala vs Java : Pourquoi devrais-je apprendre Scala ?
Publié: 2022-03-11Il y a certes une part de vérité dans l'affirmation selon laquelle "Scala est difficile", mais la courbe d'apprentissage vaut bien l'investissement. Certaines des fonctionnalités les plus complexes du langage (tuples, fonctions, macros, pour n'en nommer que quelques-unes) permettent finalement au développeur d'écrire un meilleur code et d'augmenter les performances en programmant dans Scala. Franchement, nous sommes des programmeurs, et si nous ne sommes pas assez intelligents pour apprendre un langage qui a une certaine complexité, alors nous sommes dans le mauvais domaine.
Scala est un langage JVM de type sécurisé qui intègre à la fois la programmation orientée objet et fonctionnelle dans un langage extrêmement concis, logique et extraordinairement puissant. Certains pourraient être surpris de savoir que Scala n'est pas aussi nouveau qu'ils le pensaient, ayant été introduit pour la première fois en 2003. Cependant, c'est surtout au cours des dernières années que Scala a commencé à développer une clientèle importante. Ce qui soulève la question de "Pourquoi Scala?".
Cet article examine les avantages de Scala, en particulier par rapport à Java (puisque Scala est écrit pour s'exécuter dans la JVM). Scala n'est pas la seule tentative de créer un "meilleur Java". Des alternatives telles que Kotlin et Ceylan ont également emprunté cette voie, mais elles ont pris la décision fondamentale de rester très proches dans la syntaxe du langage Java lui-même, afin de minimiser la courbe d'apprentissage. Cela peut sembler une excellente idée, mais c'est finalement quelque peu contre-productif dans la mesure où cela vous oblige à rester dans un certain nombre de ces mêmes paradigmes Java qui étaient la raison de vouloir créer un "meilleur Java" en premier lieu.
En revanche, Scala a été créé spécifiquement dans le but d'être un meilleur langage , en se débarrassant des aspects de Java qu'il considérait comme restrictifs, trop fastidieux ou frustrants pour le développeur. En conséquence, il existe en effet des distinctions de code et des changements de paradigme qui peuvent rendre un peu plus difficile l'apprentissage précoce de la programmation Scala, mais le résultat est un langage beaucoup plus propre et bien organisé qui est finalement plus facile à utiliser et augmente la productivité.
Scala vs Java : lequel est vraiment le plus complexe ?
Si la simplicité du langage Java a fait partie de son succès, ironiquement, elle a également contribué à sa complexité. Bien sûr, vous pouvez écrire presque n'importe quoi en Java, mais les lignes de code nécessaires pour le faire peuvent être intimidantes. La programmation en Scala, en revanche, a une structure légèrement plus complexe. Mais si vous pouvez écrire une seule ligne de code légèrement plus complexe qui remplace 20 lignes « plus simples » de Java, laquelle est vraiment la plus complexe ?
La vérité est que Java est souvent trop verbeux. Dans Scala, le compilateur est incroyablement intelligent, ce qui évite au développeur d'avoir à spécifier explicitement les choses que le compilateur peut déduire. Comparez, par exemple, ce simple "Hello World!" programme en Java vs Scala :
Bonjour tout le monde en Java :
public class HelloJava { public static void main(String[] args) { System.out.println("Hello World!"); } }
Bonjour tout le monde à Scala :
object HelloScala { def main(args: Array[String]): Unit = { println("Hello World!") } }
Bien qu'il n'y ait pas une grande différence entre les deux langues ici, Scala est moins verbeux, même dans cet exemple simple.
Pour un exemple plus pratique, examinons la création d'une simple liste de chaînes :
Java:
List<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("3");
Échelle :
val list = List("1", "2", "3")
Certes, il existe quelques astuces en Java pour raccourcir un peu le code, mais pas dans l'usage standard.
Considérons maintenant un cas où nous avons une liste de chaînes qui sont des nombres, mais nous voulons convertir cette liste en une liste d'entiers :
Java:
List<Integer> ints = new ArrayList<Integer>(); for (String s : list) { ints.add(Integer.parseInt(s)); }
Échelle :
val ints = list.map(s => s.toInt)
Grâce aux propriétés fonctionnelles de Scala, cette conversion devient extrêmement simple.
Un exemple de classe : Java contre Scala
Poussons les choses un peu plus loin et comparons la création d'un bean standard / plain old Java object (POJO) en Java et Scala.
Tout d'abord, la version Java :
public class User { private String name; private List<Order> orders; public User() { orders = new ArrayList<Order>(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Order> getOrders() { return orders; } public void setOrders(List<Order> orders) { this.orders = orders; } } public class Order { private int id; private List<Product> products; public Order() { products = new ArrayList<Product>(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public List<Product> getProducts() { return products; } public void setProducts(List<Product> products) { this.products = products; } } public class Product { private int id; private String category; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
Phew. Beaucoup de code.

Maintenant la version Scala :
class User { var name: String = _ var orders: List[Order] = Nil } class Order { var id: Int = _ var products: List[Product] = Nil } class Product { var id: Int = _ var category: String = _ }
Quelle langue avons-nous dit était plus compliquée ? !
Sommes-nous justes ?
Si vous êtes arrivé jusqu'ici et que vous êtes un programmeur Java, vous pensez peut-être à ce stade que je fais une comparaison injuste du code. Après tout, rien ne m'empêche de créer des variables publiques en Java, puis de me débarrasser des getters et des setters.
Cependant, si vous repensez au raisonnement derrière les getters et les setters en Java, c'est spécifiquement pour la pérennité. Autrement dit, si vous avez besoin ultérieurement d'ajouter une logique à l'obtention ou à la définition de variables, vous devrez réécrire ces variables publiques pour utiliser des méthodes à la place (c'est pourquoi l'utilisation de getters et de setters pour commencer est encouragée en Java ). Cependant, en programmation Scala, ce n'est pas le cas. En raison de la conception du langage, l'abstraction reste intacte sans avoir besoin de getters et de setters. Considérez, par exemple, cette classe User
modifiée dans Scala qui lève une NullPointerException
si vous essayez de définir le nom sur null :
class User { private var _name: String = _ var orders: List[Order] = Nil def name = _name def name_=(name: String) = { if (name == null) { throw new NullPointerException("User.name cannot be null!") } _name = name }
Et vous pouvez toujours définir le nom comme ceci :
user.name = "John Doe"
Notez que cela supprime entièrement le besoin de préconfigurer les accesseurs de méthode.
De plus, puisque Scala préfère l'immuabilité, je peux écrire ceci dans Scala de manière encore plus concise avec des classes de cas :
case class User(name: String, orders: List[Order]) case class Order(id: Int, products: List[Product]) case class Product(id: Int, category: String)
Assez fou combien moins de code je dois écrire.
Poussons l'exemple un peu plus loin
Considérons maintenant un scénario avec les classes ci-dessus où je souhaite ajouter une petite méthode astucieuse dans la classe User
qui renvoie une liste de tous les Products
que l' User
a commandés :
Dans le monde verbeux de Java :
public List<Product> getProducts() { List<Product> products = new ArrayList<Product>(); for (Order order : orders) { products.addAll(order.getProducts()); } return products; }
Heureusement, java.util.List
a une méthode addAll
, ou getProducts()
aurait été encore plus long en Java.
Dans Scala, en revanche, tout ce dont nous avons besoin est :
def products = orders.flatMap(o => o.products)
Vous pouvez voir à quel point l'implémentation du langage Scala est plus petite. Oui, cela peut sembler plus complexe pour le débutant Scala, mais une fois que vous comprenez parfaitement les concepts sous-jacents, le code Scala semblera beaucoup plus simpliste que le code Java.
Soyons encore un peu plus compliqué ici. Que se passe-t-il si nous ne voulons obtenir que les Products
d'une Category
spécifique ?
Dans ce cas, nous ne pouvons pas tirer parti de la méthode addAll
dans java.util.List
, donc les choses deviennent plus laides en Java :
public List<Product> getProductsByCategory(String category) { List<Product> products = new ArrayList<Product>(); for (Order order : orders) { for (Product product : order.getProducts()) { if (category.equals(product.getCategory())) { products.add(product); } } } return products; }
Dans Scala , cependant, le code reste assez simple. Nous utilisons simplement flatMap
pour combiner les listes de produits de chaque Order
aplaties dans une seule liste, puis nous filtrons pour n'inclure que ceux qui correspondent à la catégorie :
def productsByCategory(category: String) = orders.flatMap(o => o.products).filter(p => p.category == category)
Dynamique vs statique
Certes, les nouveaux langages n'ont pas manqué ces dernières années, mais alors que presque tous les autres qui ont émergé récemment sont dynamiques, Scala est typé statiquement.
En tant que développeur professionnel - bien que je connaisse et utilise de nombreux langages dynamiques - je pense que les vérifications au moment de la compilation sont extrêmement importantes pour écrire du code solide. Dans un langage dynamique, vous ne pouvez jamais être sûr que votre code est suffisamment exempt de bogues et robuste jusqu'à ce que vous l'exécutiez réellement dans un large éventail de scénarios. Cela peut entraîner des défauts potentiellement graves dans le code qui ne se réalisent jamais tant que le code n'est pas en production.
Emballer
Espérons que cet article compare suffisamment Java à Scala pour vous donner une idée préliminaire de la puissance et des capacités de Scala et aiguiser votre appétit pour apprendre le langage. Non seulement c'est un excellent langage qui peut rendre la programmation moins fastidieuse et plus agréable, mais il est également utilisé par certaines des plus grandes entreprises du monde (LinkedIn, Twitter, FourSquare, The Guardian, pour n'en nommer que quelques-unes).
La popularité et l'utilisation de Scala augmentent rapidement, comme en témoigne le nombre toujours croissant de postes ouverts pour les développeurs Scala. Si vous ne l'avez pas déjà fait, ce serait le bon moment pour commencer à surfer sur la vague et arrêter de demander "Pourquoi apprendre Scala ?"