8000 macro bundles and compilers · rssh/scala.github.com@781e68f · GitHub
[go: up one dir, main page]

Skip to content

Commit 781e68f

Browse files
committed
macro bundles and compilers
1 parent 2a89cb8 commit 781e68f

File tree

6 files changed

+78
-5
lines changed

6 files changed

+78
-5
lines changed

overviews/macros/bundles.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
layout: overview-large
3+
title: Macro Bundles
4+
5+
disqus: true
6+
7+
partof: macros
8+
num: 6
9+
outof: 6
10+
---
11+
<span class="label important" style="float: right;">MACRO PARADISE</span>
12+
13+
**Eugene Burmako**
14+
15+
Macro bundles and macro compilers are pre-release features included in so-called macro paradise, an experimental branch in the official Scala repository. Follow the instructions at the ["Macro Paradise"](/overviews/macros/paradise.html) page to download and use our nightly builds.
16+
17+
## Macro bundles
18+
19+
Currently, in Scala 2.10.0, macro implementations are represented with functions. Once the compiler sees an application of a macro definition,
20+
it calls the macro implementation - as simple as that. However practice shows that just functions are often not enough due to the
21+
following reasons:
22+
23+
1. Being limited to functions makes modularizing complex macros awkward. It's quite typical to see macro logic concentrate in helper
24+
traits outside macro implementations, turning implementations into trivial wrappers, which just instantiate and call helpers.
25+
26+
2. Moreover, since macro parameters are path-dependent on the macro context, [special incantations](/overviews/macros/overview.html#writing_bigger_macros) are required to wire implementations and helpers together.
27+
28+
3. As macros evolved it [became apparent](https://twitter.com/milessabin/status/281379835773857792) that there should exist different
29+
interfaces of communication between the compiler and macros. At the moment compiler can only expand macros, but what if it wanted to
30+
ask a macro to help it with type inference?
31+
32+
Macro bundles provide a solution to these problems by allowing macro implementations to be declared in traits, which extend
33+
`scala.reflect.macros.Macro`. This base trait predefines the `c: Context` variable, relieving macro implementations from having
34+
to declare it in their signatures, which simplifies modularization.
35+
36+
trait Macro {
37+
val c: Context
38+
}
39+
40+
Referencing macro implementations defined in bundles works in the same way as with impls defined in objects. You specify a bundle name
41+
and then select a method from it, providing type arguments if necessary.
42+
43+
import scala.reflect.macros.Context
44+
import scala.reflect.macros.Macro
45+
46+
trait Impl extends Macro {
47+
def mono = c.literalUnit
48+
def poly[T: c.WeakTypeTag] = c.literal(c.weakTypeOf[T].toString)
49+
}
50+
51+
object Macros {
52+
def mono = macro Impl.mono
53+
def poly[T] = macro Impl.poly[T]
54+
}
55+
56+
## Macro compilers
57+
58+
When I was implementing macro bundles, it became apparent that the mechanism which links macro definitions with macro implementations
59+
is too rigid. This mechanism simply used hardcoded logic in `scala/tools/nsc/typechecker/Macros.scala`, which takes the right-hand side
60+
of a macro def, typechecks it as a reference to a static method and then uses that method as a corresponding macro implementation.
61+
62+
Now compilation of macro defs is extensible. Inste 8000 ad of using a hardcoded implementation to look up macro impls,
63+
the macro engine performs an implicit search of a `MacroCompiler` in scope and then invokes its `resolveMacroImpl` method,
64+
passing it the `DefDef` of a macro def and expecting a reference to a static method in return. Of course, `resolveMacroImpl`
65+
should itself be a macro, namely [an untyped one](/overviews/macros/untypedmacros.md), for this to work.
66+
67+
trait MacroCompiler {
68+
def resolveMacroImpl(macroDef: _): _ = macro ???
69+
}
70+
71+
Default instance of the type class, `Predef.DefaultMacroCompiler`, implements formerly hardcoded typechecking logic.
72+
Alternative implementations could, for instance, provide lightweight syntax for macro defs, generating macro impls
73+
on-the-fly using `c.introduceTopLevel`.

overviews/macros/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ disqus: true
66

77
partof: macros
88
num: 1
9-
outof: 5
9+
outof: 6
1010
---
1111
<span class="label warning" style="float: right;">EXPERIMENTAL</span>
1212

overviews/macros/paradise.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ disqus: true
66

77
partof: macros
88
num: 2
9-
outof: 5
9+
outof: 6
1010
---
1111
<span class="label important" style="float: right;">MACRO PARADISE</span>
1212

overviews/macros/quasiquotes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ disqus: true
66

77
partof: macros
88
num: 4
9-
outof: 5
9+
outof: 6
1010
---
1111
<a href="/overviews/macros/paradise.html"><span class="label important" style="float: right;">MACRO PARADISE</span></a>
1212

overviews/macros/typemacros.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ disqus: true
66

77
partof: macros
88
num: 3
9-
outof: 5
9+
outof: 6
1010
---
1111
<a href="/overviews/macros/paradise.html"><span class="label important" style="float: right;">MACRO PARADISE</span></a>
1212

overviews/macros/untypedmacros.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ disqus: true
66

77
partof: macros
88
num: 5
9-
outof: 5
9+
outof: 6
1010
---
1111
<a href="/overviews/macros/paradise.html"><span class="label important" style="float: right;">MACRO PARADISE</span></a>
1212

0 commit comments

Comments
 (0)
0