From 79a93984737c2bf925e4162b215e874fb0c8820b Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 22 Feb 2014 15:24:40 +0100 Subject: [PATCH 1/3] support guarantees for paradise --- overviews/macros/paradise.md | 4 +++- overviews/macros/roadmap.md | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/overviews/macros/paradise.md b/overviews/macros/paradise.md index 3db590a88a..14fd363dd8 100644 --- a/overviews/macros/paradise.md +++ b/overviews/macros/paradise.md @@ -15,7 +15,9 @@ languages: [ja] Macro paradise is a plugin for several versions of Scala compilers. It is designed to reliably work with production releases of scalac, making latest macro developments available way before they end up in future versions Scala. -Refer to the roadmap for [the list of supported features and versions](/overviews/macros/roadmap.html). +Refer to the roadmap for [the list of supported features and versions](/overviews/macros/roadmap.html) +and visit [the paradise announcement](http://scalamacros.org/news/2013/08/07/roadmap-for-macro-paradise.html) +to learn more about our support guarantees. ~/210x $ scalac -Xplugin:paradise_*.jar -Xshow-phases phase name id description diff --git a/overviews/macros/roadmap.md b/overviews/macros/roadmap.md index 224eae4367..2c98ae3a05 100644 --- a/overviews/macros/roadmap.md +++ b/overviews/macros/roadmap.md @@ -13,6 +13,9 @@ languages: [ja] **Eugene Burmako** +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. +Consequently, roadmaps for Scala 2.12 and Paradise 2.12 don't exist yet. We will update this page once the information becomes available. + | Feature | Scala 2.10 | [Paradise 2.10](/overviews/macros/paradise.html) | [Paradise 2.11](/overviews/macros/paradise.html) | Scala 2.11 | |-----------------------------------------------------------------------------------|--------------------|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------|-----------------| | [Blackbox/whitebox separation](/overviews/macros/blackbox-whitebox.html) | No | No 1 | Yes 1 | Yes | From 3535079e00c4d5d131adf2e60b3af6e9a921b9f1 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 22 Feb 2014 15:39:58 +0100 Subject: [PATCH 2/3] initial docs on extractor macros --- overviews/macros/annotations.md | 4 +- overviews/macros/extractors.md | 88 +++++++++++++++++++++++++++++++ overviews/macros/paradise.md | 2 +- overviews/macros/quasiquotes.md | 2 +- overviews/macros/roadmap.md | 2 +- overviews/macros/typeproviders.md | 2 +- 6 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 overviews/macros/extractors.md diff --git a/overviews/macros/annotations.md b/overviews/macros/annotations.md index d5f297df06..fa87c75e85 100644 --- a/overviews/macros/annotations.md +++ b/overviews/macros/annotations.md @@ -5,8 +5,8 @@ title: Macro Annotations disqus: true partof: macros -num: 8 -outof: 10 +num: 9 +outof: 11 languages: [ja] --- MACRO PARADISE diff --git a/overviews/macros/extractors.md b/overviews/macros/extractors.md new file mode 100644 index 0000000000..b0c825cdbc --- /dev/null +++ b/overviews/macros/extractors.md @@ -0,0 +1,88 @@ +--- +layout: overview-large +title: Extractor Macros + +disqus: true + +partof: macros +num: 6 +--- +EXPERIMENTAL + +**Eugene Burmako** + +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. + +### The pattern + +In a nutshell, given an unapply method (for simplicity, in this +example the scrutinee is of a concrete type, but it's also possible +to have the extractor be polymorphic, as demonstrated in the tests): + + def unapply(x: SomeType) = ??? + +One can write a macro that generates extraction signatures for unapply +on per-call basis, using the target of the calls (`c.prefix`) and the type +of the scrutinee (that comes with `x`), and then communicate these signatures +to the typechecker. + +For example, here's how one can define a macro that simply passes +the scrutinee back to the pattern match (for information on how to +express signatures that involve multiple extractees, visit +[scala/scala#2848](https://github.com/scala/scala/pull/2848)). + + def unapply(x: SomeType) = macro impl + def impl(c: Context)(x: c.Tree) = { + q""" + new { + class Match(x: SomeType) { + def isEmpty = false + def get = x + } + def unapply(x: SomeType) = new Match(x) + }.unapply($x) + """ + } + +In addition to the matcher, which implements domain-specific +matching logic, there's quite a bit of boilerplate here, but +every part of it looks necessary to arrange a non-frustrating dialogue +with the typer. Maybe something better can be done in this department, +but I can't see how, without introducing modifications to the typechecker. + +Even though the pattern uses structural types, somehow no reflective calls +are being generated (as verified by `-Xlog-reflective-calls` and then +by manual examination of the produced code). That's a mystery to me, but +that's also good news, since that means that extractor macros aren't +going to induce performance penalties. + +Almost. Unfortunately, I couldn't turn matchers into value classes +because one can't declare value classes local. Nevertheless, +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 +once this restriction is lifted. + +### Use cases + +In particular, the pattern can be used to implement shapeshifting +pattern matchers for string interpolators without resorting to dirty +tricks. For example, quasiquote unapplications can be unhardcoded now: + + def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], ...) = { + ... + fun.tpe match { + case ExtractorType(unapply) if mode.inPatternMode => + // this hardcode in Typers.scala is no longer necessary + if (unapply == QuasiquoteClass_api_unapply) macroExpandUnapply(...) + else doTypedUnapply(tree, fun0, fun, args, mode, pt) + } + } + +Rough implementation strategy here would involve writing an extractor +macro that destructures `c.prefix`, analyzes parts of `StringContext` and +then generates an appropriate matcher as outlined above. + +Follow our test cases at [run/t5903a](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903a), +[run/t5903b](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903b), +[run/t5903c](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903c), +[run/t5903d](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903d) to see implementations +of this and other use cases for extractor macros. diff --git a/overviews/macros/paradise.md b/overviews/macros/paradise.md index 14fd363dd8..d1417a2412 100644 --- a/overviews/macros/paradise.md +++ b/overviews/macros/paradise.md @@ -5,7 +5,7 @@ title: Macro Paradise disqus: true partof: macros -num: 9 +num: 10 languages: [ja] --- NEW diff --git a/overviews/macros/quasiquotes.md b/overviews/macros/quasiquotes.md index 3989184156..91e60bd4c8 100644 --- a/overviews/macros/quasiquotes.md +++ b/overviews/macros/quasiquotes.md @@ -5,7 +5,7 @@ title: Quasiquotes disqus: true partof: macros -num: 7 +num: 8 languages: [ja] --- EXPERIMENTAL diff --git a/overviews/macros/roadmap.md b/overviews/macros/roadmap.md index 2c98ae3a05..f68e274b3f 100644 --- a/overviews/macros/roadmap.md +++ b/overviews/macros/roadmap.md @@ -5,7 +5,7 @@ title: Roadmap disqus: true partof: macros -num: 10 +num: 11 languages: [ja] --- diff --git a/overviews/macros/typeproviders.md b/overviews/macros/typeproviders.md index d21ac141cb..d12fcd8dd2 100644 --- a/overviews/macros/typeproviders.md +++ b/overviews/macros/typeproviders.md @@ -5,7 +5,7 @@ title: Type Providers disqus: true partof: macros -num: 6 +num: 7 languages: [ja] --- EXPERIMENTAL From 13bd588d574a1d8244ea3551f0db844b8a1e7786 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 22 Feb 2014 15:42:51 +0100 Subject: [PATCH 3/3] mentions macros that must necessarily be whitebox --- overviews/macros/extractors.md | 2 ++ overviews/macros/implicits.md | 7 +++---- overviews/macros/typeproviders.md | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/overviews/macros/extractors.md b/overviews/macros/extractors.md index b0c825cdbc..a8e2cfa2d0 100644 --- a/overviews/macros/extractors.md +++ b/overviews/macros/extractors.md @@ -86,3 +86,5 @@ Follow our test cases at [run/t5903a](https://github.com/scala/scala/tree/00624a [run/t5903c](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903c), [run/t5903d](https://github.com/scala/scala/tree/00624a39ed84c3fd245dd9df7454d4cec4399e13/test/files/run/t5903d) to see implementations of this and other use cases for extractor macros. + +Please note that extractor macros must be [whitebox](/overviews/macros/blackbox-whitebox.html), otherwise they will not work. diff --git a/overviews/macros/implicits.md b/overviews/macros/implicits.md index 401ffab3f1..69df91740f 100644 --- a/overviews/macros/implicits.md +++ b/overviews/macros/implicits.md @@ -140,12 +140,11 @@ problem is extremely simple and elegant. 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. The typechecker can infer as much as it possibly can (e.g. in the running example `C` will be inferred to `Foo` and `L` will remain uninferred) and then stop. After that we expand the macro and then proceed with type inference using the type of the -expansion to help the typechecker with previously undetermined type arguments. +expansion to help the typechecker with previously undetermined type arguments. This is how it's implemented in Scala 2.11.0. -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. +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. Note how simple everything is. The `materializeIso` implicit macro just takes its first type argument and uses it to produce an expansion. 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 - everything happens automatically. -Please note that there is [a funny caveat](https://github.com/scalamacros/kepler/blob/7b890f71ecd0d28c1a1b81b7abfe8e0c11bfeb71/test/files/run/t5923a/Macros_1.scala) -with Nothings that we plan to address later. +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. diff --git a/overviews/macros/typeproviders.md b/overviews/macros/typeproviders.md index d12fcd8dd2..00db1bf705 100644 --- a/overviews/macros/typeproviders.md +++ b/overviews/macros/typeproviders.md @@ -84,6 +84,8 @@ it has performance problems caused by the fact that Scala emits reflective calls of structural types. There are several strategies of dealing with that, but this margin is too narrow to contain them 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/). +Please note that fake type providers must be [whitebox](/overviews/macros/blackbox-whitebox.html), otherwise they will not work. + ### Real type providers With the help of [macro paradise](/overviews/macros/paradise.html) and its [macro annotations](/overviews/macros/annotations.html), it becomes