SP005: Macros, Compiler und Web-Geschichten
Scala Profis
German - April 25, 2016 20:21 - 1 hour - 51.2 MBTechnology News Tech News Homepage Download Apple Podcasts Google Podcasts Overcast Castro Pocket Casts RSS feed
SP005: Macros, Compiler und Web-Geschichten
Erste Erfahrungen mit Macros
Endlich hat Sven selber Erfahrungen mit Macros gesammelt. Auslöser waren erste Gehversuche mit Scala.js zur Umsetzung eines AngularJS-Projekts auf Basis von scalajs-angular.
Scala.js bietet nahezu alle Möglichkeiten von Scala, aber Reflection gehört nicht dazu. Probleme, die in Java üblicherweise über Reflection gelöst werden, lassen sich in Scala.js aber mit Macros meist eleganter und vor Allem zur Compilier-Zeit lösen.
scalajs-angular definiert zum Beispiel eine @injectable-Annotation um in Scala.js geschriebenen Komponenten den von Angular für Dependency-Injection benötigten Namen zuzuweisen. Darauf basierend hat Sven einige nützliche Macros erstellt:
Methode um sich vom Injector eine Instanz eines Typs liefern zu lassen ohne manuell den Namen angeben und dann auch noch explizit casten zu müssen (PR #79)
Methoden relativeTemplate und companionTemplate, um in HTML-Dateien abgelegte Templates zur Compile-Zeit als String einbetten zu können (PR #83)
Erfahrungen
Wenn man eine Vorlage hat ist die Erstellung eines Makros mit reify oder Quasiquotes relativ einfach.
Ohne Vorlage ein Macro zu erstellen ist für mich weiterhin schwierig.
Auch nach dem Schreiben erschließen mir sich diverse Aspekte nicht (Beispiel splice) — hier ist wohl doch ein tiefergreifendes Verständnis des ASTs und der zugehörigen API notwendig. Gibt es da irgendwo eine brauchbar Beschreibung?
Macros können nur auf Objekten definiert werden — nicht auf Klassen. Um auf Instanzen zu operieren sind also Hilfs-Objekte notwendig — implizite Parameter können die Nutzung vereinfachen.
Die notwendige Verteilung von Macros und Nutzung auf zwei Projekte macht die Erstellung von Libraries mit Komfort-Funktionen schwierig.
Mehr zu meinen Erfahrungen mit Scala.js in der nächsten Episode.
SourceCode
Kleine Scala Bibliothek, die Zugriff auf Source-Code Informationen wie z.B. den Dateinamen oder der Zeile zur Laufzeit bietet. Die benötigten Objekte können dazu über implizite Parameter oder implicitly geholt werden.
User-Cases
Logging
def log(message: String)(implicit line sourcecode.Line, file sourcecode.File): Unit =
println(s"[${file.value}:${line.value}]: $message")
Übernehmen von Namen
val CREATION_DATE = newField("CREATION_DATE", ...)
=>
val CREATION_DATE = newField(...)
Debug Ausgaben
def log[A](value: sourcecode.Text[V])(implicit name sourcecode.Name): Unit =
println(s"${name.value}(${value.source} = ${value.value})")
def foo(arg: String): Unit = {
log(arg)
...
}
foo("bar")
Gibt aus: foo(arg = bar)
Links
Dotty
Compiliert den größten Teil er Scala Standard Library und eine handvoll anderer Projekte
Ziel ist es einen neuen, schlanken Compiler zu erhalten, der sich deutlich leichter weiterentwickeln lässt (wie der Roslyn Compiler für C#)
Das Vorgehen über einen experimentellen Compiler hat sich ebenfalls bei Roslyn bewährt (der übrigens laut eigenen Aussagen einiges von Scala übernommen hat)
Ob dotty irgendwann scalac ablösen wird ist nicht klar — es kann auch sein, dass lediglich Erkenntnisse aus dotty nach scalac zurückfließen.
Scala 2.12.0‑M4
Vervollständigt die Features von 2.12. Auffälligste Änderung ist der neue ScalaDoc-Style.
Es folgen M5 und danach RC1.
Scala 2.12 Features
In Scala 2.12 geht es im Wesentlichen darum die neuen Java 8 Features optimal zu nutzen:
Traits zu Interfaces compilieren (bisher Klasse und Interface)
Java 8‑styled Lambdas:
Keine anonymen Klassen mehr und somit deutlich kleinere JARs.
Bessere Java-Scala interoperabilität
Neues Compiler-Backend arbeitet schneller
Neuer Bytecode-Optimizer (unter anderem Inlining von final Methoden)
Links
Scala 2.12.0‑M4 is now available
SI-2712
Links
SI-2712
Explaining Miles’s Magic
Frontend Asset-Pipeline mit Play
sbt-webverspricht mit Web-JARs die einfache Einbindung von JavaScript-Libraries und mit Plug-Ins einen einfachen Aufbau einer Frontend-Asset-Pipeline, um z.B. LESS- oder SASS-Dateien zu CSS zu compilieren, ES6-JavaScript nach ES5 zu compilieren, zu konkatenieren und zu minifizieren.
In der Praxis klappt das leider nicht: Die sbt-web-Plug-Ins sind halbherzig umgesetzt:
Optionen fehlen oder funktionieren nicht wie versprochen
sinnvolle Verarbeitungsketten (z.B. mit der Erstellung von Source-Maps über mehrere Schritte hinweg) lassen sich gar nicht realisieren.
Ausweg
Mit sbt-web-Plug-Ins wie zum Beispiel sbt-play-gulp lässt sich eine Asset-Pipeline mit im JavaScript-Umfeld etablierten Build-Systemen (in diesem Fall GULP) aufbauen und in de Play-Lifecycle einbinden.
ScalaCSS
Scala Bibliothek zum Erzeugen von CSS, ähnlich wie LESS oder SASS, allerdings mit Scala-Code.
Browser Prefix
Bei CSS-Attributen oder Funktionen bei denen für die verschiedenen Browser ein Prefix verwendet werden muss kümmert ScalaCSS sich automatisch darum die Prefixe für alle Browser gesetzt werden.
Konflikterkennung
// In MyGenericTheme.scala
val button = style(margin(8 px, auto), ...)
// In UserStyles.scala
val userTitle = style(marginLeft(4 ex), ...)
...
val userButton = style(button, userTitle, ...)
ScalaCSS produziert hier auf Wunsch eine Warnung und es kann festgelegt werden, welcher Stil gewinnen soll.
Links
Github Seite
Dokumentation
Can I use…
scalatags
Gib uns Dein Feedback als Kommentar auf unserer Web-Site, via Twitter oder Google+.
Kapitel
Intro (00:00:00.000)
Erste Erfahrungen mit Macros (00:01:10.249)
SourceCode (00:23:53.474)
Dotty (00:36:01.091)
Scala 2.12.0‑M4 (00:45:53.588)
SI-2712 (00:51:31.693)
Frontend Asset-Pipeline mit Play (00:54:21.364)
ScalaCSS (01:01:41.010)
Outro (01:10:03.021)
Lizenz
Scala Profis von Benjamin Hagemeister & Sven Wiegand ist lizenziert unter einer Creative Commons Namensnennung — Keine Bearbeitungen 4.0 International Lizenz.
Über diese Lizenz hinausgehende Erlaubnisse kannst Du unter http://scalaprofis.de erhalten.
Titelsong basierend auf Wish You Were Here von THE.MADPIX.PROJECT lizensiert unter Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0).