Bonjour chers collègues.
Il n'y a pas si longtemps, nous avons imprimé le
livre d' Odersky, Spoon et Wenners sur Scala 2.12. Après tout, Scala 3 est encore loin.
L'auteur de l'article d'aujourd'hui est Adam Worski, co-fondateur de SoftwareMill et développeur Scala expérimenté. Il a obtenu un résumé intéressant des forces de la langue Scala moderne, que nous attirons votre attention.
Après une
conférence plénière de Martin Odersky sur ScalaDays, où il a décrit les plans de Scala 3 et une
conférence plénière de John de Goes lors de la conférence Scalapeño sur l'avenir de
Scala , des discussions animées se poursuivent dans
la communauté Scala . Outre les discussions de ces présentations en plénière, de nombreuses discussions se déroulent sur Twitter, dans les communautés Slack, ainsi que sur reddit (voir, par exemple,
1 ,
2 ).
Telle est la question!Tout cela est très intéressant et instructif pour les spécialistes travaillant déjà dans l'écosystème Scala. Cependant, une grande partie de la controverse est liée aux divers défauts intuitivement perceptibles ou réels de Scala en tant que langue. Ces moments peuvent effrayer les gens "de l'extérieur", les obligeant à se demander: "Pourquoi devrais-je utiliser Scala?", "Et si c'est une impasse?", "Est-ce que Scala 3 répétera le succès de Python 3?" etc. Comme dans la plupart des discussions, les points les plus faibles et les plus émotifs retiennent l'attention, et ce débat ne fait pas exception.
Prenons donc
un peu de recul : pourquoi auriez-vous même besoin de Scala? Quelles sont les raisons techniques et commerciales de travailler avec cette langue?
Domaine du projetPour commencer, la langue Scala est particulièrement bonne pour certains domaines (mais pas pour tout le monde!). L'atout le plus important de Scala est sa
flexibilité dans la définition des abstractions . À votre disposition - un certain nombre de «briques» simples pour cela; Parfois, définir une abstraction n'est pas plus difficile que d'utiliser une classe, des méthodes et des expressions lambda. Parfois, vous devez utiliser un paramètre implicite ou une méthode d'extension; dans de rares cas, il ne reste plus qu'à recourir aux macro-commandes. Cependant,
il existe des options .
Ainsi, Scala est parfait pour vous si vous avez besoin de
naviguer dans un sujet complexe . Par exemple, nous pouvons parler de programmation distribuée ou compétitive. La concurrence est très difficile, et Scala possède un certain nombre de bibliothèques qui simplifient cette tâche en créant des abstractions. Il existe deux approches principales pour cela: l'acteur, mis en œuvre avec
Akka , et dans l'esprit de FP, présenté par
Monix /
cats-effect et
Scalaz /
ZIO (si vous souhaitez en savoir plus sur la comparaison de ces outils - j'ai écrit une
série d'articles sur ce sujet )
Cependant, bien sûr, nous pouvons parler d'autres sujets. Les capacités de Scala nous permettent également de faire passer la modélisation des applications métier typiques au niveau supérieur. Mais dans ce cas, nous parlons de la complexité d'un ordre différent. Dans le cas des systèmes distribués, nous sommes confrontés à une complexité technique. Lors de la programmation de la logique métier dans les applications, nous parlons déjà de la complexité du domaine en tant que tel. Par exemple, le livre de Debasish Ghosh «
Modélisation de domaine fonctionnel et réactif » explique comment combiner DDD avec une programmation fonctionnelle et réactive.
Difficulté linguistiqueRemarque: en parlant de Scala, tout le monde aime souligner l'étendue des possibilités de cette langue, en soulignant que précisément en raison d'une telle polyvalence, cette langue est si complexe. Ce n'est pas tout à fait vrai.
Comme mentionné ci-dessus, Scala a un certain nombre de constructions de base à partir desquelles des abstractions peuvent être construites. Cependant, tous peuvent être
combinés les uns avec les autres, grâce à quoi la langue acquiert une telle flexibilité. La plupart des projets innovants que vous pouvez rencontrer se résument à l'une ou l'autre combinaison de types d'ordre supérieur, de paramètres implicites et de sous-typage.
Ainsi, avec un nombre relativement restreint de fonctionnalités de base (la taille de la grammaire Scala est plus simple que Kotlin, Java ou Swift!) - ce qui, à son tour, facilite l'apprentissage - les options de combinaison sont beaucoup plus nombreuses.
Le choix est-il trop large? Je ne pense pas. Le programmeur, en tant que professionnel compétent et responsable, est plus que capable de choisir la meilleure option pour résoudre un problème spécifique. Pour plus d'informations, consultez l'article «
Pile Scala simple ».
Java en mieuxOn parle beaucoup maintenant que
Kotlin a supplanté Scala comme «comme Java, mais en mieux.» Mais je crois que
c'est Scala, et non Kotlin , qui mérite toujours un tel titre. Il y a deux raisons principales à cela:
Tout d'abord, l'
immuabilité à Scala est primordiale . Cela est dû à la nature de Scala en tant que telle: l'écriture de code dessus est pratique principalement à l'aide de données immuables. Ces données comprennent notamment:
val
(en tant qu'unités de la première classe), les classes de
case
, les fonctions d'ordre supérieur, etc. Mais le fait est de savoir comment la bibliothèque de langues Scala standard est conçue et écrite; toutes les structures de données utilisées par défaut sont immuables. Grâce à l'immuabilité, un certain nombre de choses sont simplifiées, en particulier dans notre monde de haute concurrence, où ces langues gagnent, où l'immuabilité est préférée.
Deuxièmement, Scala prend en charge
les constructeurs de types, les types d'ordre supérieur et les types de classes (déclarés implicitement), ce qui simplifie considérablement le travail avec les types d'habillage / conteneur, par exemple,
Promise
,
Future
ou
Task
. De tels wrappers prévalent lors de la programmation dans un style asynchrone ou réactif, et la présence de constructions de langage qui simplifient le travail avec, par exemple, une base de code où
Future
est activement utilisé est un autre argument en faveur de Scala.
Quels sont les types de classe? Leur rôle est à peu près le même que celui des modèles de conception en Java, cependant, ils sont plus flexibles et faciles à utiliser dès que vous saisissez fermement leur signification. Il existe d'excellents guides à ce sujet, comme
1 ,
2 .
Qu'en est-il des constructeurs de types? Ce sont des types tels que
Future
ou
Option
, servant de «conteneurs» ou de «wrappers» pour d'autres types. Ainsi, vous pouvez avoir
Option[String]
ou
Future[Int]
. Les types d'ordre supérieur vous permettent d'écrire du code qui résume tout wrapper. Voir par exemple.
1 ,
2 .
Tout à coup, vous vous demandez pourquoi même recourir à
Future
/
Task
? Le fait n'est pas seulement que la plupart des calculs «réactifs» hautes performances avec des retards minimaux sont effectués à l'aide d'E / S asynchrones, pour lesquelles de telles conceptions sont simplement demandées. D'autres raisons sont données dans cette
discussion sur reddit et dans mon article «
Pourquoi s'embêter avec des wrappers? "
Travailler dans un environnement essentiellement inchangé, ainsi que la possibilité de gérer facilement des constructions comme
Future
,
Promise
ou
Task
(et de les abstraire!) Transforme radicalement votre code. À première vue, cela peut ne pas être évident: si vous avez une expérience Java ou Ruby derrière vous, vous ne pourrez pas immédiatement réaliser ces aspects de Scala. Mais, même d'un point de vue éducatif, il est utile de comprendre comment fonctionne l'approche «fonctionnelle» et, plus important encore, pourquoi elle peut se révéler une
alternative très valable .
Naturellement, Scala et Kotlin ont un certain nombre d'avantages communs par rapport à Java, par exemple:
- Syntaxe plus compacte
- Code moins stéréotypé
- Un système de type plus riche
- Manque de ballast linguistique
Dans le même temps, les deux langues donnent accès à l'écosystème des bibliothèques et des frameworks JVM.
Plus le système de types est riche (à Scala, il est plus riche qu'à Kotlin, et à Kotlin - plus riche qu'à Java), plus le travail de vérification est effectué par le compilateur et non par la personne. C'est pour cela que des ordinateurs ont été créés: pour effectuer des tâches répétitives ennuyeuses et routinières. La vérification de l'applicabilité des types n'est certainement qu'une de ces tâches.
Dans le même temps, un système de type riche est utile non seulement lors de l'
écriture de code , mais aussi, dans une bien plus grande mesure, lors de la
lecture de code . Quand il vous est facile de naviguer dans la base de code, de comprendre ce qu'il fait et, de plus, ce n'est pas effrayant (ou pas si effrayant) d'entreprendre sa
refactorisation , cela caractérise le langage de manière très positive d'un point de vue technique et appliqué.
FP vs OOPUne autre question souvent soulevée dans ces discussions est de savoir si le langage Scala doit continuer à adhérer à la synthèse de la POO et de la PF, ou doit-il évoluer le long d'une voie purement fonctionnelle. Je suis
partisan de la synthèse , notamment parce que la PF et la POO, à mon avis, ne sont pas des approches alternatives, mais se complètent mutuellement.
FP
programme en utilisant des fonctions , mais pas toutes, mais référentiellement transparentes (voir cette
réponse à reddit dans un fil précédent, où la transparence référentielle est parfaitement expliquée). En POO, la communication avec les objets est organisée à l'aide de «messages» ou, dans notre terminologie, d'appels à des méthodes virtuelles. Il n'y a pas une seule raison pour que ces deux approches ne puissent pas coexister, et Scala l'a déjà démontré!
Dans un
tweet sur les vertus de Scala, John de Goes mentionne certaines fonctionnalités de POO qui sont utiles dans une approche purement fonctionnelle, en particulier,
les modules de première classe (obtenus en composant des objets), la
syntaxe ponctuelle (appel de méthodes dans des objets) et les
classes / types d'
instances comme constructions de première classe . Tous ces éléments sont les éléments d'une combinaison réussie de deux paradigmes. Peut-être que d'autres sont juste autour du coin?
Le projet de «synthèse» n'est pas encore terminé, il y a certainement un champ de discussion ici. Un aspect incomplet est la syntaxe proposée pour les méthodes d'extension, qui devrait remplacer des conversions implicites beaucoup plus confuses. Une autre optimise la syntaxe des classes de types;
La suggestion faite il y a quelque temps est clairement grossière et ne couvre pas certaines des utilisations les plus courantes des monades à Scala. Certaines suggestions sont meilleures, d’autres doivent être affinées, mais il est bon qu’elles soient reçues et que des discussions aient lieu à leur sujet; grâce à eux, la langue vit et, finalement, la meilleure solution y est fixée.
Scala 3Scala 3 sortira dans deux ans. Un certain nombre de possibilités intéressantes y apparaîtront, en particulier les types opaques, les paramètres de trait, une nouvelle approche de métaprogrammation, les types d'union et d'intersection, les types de fonctions implicites - ce ne sont que quelques exemples. Bien sûr, il y a une préoccupation (fondée) concernant la migration.
Il est déjà connu qu'un outil spécial sera introduit pour
la migration automatique de code de Scala 2 vers Scala 3 à l'aide de
scalafix . Étant donné que Scala est un langage typé statiquement, une telle tâche peut être résolue à grande échelle et est beaucoup plus simple que, par exemple, en Python. Mais, bien sûr, il n'y a pas de magie ici: même si cet outil fournit une couverture correcte du code à 99%, 1% des cas les plus problématiques resteront. Comme vous ne pouvez pas compter sur la magie, la migration de ces fragments devra être effectuée manuellement.
Ce sont les coûts de travail avec un langage en développement actif: vous obtenez les dernières opportunités, mais certaines d'entre elles ne sont en fait pas si bonnes et doivent être améliorées. Néanmoins, les changements proposés ne sont pas révolutionnaires. Le langage Scala 3 est très similaire à Scala 2, aucun changement majeur de paradigme n'est attendu.
Il est encourageant de constater que l'équipe de Scala prend au sérieux la migration. Alors que la migration antérieure entre les anciennes versions de Scala (par exemple de 2.8 à 2.9) était assez lourde, les migrations récentes se sont beaucoup mieux passées. Il y a trois parties principales impliquées: l'EPFL,
ScalaCenter et
Lightbend tous (souvent ensemble) travaillent pour faciliter la migration. Par exemple, il existe un outil
MIMA compatible binaire, et de nombreuses nouvelles bibliothèques sont constamment créées dans la communauté pour assurer un travail pratique avec les nouvelles versions de Scala.
Enfin, l'outil TASTY encore inachevé (qui, par conséquent, ne peut pas encore être évalué) devrait garantir l'utilisation de fichiers binaires de Scala 2 à Scala 3.
Alors pourquoi utiliser Scala?Alors, quelles sont les raisons de s'arrêter à Scala, si vous considérez cette langue d'un point de vue commercial? Tous les avantages techniques ci-dessus sont directement utiles aux entreprises. Lorsque vous avez un langage dans lequel vous pouvez écrire du code complexe avec moins de bogues, vous disposez d'un délai minimal en termes et d'utilisateurs satisfaits. Si vous commencez à rédiger des applications concurrentielles puissantes et pratiquement antidérapantes pour Scala, pour lesquelles des outils spéciaux sont fournis dans Scala, cela se révélera être un sérieux avantage pour votre entreprise.
N'oubliez pas non plus
Spark , la plate-forme leader pour
l'analyse de données distribuées . Scala est utilisé non seulement pour implémenter Spark en tant que tel, mais aussi pour définir les calculs eux-mêmes. Voici une autre abstraction orientée science des données qui cache un modèle de calcul complexe.
RésuméBien sûr, il y a des problèmes à Scala, mais où ne sont-ils pas? L'optimisme s'explique par le fait que de nombreuses personnes utilisant Scala quotidiennement travaillent activement à l'
amélioration des outils , des bibliothèques et du langage lui-même. Je peux supposer qu'ils continuent de travailler avec Scala précisément parce que, avec toutes les lacunes disponibles, pas une seule langue n'est aussi bien adaptée à leur domaine.
Scala vous permet de développer votre propre style de programmation, quel que soit le langage que vous utilisiez: Java, Ruby, ou tout simplement de vous essayer à la programmation. Il n'y a pas d'approche gagnante unique à Scala; soit l'approche plus
impérative d' Akka, soit l'approche plus
fonctionnelle de Cats et Scalaz.
C'est là que le problème peut être vu: il y a des fractions dans la communauté Scala qui adhèrent à l'approche OOP / AF «réactive», «synthétique» et à la FA pure. Cependant, en fait, c'est un énorme avantage. En raison de cette diversité, des discussions ont lieu, de nombreuses opinions différentes sont exprimées de différents points de vue. Sur ce, à son tour, vous pouvez parfaitement apprendre à résoudre des problèmes non standard et enrichir vos propres outils.
Quelle que soit la voie que vous choisissez à Scala, vous serez soutenu par une impressionnante communauté de collègues impliqués dans le développement de bibliothèques et de frameworks; ces personnes sont toujours prêtes à aider et à discuter des idées émergentes.