2013-07-01 4 views
12

Ich habe gerade bemerkt, dass Scala Makros hat, aber ich habe nie einen Code gesehen, der sie verwendet. Sie scheinen auch ziemlich verschieden von C-Präprozessor-Makros und dergleichen zu sein. Wenn man die overview Makros liest, sieht es nicht so aus, als würden sie irgendetwas anbieten, was vorher in Scala nicht möglich war. Unter der Motivation Überschrift gibt es eine Liste der Dinge, die Makros zu aktivieren:Scala-Makros, wo werden sie verwendet?

  • Sprache Virtualisierung (Überlastung/Überschreiben Semantik der ursprünglichen Programmiersprache tiefe Einbettung von DSLs zu ermöglichen), Verdinglichung
  • Programm (Bereitstellung von Programmen mit Mitteln ihren eigenen Code) auf der Grundlage Programm Verdinglichung),
  • algorithmisches Programm 012
  • Selbstoptimierung (Selbstanwendung von Optimierungen domänenspezifischen zu inspizierenKonstruktion (Generierung von Code, der mühsam mit den Abstraktionen geschrieben wird, die von einer Programmiersprache unterstützt werden).

Später im Menü gibt es experimentelle Makro-Funktionen, wie zum Beispiel Typ-Makros, quasiquotes, untypisierten Makros und noch mehr. Dies ist eindeutig gefragt!

All diese scheinen wie nette Features für Leute, die sehr anspruchsvolle Bibliotheken mit einem starken Verständnis von Scala bauen. Aber bieten Makros auch etwas für den durchschnittlichen Scala-Entwickler? Werden Makros meinen Scala-Code verbessern?

+1

Sie einen Blick auf unsere neuesten Papier nehmen, die einige der interessantesten Verwendungen von Makros skizziert: http://scalamacros.org/ papstalks/2013-04-22-LetOurPowersCombine.pdf. –

+0

Hier ist ein dedizierter Dokumentations-Artikel: http://docs.scala-lang.org/overviews/macros/usecases.html –

Antwort

17

Als "durchschnittlicher" Scala-Entwickler werden Sie höchstwahrscheinlich keine Makros selbst schreiben, außer Sie haben einen sehr guten Grund.

Makros sind eine Methode der Kompilierzeit Meta-Programmierung, das heißt Sie Programme programmieren. Zum Beispiel ist ein Def-Makro, das Teil von Scala 2.10 ist, aber immer noch "experimentell", wie eine normale Methode, aber wenn Sie diese Methode im Code aufrufen, ersetzt der Compiler diesen Aufruf mit dem Makro, das hinter dieser Methode versteckt ist wird produzieren (ein neues Codefragment).


Ein sehr einfaches Beispiel. Integrieren Sie das Datum, wenn das Projekt in den Code kompiliert wurde:

import java.util.Date 
import reflect.macros.Context 
import language.experimental.macros 

object CompileTime { 
    def apply(): Date = macro applyImpl 

    def applyImpl(c: Context)(): c.Expr[Date] = { 
    import c.universe._ 
    val now  = System.currentTimeMillis() // this is executed during compilation! 
    val nowExpr = c.Expr[Long](Literal(Constant(now))) 
    val code = reify(new Date(nowExpr.splice)) 
    c.Expr(code.tree) 
    } 
} 

Mit Hilfe dieser Makro (der folgende Code muss separat aus dem Makrocode oben kompiliert werden):

object MacroTest extends App { 
    println(s"This project was compiled on ${CompileTime()}") 
} 

(Wenn Sie laufen dass die Kompilierzeit tatsächlich konstant ist.


Also kurz gesagt, Makros bieten eine Funktionalität, die war nicht in jeder früheren Scala-Version verfügbar. Sie können Dinge mit Makros tun, die Sie sonst nicht tun können (oft können Sie ähnliche Dinge mit der Laufzeitreflexion schreiben, aber Makros werden zur Kompilierungszeit überprüft).

Als Benutzer werden Sie jedoch mehr und mehr Bibliotheken ausgesetzt, die Makros enthalten, weil sie leistungsfähige Konstrukte bereitstellen können, die vollständig typsicher sind.Beispielsweise können automatische Serialisierer für JSON aus einer Fallklasse mit Makros realisiert werden, da das Makro den Typ Ihrer Fallklasse prüfen und die richtige Programmstruktur (AST) zum Lesen und Schreiben dieser Fallklasse erstellen kann, ohne Laufzeitverlust Fehler.

Einige zufällige Links

+1

Eine Reihe von Logging- und Serialisierungs-Bibliotheken verwenden Makros hinter den Kulissen. – Andy