Hallo Kollegen.
Vor nicht allzu langer Zeit haben wir das
Buch von Odersky, Spoon und Wenners über Scala 2.12 gedruckt. Immerhin ist Scala 3 noch weit weg.
Der Autor des heutigen Artikels ist Adam Worski, Mitbegründer von SoftwareMill und erfahrener Scala-Entwickler. Er hat eine interessante Zusammenfassung der Stärken der modernen Scala-Sprache erhalten, auf die wir Sie aufmerksam machen.
Nach einem
Plenarvortrag von Martin Odersky über ScalaDays, in dem er Pläne für Scala 3 skizzierte, und einem
Plenarvortrag von John de Goes auf der Scalapeño-Konferenz über die Zukunft von
Scala werden in
der Scala-Community lebhafte Diskussionen fortgesetzt. Neben den Diskussionen zu diesen Plenarpräsentationen finden zahlreiche Diskussionen auf Twitter, in Slack-Communities sowie auf reddit statt (siehe z. B.
1 ,
2 ).
Das ist die Frage!All dies ist sehr interessant und informativ für Spezialisten, die bereits im Scala-Ökosystem arbeiten. Ein Großteil der Kontroversen hängt jedoch mit den verschiedenen intuitiv wahrnehmbaren oder tatsächlichen Fehlern von Scala als Sprache zusammen. Diese Momente können Menschen "von außen" erschrecken und sie fragen: "Warum sollte ich Scala überhaupt verwenden?", "Was ist, wenn dies eine Sackgasse ist?", "Wird Scala 3 den Erfolg von Python 3 wiederholen?" usw. Wie in den meisten Diskussionen erregen die schwächsten und emotionalsten Punkte die Aufmerksamkeit, und diese Debatte ist keine Ausnahme.
Machen wir also
einen Schritt zurück : Warum brauchst du überhaupt Scala? Was sind die technischen und geschäftlichen Gründe für die Arbeit mit dieser Sprache?
ProjektfachbereichZunächst ist die Scala-Sprache besonders gut für bestimmte Themenbereiche (aber nicht für alle!). Das wichtigste Kapital von Scala ist seine
Flexibilität bei der Definition von Abstraktionen . Zu Ihrer Verfügung - eine Reihe von einfachen "Steinen" dafür; Manchmal ist das Definieren einer Abstraktion nicht schwieriger als das Verwenden von Klassen-, Methoden- und Lambda-Ausdrücken. Manchmal müssen Sie einen impliziten Parameter oder eine Erweiterungsmethode verwenden. In seltenen Fällen wird nur auf Makrobefehle zurückgegriffen. Es
gibt jedoch Optionen .
Somit ist Scala perfekt für Sie, wenn Sie in
einem komplexen Themenbereich navigieren müssen. Zum Beispiel können wir über verteilte oder wettbewerbsfähige Programmierung sprechen. Parallelität ist sehr schwierig, und Scala verfügt über eine Reihe von Bibliotheken, die diese Aufgabe durch das Erstellen von Abstraktionen vereinfachen.
Hierfür gibt es zwei Hauptansätze: schauspielerbasiert, mit
Akka implementiert und im Geiste von FP, präsentiert von
Monix /
Katzeneffekt und
Scalaz /
ZIO (wenn Sie mehr über den Vergleich dieser Tools lesen möchten - habe ich eine
Reihe von Artikeln zu diesem Thema geschrieben )
Natürlich können wir auch über andere Themenbereiche sprechen. Die Fähigkeiten von Scala ermöglichen es uns auch, die Modellierung typischer Geschäftsanwendungen auf die nächste Stufe zu heben. In diesem Fall sprechen wir jedoch über die Komplexität einer anderen Reihenfolge. Bei verteilten Systemen sind wir mit technischer Komplexität konfrontiert. Bei der Programmierung von Geschäftslogik in Anwendungen sprechen wir bereits über die Komplexität des Themenbereichs als solchen. In Debasish Ghoshs Buch „
Funktionale und reaktive Domänenmodellierung “ wird beispielsweise erklärt, wie DDD mit funktionaler und reaktiver Programmierung kombiniert werden kann.
SprachschwierigkeitenHinweis: Wenn es um Scala geht, betont jeder gerne die Breite der Möglichkeiten dieser Sprache und betont, dass diese Sprache gerade wegen ihrer Vielseitigkeit so komplex ist. Dies ist nicht ganz richtig.
Wie oben erwähnt, verfügt Scala über eine Reihe grundlegender Konstrukte, aus denen Abstraktionen erstellt werden können. Sie können jedoch alle miteinander
kombiniert werden, wodurch die Sprache eine solche Flexibilität erhält. Die meisten innovativen Projekte, auf die Sie möglicherweise stoßen, beruhen auf der einen oder anderen Kombination von Typen höherer Ordnung, impliziten Parametern und Untertypen.
Mit einer relativ geringen Anzahl grundlegender Funktionen (die Größe der Scala-Grammatik ist einfacher als bei Kotlin, Java oder Swift!) - was wiederum das Lernen erleichtert - sind die Kombinationsoptionen viel zahlreicher.
Ist die Auswahl zu groß? Ich glaube nicht. Der Programmierer kann als kompetenter und verantwortungsbewusster Fachmann mehr als die beste Option zur Lösung eines bestimmten Problems auswählen. Weitere Informationen finden Sie im Artikel „
Simple Scala Stack “.
Java nur besserEs wird viel darüber geredet, dass
Kotlin Scala als "wie Java, nur besser" abgelöst hat. Aber ich glaube, dass
es Scala und nicht Kotlin ist, die einen solchen Titel noch verdient. Dafür gibt es zwei Hauptgründe:
Erstens ist die
Unveränderlichkeit in Scala von größter Bedeutung . Dies liegt an der Natur von Scala als solchem: Das Schreiben von Code ist in erster Linie mithilfe unveränderlicher Daten praktisch. Zu diesen Daten gehören insbesondere:
val
(als Einheiten der ersten Klasse), Fallklassen, Funktionen höherer Ordnung usw. Der Punkt ist jedoch, wie die Standard-Scala-Sprachbibliothek entworfen und geschrieben wird. Alle standardmäßig verwendeten Datenstrukturen sind unveränderlich. Dank der Unveränderlichkeit wird eine Reihe von Dingen vereinfacht, insbesondere in unserer Welt des starken Wettbewerbs, in der diese Sprachen gewinnen und die Unveränderlichkeit bevorzugt wird.
Zweitens unterstützt Scala Typkonstruktoren
, Typen höherer Ordnung und Klassentypen (implizit deklariert), was die Arbeit mit Wrapping- / Containertypen, z. B.
Promise
,
Future
oder
Task
, erheblich vereinfacht. Solche Wrapper setzen sich durch, wenn in einem asynchronen oder reaktiven Stil programmiert wird, und das Vorhandensein von Sprachkonstrukten, die das Arbeiten beispielsweise mit einer Codebasis vereinfachen, in der
Future
aktiv verwendet wird, ist ein weiteres Argument für Scala.
Was sind Klassentypen? Ihre Rolle entspricht in etwa der von Entwurfsmustern in Java. Sie sind jedoch flexibler und benutzerfreundlicher, sobald Sie ihre Bedeutung genau verstanden haben. Es gibt einige ausgezeichnete Anleitungen dazu, wie
1 ,
2 .
Was ist mit Typkonstruktoren? Dies sind Typen wie
Future
oder
Option
, die als "Container" oder "Wrapper" für andere Typen dienen. Sie können also
Option[String]
oder
Future[Int]
. Mit Typen höherer Ordnung können Sie Code schreiben, der jeden Wrapper abstrahiert. Siehe zum Beispiel.
1 ,
2 .
Plötzlich fragen Sie sich, warum Sie überhaupt auf
Future
/
Task
zurückgreifen sollten. Der Punkt ist nicht nur, dass die meisten "reaktiven" Hochleistungsberechnungen mit minimalen Verzögerungen unter Verwendung von asynchronen E / A durchgeführt werden, für die nur solche Entwürfe einfach angefordert werden. Andere Gründe werden in dieser
Diskussion über reddit und in meinem Artikel „
Warum sich mit Wrappern beschäftigen? ""
Das Arbeiten in einer überwiegend unveränderten Umgebung sowie die Möglichkeit, Konstrukte wie
Future
,
Promise
oder
Task
bequem zu handhaben (und zu abstrahieren!), Transformiert Ihren Code radikal. Auf den ersten Blick ist dies möglicherweise nicht offensichtlich: Wenn Sie Java- oder Ruby-Erfahrung hinter sich haben, können Sie diese Aspekte von Scala nicht sofort erkennen. Aber auch aus pädagogischer Sicht ist es hilfreich zu verstehen, wie der „funktionale“ Ansatz funktioniert und, was noch wichtiger ist, warum er sich als
sehr wertvolle Alternative herausstellen kann.
Natürlich haben sowohl Scala als auch Kotlin eine Reihe gemeinsamer Vorteile gegenüber Java, zum Beispiel:
- Kompaktere Syntax
- Weniger stereotyper Code
- Ein reichhaltigeres System
- Mangel an Sprachballast
Gleichzeitig bieten beide Sprachen Zugriff auf das Ökosystem von Bibliotheken und JVM-Frameworks.
Je umfangreicher das Typsystem ist (in Scala ist es umfangreicher als in Kotlin und in Kotlin - umfangreicher als in Java), desto mehr Überprüfungsarbeiten werden vom Compiler und nicht von der Person ausgeführt. Aus diesem Grund wurden Computer geschaffen, um langweilige, sich wiederholende Routineaufgaben auszuführen. Die Überprüfung der Anwendbarkeit von Typen ist definitiv nur eine dieser Aufgaben.
Gleichzeitig ist ein Rich-Type-System nicht nur beim
Schreiben von Code nützlich, sondern in viel größerem Umfang auch beim
Lesen von Code . Wenn es für Sie einfach ist, in der Codebasis zu navigieren, zu verstehen, was sie tut, und es außerdem nicht beängstigend (oder nicht so beängstigend) ist, das
Refactoring durchzuführen , wird die Sprache sowohl aus technischer als auch aus angewandter Sicht sehr positiv charakterisiert.
FP gegen OOPEine andere Frage, die in solchen Diskussionen häufig aufgeworfen wird, ist, ob die Scala-Sprache weiterhin an der Synthese von OOP und FP festhalten oder sich auf einem rein funktionalen Weg entwickeln sollte. Ich bin ein
Befürworter der Synthese , insbesondere weil FP und OOP meiner Meinung nach keine alternativen Ansätze sind, sondern sich gegenseitig ergänzen.
FP
programmiert mit Funktionen , obwohl keine, aber referenziell transparent (siehe diese
Antwort auf reddit in einem früheren Thread, in dem referenzielle Transparenz perfekt erklärt wird). In OOP wird die Kommunikation mit Objekten mithilfe von „Nachrichten“ oder in unserer Terminologie mithilfe von Aufrufen virtueller Methoden organisiert. Es gibt keinen einzigen Grund, warum diese beiden Ansätze nicht koexistieren könnten, und Scala hat dies bereits demonstriert!
In einem
Tweet zu den Vorzügen von Scala erwähnt John de Goes einige OOP-Funktionen, die für einen rein funktionalen Ansatz nützlich sind, insbesondere
erstklassige Module (erhalten durch Zusammensetzen von Objekten),
Punktsyntax (Aufrufen von Methoden in Objekten) und
Klassen- /
Typinstanzen als erstklassige Konstrukte . All dies sind Elemente einer erfolgreichen Kombination zweier Paradigmen. Vielleicht sind noch mehr gleich um die Ecke?
Das „Synthese“ -Projekt ist noch nicht abgeschlossen, hier gibt es definitiv ein Diskussionsfeld. Ein unvollständiger Aspekt ist die vorgeschlagene Syntax für Erweiterungsmethoden, die viel verwirrendere implizite Konvertierungen ersetzen sollte. Zum anderen wird die Syntax von Typklassen optimiert.
Der vor einiger Zeit gemachte
Vorschlag ist eindeutig grob und deckt einige der häufigsten Verwendungen von Monaden in Scala nicht ab. Einige Vorschläge sind besser, andere müssen verfeinert werden, aber es ist gut, dass sie eingehen und Diskussionen darüber geführt werden. Dank ihnen lebt die Sprache und letztendlich ist die beste Lösung darin festgelegt.
Scala 3Scala 3 wird in zwei Jahren veröffentlicht. Darin werden eine Reihe interessanter Möglichkeiten auftauchen, insbesondere undurchsichtige Typen, Merkmalsparameter, ein neuer Metaprogrammierungsansatz, Vereinigungs- und Schnitttypen, implizite Funktionstypen - dies sind nur einige Beispiele. Natürlich gibt es (begründete) Bedenken hinsichtlich der Migration.
Es ist bereits bekannt, dass ein spezielles Tool für die
automatische Codemigration von Scala 2 zu Scala 3 mithilfe von
Scalafix eingeführt wird . Da Scala eine statisch typisierte Sprache ist, kann eine solche Aufgabe in großem Maßstab gelöst werden und ist viel einfacher als beispielsweise in Python. Aber hier gibt es natürlich keine Magie: Selbst wenn dieses Tool den Code zu 99% korrekt abdeckt, bleibt 1% der problematischsten Fälle bestehen. Da Sie sich nicht auf Magie verlassen können, muss die Migration dieser Fragmente manuell erfolgen.
Dies sind die Kosten für die Arbeit mit einer sich aktiv entwickelnden Sprache: Sie erhalten die neuesten Möglichkeiten, aber einige davon sind tatsächlich nicht so gut und müssen verbessert werden. Trotzdem sind die vorgeschlagenen Änderungen nicht revolutionär. Die Sprache von Scala 3 ist Scala 2 sehr ähnlich, es werden keine größeren Paradigmenwechsel erwartet.
Es ist ermutigend, dass das Scala-Team die Migration ernst nimmt. Während frühere Migrationen zwischen älteren Versionen von Scala (z. B. von 2,8 auf 2,9) ziemlich aufwändig waren, verliefen die jüngsten Migrationen viel besser. Es sind drei Hauptparteien beteiligt: EPFL,
ScalaCenter und
Lightbend, die alle (oft zusammen) arbeiten, um die Migration zu erleichtern. Zum Beispiel gibt es ein binärkompatibles
MIMA- Tool, und in der Community werden ständig zahlreiche neue Bibliotheken erstellt, um eine bequeme Arbeit mit neuen Versionen von Scala zu gewährleisten.
Schließlich sollte das noch nicht fertiggestellte TASTY-Tool (das dementsprechend noch nicht evaluiert werden kann) die Verwendung von Binärdateien von Scala 2 bis Scala 3 sicherstellen.
Warum also Scala verwenden?Was sind die Gründe, um bei Scala anzuhalten, wenn Sie diese Sprache aus geschäftlicher Sicht betrachten? Alle oben genannten technischen Vorteile sind direkt für das Geschäft nützlich. Wenn Sie eine Sprache haben, in der Sie komplexen Code mit weniger Fehlern schreiben können, erhalten Sie nur minimale Verzögerungen bei den Begriffen und zufriedene Benutzer. Wenn Sie leistungsstarke, praktisch rutschfeste Wettbewerbsanwendungen für Scala schreiben, für die in Scala Spezialwerkzeuge bereitgestellt werden, ist dies ein schwerwiegender Vorteil für Ihr Unternehmen.
Vergessen Sie außerdem nicht
Spark , die führende Plattform für
verteilte Datenanalysen . Scala wird nicht nur verwendet, um Spark als solchen zu implementieren, sondern auch um die Berechnungen selbst zu definieren. Hier ist eine weitere datenwissenschaftlich orientierte Abstraktion, die ein komplexes Rechenmodell verbirgt.
ZusammenfassungNatürlich gibt es Probleme in Scala, aber wo sind sie nicht? Der Grund für Optimismus ist, dass viele Menschen, die Scala täglich verwenden, aktiv daran arbeiten,
die Tools , Bibliotheken und die Sprache selbst zu
verbessern . Ich kann davon ausgehen, dass sie weiterhin mit Scala zusammenarbeiten, gerade weil trotz aller verfügbaren Mängel keine einzige Sprache für ihr Fachgebiet so gut geeignet ist.
Mit Scala können Sie Ihren eigenen Programmierstil entwickeln, unabhängig davon, welche Sprache Sie früher verwendet haben: Java, Ruby oder einfach nur selbst programmieren. Es gibt keinen einzigartig gewinnenden Ansatz für Scala. entweder Akkas
zwingenderer Ansatz oder Cats und Scalaz '
funktionalerer Ansatz.
Hier zeigt sich das Problem: In der Scala-Community gibt es Fraktionen, die sich an den „reaktiven“, „synthetischen“ OOP / AF-Ansatz und den reinen AF halten. Tatsächlich ist dies jedoch ein großer Vorteil. Aufgrund dieser Vielfalt finden Diskussionen statt, viele unterschiedliche Meinungen werden aus unterschiedlichen Blickwinkeln geäußert. Auf diese Weise können Sie perfekt lernen, wie Sie nicht standardmäßige Probleme lösen und Ihre eigenen Tools bereichern.
Welchen Weg Sie auch in Scala wählen, Sie werden von einer beeindruckenden Gemeinschaft von Kollegen unterstützt, die an der Entwicklung von Bibliotheken und Frameworks beteiligt sind. Diese Leute sind immer bereit zu helfen und neue Ideen zu diskutieren.