Quick link: Scalaxy/MacroExtensions on GitHub
Scala’s enrich-my-library pattern allows Scala developers to add methods (and more) to existing classes.
Scala 2.10 facilitates this pattern by providing implicit classes:
This works great, but…
- It usually implies some object creation at runtime (lightweight though it might be, expecially if the extension is a value class),
- Your extension library is a new runtime dependency (which is not such a bad thing, but it can be avoided, please read on).
The other day, Eric Christiansen rightly complained on NativeLibs4Java’s mailing list that Scalaxy/Compilets were quite constrained by the typer, and that he wished he could define extension methods more easily.
I gave that a serious thought, and came up with a compiler plugin that runs before the typer / namer and performs the following expansion:
Quite exciting syntax twisting, but overall not a huge line-saver.
Then I realized there’s another pattern that could benefit from such rewrites: macros enrichments.
A macro enrichment?
A macro enrichment just extends the “enrich-my-library” pattern by implementing the extension method using a macro. As a result, the enrichment is “inlined” at compilation time, and there’s no runtime dependency nor overhead. See my recent experiments for examples of such macro enrichments:
Scalaxy/MacroExtensions just uses the exact same syntax as above to create all the implicit class / macro wiring necessary to implement the extension as a macro:
Update(Feb 22th 2013): Updated the syntax to use @scalaxy.extend instead of @extend.
The plugin supports two kinds of body for extension methods: regular code, and macro.
- If the body looks like some regular method implementation, as above, it will wrap it in a reify call and will wrap all references to self and to the method parameters in splice calls.
- If the body is a macro implementation, it will put it verbatim in the resulting macro: