- About Scala
- In the Enterprise
- Scala Community
- Language Research
- In the Press
- The Scala Team
- Scala's Prehistory
- Contact Us
- Learning Scala
- Tour of Scala
- Scala API
- Setup & Getting Started
- Programming Guides
- Other Guides
- Code Examples
- Scala Developers
scala-macros vs scala-virtualized
I am far from a Scala expert and I could be wrong, but to my naive eyes
it looks like two large projects are entering Scala which both
accomplish pretty much the same thing (or at least overlap to a very
scala-macros and scala-virtualized
They are both mechanisms that allow you to write normal-looking Scala
code which does something else in the background, like generating SQL
queries and what not. In other words, both scala-macros and
scala-virtualized are mechanisms for creating domain specific languages
Having two distinct and complex mechanisms for doing essentially the
same thing seems wasteful and redundant. Not to mention the possible
unintended interactions between two such complex features.
Now, if you accept that the two mechanisms are somewhat redundant (which
you might disagree with of course), the question turns to which one is
better for Scala programmers...
1) Scala-virtualized is much more in the spirit of Scala
Even before scala-virtualized you could implement e.g. flatMap() in your
classes and have them participate in Scala's for/yield protocol, or you
could override various operators and such. Using methods to override
behavior of Scala's builtin constructs is nothing new. Scala-virtualized
merely expands that existing precedent to all language constructs and
brings it to its logical conclusion.
On the other hand, Scala had nothing like scala-macros before. It's a
completely new concept and somewhat alien in the Scala context. I've
used macros in Lisp to great effect, but Lisp is a language that is very
amenable to macros because Lisp code and data look the same. Scala code
and data look nothing alike, which brings me to the second point...
2) Scala-virtualized is much more intuitive to use for the library writer
With scala-virtualized you write your DSL implementations in
straightforward Scala code, similar to how you would write e.g. implicit
conversions to pimp a library or things of that nature.
With scala-macros you are forced to write this weird AST meta-language
that looks nothing like normal Scala code. It's almost like having to
learn another language on top of Scala.
3) How do you even debug scala-macros?
In scala-virtualized the overridden behavior sits in normal methods that
a debugger could interactively step through at run time, whenever you
hit an overridden construct as you step through your DSL.
With scala-macros, the code inside the macro is executed in some
precompilation phase before the code runs. When you actually run the
program it's no longer the macro code that gets executed, it's the
*result* produced by the AST manipulations in the macro code. So when
stepping interactively with a debugger you can't really step through the
original macro code that generated the code you are currently running.
This makes finding bugs in the macros much more difficult as your macro
4) Scala-macros might be more powerful
Not to be completely one-sided, I will concede that scala-macros might
be strictly more powerful than scala-virtualized. I have no formal proof
of this, but it sounds like rewriting/generating ASTs from scala-macros
might enable some crazy things that might not be possible (or easy) in
scala-virtualized. But are these corner cases where scala-macros is more
powerful than scala-virtualized really something that you would often
use in practice?
In summary, compared to scala-virtualized, scala-macros look like a
low-level hackish solution in search of a problem. They are complex to
write, un-scalaish, difficult to debug, and will probably just add to
Scala's image of "too much complex inscrutable magic".
Finally, my question to the Scala Community is:
What *practical* problems can you solve with scala-macros that you
couldn't solve just as easily with scala-virtualized?