/ / Je možné zjednodušiť deklaráciu argumentov metódy Scala pomocou makier? - škála, makrá, škála-2.10

Je možné zjednodušiť deklaráciu argumentov metódy Scala pomocou makier? - scala, makrá, scala-2.10

Metódy sú často deklarované so zrejmými názvami parametrov, napr.

def myMethod(s: String, image: BufferedImage, mesh: Mesh) { ... }

Názvy parametrov zodpovedajú typom parametrov.

1) „s“ sa často používa pre reťazec

2) „i“ pre Int

3) názov triedy s malým písmom pre jedno slovo s názvom triedy (Mesh -> mesh)

4) posledné slovo z názvu triedy s malými písmenami pre dlhé názvy tried (BufferedImage -> obrázok)

(Samozrejme, nebolo by to vhodné pre VŠETKY metódy a argumenty. Niekto by samozrejme uprednostnil iné pravidlá ...)

Makrá Scala sú určené na generovanie niektorých výrazov v kóde. Chcel by som napísať niekoľko konkrétnych makier na konverziu na opravu výrazov Scala, napríklad:

// "arguments interpolation" style
// like string interpolation
def myMethod s[String, BufferedImage, Mesh]
{ /* code using vars "s", "image", "mesh" */ }

// or even better:
mydef myMethod[String, BufferedImage, Mesh]
{ /* code using vars "s", "image", "mesh" */ }

Je to možné?

odpovede:

2 pre odpoveď č. 1

Momentálne to nie je možné a pravdepodobne budenikdy nebuď. Makrá nemôžu zavádzať svoju vlastnú syntax - musia byť reprezentované platným kódom Scala (ktorý je možné spustiť v čase kompilácie) a tiež musia vygenerovať platný kód Scala (lepšie povedané platný Scala AST).

Oba vaše zobrazené príklady nie sú platným kódom Scala, takže s nimi makra nemôžu pracovať. Napriek tomu súčasná nočná výstavba Makro raj obsahuje netypové makra. Umožňujú písať Scala kód, ktorý je po rozšírení typovo kontrolovaný, to znamená, že je možné písať:

forM({i = 0; i < 10; i += 1}) {
println(i)
}

Všimnite si, že zložené zátvorky vo vnútri prvého zoznamu parametrov sú potrebné, pretože aj keď kód nie je typicky kontrolovaný, keď ho niekto napíše, musí predstavovať platnú Scala AST.

Implementácia tohto makra vyzerá takto:

def forM(header: _)(body: _) = macro __forM

def __forM(c: Context)(header: c.Tree)(body: c.Tree): c.Tree = {
import c.universe._
header match {
case Block(
List(
Assign(Ident(TermName(name)), Literal(Constant(start))),
Apply(Select(Ident(TermName(name2)), TermName(comparison)), List(Literal(Constant(end))))
),
Apply(Select(Ident(TermName(name3)), TermName(incrementation)), List(Literal(Constant(inc))))
) =>

// here one can generate the behavior of the loop
// but omit full implementation for clarity now ...

}
}

Namiesto už typicky skontrolovaného výrazumakro očakáva iba strom, ktorý je po rozšírení typicky skontrolovaný. Samotné volanie metódy očakáva dva zoznamy parametrov, ktorých typy parametrov sa môžu po fáze rozšírenia oneskoriť, ak sa použije podčiarkovník.

V súčasnosti je ich trochu dokumentácia k dispozícii, ale pretože je extrémne beta, veľa vecí sa pravdepodobne v budúcnosti zmení.

S makrami typu je možné napísať niečo také:

object O extends M {
// traverse the body of O to find what you want
}

type M(x: _) = macro __M

def __M(c: Context)(x: c.Tree): c.Tree = {
// omit full implementation for clarity ...
}

To je pekné, aby sa oddialilo typická kontrola celého tela, pretože to umožňuje ochladiť veci ...


Makrá, ktoré môžu meniť Scalasovu syntax, nie sú momentálne plánované a pravdepodobne to nie je dobrý nápad. Nemôžem povedať, či sa to stane jedného dňa, iba budúcnosť nám to môže povedať.


2 pre odpoveď č. 2

Odhliadnuc od „prečo“ (nie, naozaj, prečo to chcete urobiť?), Odpoveď je nie, pretože pokiaľ viem, makrá nemôžu (v súčasnom stave) generovať metódy alebo typy, iba výrazy.