2013-07-01 13 views
12

Właśnie zauważyłem, że Scala ma makra, ale nigdy nie widziałem żadnego kodu, który je wykorzystuje. Wydają się również zupełnie różnić od makr preprocesora C i tym podobnych. Po przeczytaniu makr nie wyglądało na to, że oferują coś, co wcześniej nie było możliwe w Scali. Pod nagłówkiem motywacji, tam znajduje się lista rzeczy, które makra umożliwiają:Scala macros, gdzie są one używane?

  • Język wirtualizację (Imax/nadrzędne semantykę oryginalnym języku programowania na włączyć głębokie osadzenie DSL),
  • Program reifikacja (dostarczanie programów ze środków wglądu do swoich własny kod),
  • Samooptymalizacja (samo stosowanie specyficznych domen optymalizacje na podstawie programu reifikację)
  • algorytmiczne programu (generowanie kodu, który jest żmudny w pisaniu z abstrakcjami obsługiwanych przez język programowania).

Później w menu, istnieją eksperymentalne funkcje makro, takie jak makra typu, quasiquotes, bez typu makr i jeszcze więcej. Oczywiście istnieje na to popyt!

Wszystkie te wydają się być fajnymi funkcjami dla osób, które budują bardzo wyrafinowane biblioteki z silnym zrozumieniem Scali. Ale czy makra oferują coś także dla przeciętnego programisty Scala? Czy użycie makr sprawi, że mój kod Scala będzie lepszy?

+1

Można również zapoznać się z naszą najnowszą papieru, który przedstawia niektóre z interesujących zastosowań makr: http://scalamacros.org/ paperstalks/2013-04-22-LetOurPowersCombine.pdf. –

+0

Oto dedykowany artykuł witryny doc: http://docs.scala-lang.org/overviews/macros/usecases.html –

Odpowiedz

17

Jako "przeciętny" programista Scala, najprawdopodobniej nie będziesz pisać makr sam, chyba że masz bardzo dobry powód.

Makra to metoda kompilacji meta czasu, czyli programowania programów. Na przykład, def-macro-które jest częścią Scala 2.10, ale nadal "eksperymentalne" - wygląda jak zwykła metoda, ale za każdym razem, gdy wywołasz tę metodę w swoim kodzie, kompilator zastąpi to wywołanie tym, co to makro ukryte za tą metodą wytworzy (nowy fragment kodu).


bardzo prosty przykład. Włączenie datę, kiedy projekt został skompilowany do kodu:

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) 
    } 
} 

użyciu tego makra (poniższy kod musi zostać skompilowany osobno z kodu makro powyżej):

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

(Po uruchomieniu to wiele razy, widzisz, że czas kompilacji jest rzeczywiście stały)


Krótko mówiąc, makra oferują funkcjonalność, która był nie dostępny w żadnej poprzedniej wersji Scala. Możesz robić rzeczy za pomocą makr, których nie możesz wykonać w inny sposób (często możesz pisać podobne rzeczy za pomocą refleksji runtime, ale makra są sprawdzane w czasie kompilacji).

Jako użytkownik będziesz jednak coraz bardziej narażony na działanie bibliotek zawierających makra, ponieważ mogą one dostarczyć potężne konstrukcje, które są w pełni typu bezpieczne.Na przykład automatyczne serializatory dla JSON z klasy case mogą być realizowane za pomocą makr, ponieważ makro może sprawdzać typ klasy case i budować poprawną strukturę programu (AST), aby odczytać i zapisać tę klasę case, bez niebezpieczeństwa runtime niepowodzenie.

jakiś przypadkowy linki

+1

Wiele bibliotek rejestrowania i serializacji używa makr za kulisami. – Andy

Powiązane problemy