Warum Mann Scala?

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?

Projektfachbereich

Zunä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.

Sprachschwierigkeiten

Hinweis: 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 besser

Es 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 OOP

Eine 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 3

Scala 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.

Zusammenfassung

Natü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.

Source: https://habr.com/ru/post/de423317/


All Articles