Skip to content

Commit 65583e8

Browse files
committed
Merge pull request #306 from xeno-by/master
updates to macro docs
2 parents 69f260f + 13bd588 commit 65583e8

File tree

7 files changed

+107
-11
lines changed

7 files changed

+107
-11
lines changed

overviews/macros/annotations.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ title: Macro Annotations
55
disqus: true
66

77
partof: macros
8-
num: 8
9-
outof: 10
8+
num: 9
9+
outof: 11
1010
languages: [ja]
1111
---
1212
<span class="label important" style="float: right;">MACRO PARADISE</span>

overviews/macros/extractors.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
layout: overview-large
3+
title: Extractor Macros
4+
5+
disqus: true
6+
7+
partof: macros
8+
num: 6
9+
---
10+
<span class="label warning" style="float: right;">EXPERIMENTAL</span>
11+
12+
**Eugene Burmako**
13+
14+
Extractor macros are shipped with the recent milestone builds of Scala 2.11, starting from 2.11.0-M5, enabled by name-based extractors introduced by Paul Phillips in Scala 2.11.0-M5. Extractor macros are not available in Scala 2.10.x or in macro paradise. Follow the instructions at [http://www.scala-lang.org/download/](http://www.scala-lang.org/download/) to download and use the latest milestone of 2.11.
15+
16+
### The pattern
17+
18+
In a nutshell, given an unapply method (for simplicity, in this
19+
example the scrutinee is of a concrete type, but it's also possible
20+
to have the extractor be polymorphic, as demonstrated in the tests):
21+
22+
def unapply(x: SomeType) = ???
23+
24+
One can write a macro that generates extraction signatures for unapply
25+
on per-call basis, using the target of the calls (`c.prefix`) and the type
26+
of the scrutinee (that comes with `x`), and then communicate these signatures
27+
to the typechecker.
28+
29+
For example, here's how one can define a macro that simply passes
30+
the scrutinee back to the pattern match (for information on how to
31+
express signatures that involve multiple extractees, visit
32+
[scala/scala#2848](https://github.com/scala/scala/pull/2848)).
33+
34+
def unapply(x: SomeType) = macro impl
35+
def impl(c: Context)(x: c.Tree) = {
36+
q"""
37+
new {
38+
class Match(x: SomeType) {
39+
def isEmpty = false
40+
def get = x
41+
}
42+
def unapply(x: SomeType) = new Match(x)
43+
}.unapply($x)
44+
"""
45+
}
46+
47+
In addition to the matcher, which implements domain-specific
48+
matching logic, there's quite a bit of boilerplate here, but
49+
every part of it looks necessary to arrange a non-frustrating dialogue
50+
with the typer. Maybe something better can be done in this department,
51+
but I can't see how, without introducing modifications to the typechecker.
52+
53+
Even though the pattern uses structural types, somehow no reflective calls
54+
are being generated (as verified by `-Xlog-reflective-calls` and then
55+
by manual examination of the produced code). That's a mystery to me, but
56+
that's also good news, since that means that extractor macros aren't
57+
going to induce performance penalties.
58+
59+
Almost. Unfortunately, I couldn't turn matchers into value classes
60+
because one can't declare value classes local. Nevertheless,
61+
I'm leaving a canary in place ([neg/t5903e](https://github.com/scala/scala/blob/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/neg/t5903e/Macros_1.scala#L1)) that will let us know
62+
once this restriction is lifted.
63+
64+
### Use cases
65+
66+
In particular, the pattern can be used to implement shapeshifting
67+
pattern matchers for string interpolators without resorting to dirty
68+
tricks. For example, quasiquote unapplications can be unhardcoded now:
69+
70+
def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], ...) = {
71+
...
72+
fun.tpe match {
73+
case ExtractorType(unapply) if mode.inPatternMode =>
74+
// this hardcode in Typers.scala is no longer necessary
75+
if (unapply == QuasiquoteClass_api_unapply) macroExpandUnapply(...)
76+
else doTypedUnapply(tree, fun0, fun, args, mode, pt)
77+
}
78+
}
79+
80+
Rough implementation strategy here would involve writing an extractor
81+
macro that destructures `c.prefix`, analyzes parts of `StringContext` and
82+
then generates an appropriate matcher as outlined above.
83+
84+
Follow our test cases at [run/t5903a](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903a),
85+
[run/t5903b](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903b),
86+
[run/t5903c](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903c),
87+
[run/t5903d](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903d) to see implementations
88+
of this and other use cases for extractor macros.
89+
90+
Please note that extractor macros must be [whitebox](/overviews/macros/blackbox-whitebox.html), otherwise they will not work.

overviews/macros/implicits.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,11 @@ problem is extremely simple and elegant.
140140
In 2.10 we don't allow macro applications to expand until all their type arguments are inferred. However we don't have to do that.
141141
The typechecker can infer as much as it possibly can (e.g. in the running example `C` will be inferred to `Foo` and
142142
`L` will remain uninferred) and then stop. After that we expand the macro and then proceed with type inference using the type of the
143-
expansion to help the typechecker with previously undetermined type arguments.
143+
expansion to help the typechecker with previously undetermined type arguments. This is how it's implemented in Scala 2.11.0.
144144

145-
An illustration of this technique in action can be found in our [files/run/t5923c](https://github.com/scalamacros/kepler/tree/7b890f71ecd0d28c1a1b81b7abfe8e0c11bfeb71/test/files/run/t5923c) tests.
145+
An illustration of this technique in action can be found in our [files/run/t5923c](https://github.com/scala/scala/tree/7b890f71ecd0d28c1a1b81b7abfe8e0c11bfeb71/test/files/run/t5923c) tests.
146146
Note how simple everything is. The `materializeIso` implicit macro just takes its first type argument and uses it to produce an expansion.
147147
We don't need to make sense of the second type argument (which isn't inferred yet), we don't need to interact with type inference -
148148
everything happens automatically.
149149

150-
Please note that there is [a funny caveat](https://github.com/scalamacros/kepler/blob/7b890f71ecd0d28c1a1b81b7abfe8e0c11bfeb71/test/files/run/t5923a/Macros_1.scala)
151-
with Nothings that we plan to address later.
150+
Please note that there is [a funny caveat](https://github.com/scala/scala/blob/7b890f71ecd0d28c1a1b81b7abfe8e0c11bfeb71/test/files/run/t5923a/Macros_1.scala) with Nothings that we plan to address later. Also note that fundep materializers must be [whitebox](/overviews/macros/blackbox-whitebox.html), otherwise they will not work.

overviews/macros/paradise.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: Macro Paradise
55
disqus: true
66

77
partof: macros
8-
num: 9
8+
num: 10
99
languages: [ja]
1010
---
1111
<span class="label success" style="float: right;">NEW</span>
@@ -15,7 +15,9 @@ languages: [ja]
1515
Macro paradise is a plugin for several versions of Scala compilers.
1616
It is designed to reliably work with production releases of <code>scalac</code>,
1717
making latest macro developments available way before they end up in future versions Scala.
18-
Refer to the roadmap for [the list of supported features and versions](/overviews/macros/roadmap.html).
18+
Refer to the roadmap for [the list of supported features and versions](/overviews/macros/roadmap.html)
19+
and visit [the paradise announcement](http://scalamacros.org/news/2013/08/07/roadmap-for-macro-paradise.html)
20+
to learn more about our support guarantees.
1921

2022
~/210x $ scalac -Xplugin:paradise_*.jar -Xshow-phases
2123
phase name id description

overviews/macros/quasiquotes.md

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

77
partof: macros
8-
num: 7
8+
num: 8
99
languages: [ja]
1010
---
1111
<span class="label warning" style="float: right;">EXPERIMENTAL</span>

overviews/macros/roadmap.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ title: Roadmap
55
disqus: true
66

77
partof: macros
8-
num: 10
8+
num: 11
99
languages: [ja]
1010
---
1111

1212
<span class="label warning" style="float: right;">EXPERIMENTAL</span>
1313

1414
**Eugene Burmako**
1515

16+
Scala team is currently busy with the release of Scala 2.11.0-final, and at the moment we don't have concrete plans for Scala 2.12.
17+
Consequently, roadmaps for Scala 2.12 and Paradise 2.12 don't exist yet. We will update this page once the information becomes available.
18+
1619
| Feature | Scala 2.10 | [Paradise 2.10](/overviews/macros/paradise.html) | [Paradise 2.11](/overviews/macros/paradise.html) | Scala 2.11 |
1720
|-----------------------------------------------------------------------------------|--------------------|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------|-----------------|
1821
| [Blackbox/whitebox separation](/overviews/macros/blackbox-whitebox.html) | No | No <sup>1</sup> | Yes <sup>1</sup> | Yes |

overviews/macros/typeproviders.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: Type Providers
55
disqus: true
66

77
partof: macros
8-
num: 6
8+
num: 7
99
languages: [ja]
1010
---
1111
<span class="label warning" style="float: right;">EXPERIMENTAL</span>
@@ -84,6 +84,8 @@ it has performance problems caused by the fact that Scala emits reflective calls
8484
of structural types. There are several strategies of dealing with that, but this margin is too narrow to contain them
8585
so I refer you to an amazing blog series by Travis Brown for details: [post 1](http://meta.plasm.us/posts/2013/06/19/macro-supported-dsls-for-schema-bindings/), [post 2](http://meta.plasm.us/posts/2013/07/11/fake-type-providers-part-2/), [post 3](http://meta.plasm.us/posts/2013/07/12/vampire-methods-for-structural-types/).
8686

87+
Please note that fake type providers must be [whitebox](/overviews/macros/blackbox-whitebox.html), otherwise they will not work.
88+
8789
### Real type providers
8890

8991
With the help of [macro paradise](/overviews/macros/paradise.html) and its [macro annotations](/overviews/macros/annotations.html), it becomes

0 commit comments

Comments
 (0)