Scala 2.10 Makros im Vergleich zu dem, was in Java verfügbar ist

8

Ich kenne dieses Feld nicht so gut.

Kann jemand erklären, was in Scala 2.10 mit Makros möglich ist, verglichen mit dem, was in Java mit Kompilierungs-Präprozessoren und Werkzeugen wie CGLIB, ASM, Byteman ... möglich ist?

    
Sebastien Lorber 12.12.2012, 10:34
quelle

2 Antworten

16

[Update] : Ich habe versucht, ein Beispiel mit Slick zu integrieren. Es ist schwierig, eine Menge dieser Dinge für ein Java-Publikum (nicht Scala) zusammenzufassen.

Makros in Scala 2.10 bringen eine vollwertige Metaprogrammierung in die richtige Sprache als erstklassiger Bürger.

%Vor%

Konnten Eigenschaften wie diese allgemein entweder durch textuelle Vorverarbeitung oder erreicht werden Byte-Code-Manipulation auf sichere und saubere Weise?

Die Metaprogrammierung kommt irgendwann zur Code-Generierung, und ohne Qualifizierung ist sie ein Überbegriff für eine Vielzahl von Techniken - im Interesse, nicht selbst ein bisschen Code schreiben zu müssen - wenn man so wäre Auflisten einiger dieser Techniken in einer ungefähren Reihenfolge der Phase - von vorkompilierter roher Quelle bis zum Ausführen von Code könnte die Liste wie folgt aussehen:

  • Textuelle Quellenpräprozessoren (C)
  • Template-Systeme (C ++) (viele mögen argumentieren, dass die oben genannten auch sind primitiv zu betrachten)
  • Reflexion "natürlich verfügbar" in einigen dynamischen Sprachen (Ruby)
  • Laufzeitreflexion in statisch typisierten Sprachen (Java), die verleiht der Sprache eine gewisse Dynamik auf Kosten der Typsicherheit
  • Byte-Code-Manipulation

(Ich habe Makrosysteme ausgelassen, die zur Kompilierungszeit ausführen , mehr dazu im nächsten Absatz.)

Zunächst sollten Sie in Betracht ziehen, dass alle oben genannten Techniken im Wesentlichen Code generieren - sei es die Generierung / Manipulation von reinem Textquellcode oder die Erzeugung / Manipulation von Bytecode zur Laufzeit.

Was ist mit Makrosystemen? Makros, die zur Kompilierungszeit ausgeführt werden und nicht auf Textquellcode oder kompiliertem Bytecode arbeiten, sondern auf einer weitaus wertvolleren Stufe - sie arbeiten während des AST des Programms Kompilierung und die dort verfügbaren Informationen und die Integration in den Kompilierungsprozess bringen ihnen einige starke Vorteile. Sie sind sowohl in dynamischen Sprachen (wie Lisp und Dylan) als auch in statisch typisierten Sprachen ( Vorlage Haskell und Scala 2.10 selbstreinigende Makros) verfügbar.

>

In Bezug auf Makros in Scala 2.10, von meinem Kopf, Ich würde sagen, der wichtigste Vorteil wäre:

Typ Sicherheit : Kompilierungs-Präprozessoren und Byte-Code-Manipulation können nicht Nutzen Sie das Typsystem. Mit Makros - insbesondere Kompilierzeit Makros - die Art, die Scala 2.10 haben wird, ist die Makrosprache Scala selbst mit Zugriff auf die API des Compilers. Jede Art von statischer Analyse / Überprüfung von Quellcode mit voller Typinformation, die normalerweise nur zur Kompilierzeit möglich ist, wird für Makros verfügbar sein.

(sichere) Syntaxerweiterung : Makros ermöglichen die Anpassung von Sprachkonstrukten, um DSLs besser zu implementieren. Ein gutes Beispiel ist Slick , eine Datenbankbibliothek, mit der Sie SQL-Abfragen als typsicheren Scala-Code ausdrücken können:

Betrachten wir zuerst die einfache Scala-Listenverarbeitung - noch keine Rede von Datenbanken oder Makros:

%Vor%

Slick, sogar die Nicht-Makro -Version, lässt Sie Datenbanktabellen so behandeln, als wären sie Scala Collections: So erreicht die non-macro -Version (Slick nennt es die embedding embedding API) dasselbe, wenn Coffee s stattdessen eine SQL-Tabelle ist:

%Vor%

Schließen Sie genug! Aber hier wird die === -Methode verwendet, um == zu imitieren, was aus dem offensichtlichen Grund, dass Sie die -Darstellung einer SQL-Spalte nicht mit einer tatsächlichen Int vergleichen können, nicht verwendet werden kann.

Dies ist in der Makro-Version gelöst, wenn Sie Scala 2.10 handlich haben:

%Vor%

Hier werden also Makros verwendet, um die gleiche Syntax sowohl für SQL als auch für eine einfache Scala-Sammlung bereitzustellen. Es ist die Kombination von Typsicherheit und Makrohygiene zu der bereits vorhandenen Ausdruckskraft und Kompositionalität von Scala, die Macros attraktiv macht.

Betrachten Sie auch dieses Beispiel aus dem Link, der von der anderen Antwort beigetragen wurde:

%Vor%

Damit wird ein Makro assert definiert, dessen Verwendung einem Methodenaufruf ähnelt:

%Vor%

Nur, weil assert ein Makro und keine Methode ist, wird der boolesche Ausdruck 2 + 2 == 4 nur ausgewertet, wenn Assertions aktiviert sind . Beachten Sie, dass es eine Kurzschrift gibt, die Ihnen beim Ausdruck von ASTs hilft, aber dieses Beispiel ist hoffentlich auf diese Weise klarer .

Last but not least - Scala 2.10 Makros werden Teil von Scala - Integriert in die Standard-Distribution - im Gegensatz zu einigen Drittanbieter-Bibliothek zur Verfügung gestellt.

    
Faiz 12.12.2012, 10:47
quelle
4

Zusätzlich zu den von Faiz erwähnten Punkten sind Scala-Makros hygienisch : Sie werden nicht versehentlich von Capturing betroffen sein Identifikatoren. Scala-Makros sind insbesondere Selbstreinigung : Hygiene wird durch Verdinglichung erreicht, wo die Verdinglichung selbst ist ein Makro. Für einen tieferen Einblick, wie das funktioniert, siehe Scala-Makros, ein technischer Bericht .

    
michid 12.12.2012 11:39
quelle

Tags und Links