Vampire methods for structural types

I wish I could take credit for what I’m about to show you, because it’s easily the cleverest thing I’ve seen all week, but it’s Eugene Burmako’s trick and I’ve only simplified his demonstration a bit and adapted it to work in Scala 2.10.

First for the setup. Start your REPL like this to have it print the tree for every expression after the compiler’s cleanup phase:

It’ll print some stuff you can ignore. Hit return to get a prompt (if you want), and then copy and paste the following:

And it’ll print some more stuff you don’t need to worry about.

The makeInstance method here is pretty simple: we’re just defining a class and instantiating it (using the workaround I identified here). The inferred type of the instance will be a structural type with z and v methods.

And the punchline:

Now you can start paying attention to all that stuff it’s been printing. Here’s the important part:

This is what the trait’s constructor looks like after the cleanup phase. Notice all the ugly reflection business happening in the initialization of zombie—this is why you get warnings about reflective access when you use structural types in Scala, and why calling methods on structural types is (at least a little) slower.

Now look at the initialization for vampire. No reflection at all—the macro has just replaced myInstance.v with 42.

I missed this when Eugene first posted it on Twitter a couple of days ago—now I wish I could buy him a beer, because this totally made my Friday afternoon.