
Why don't I metaprogram more? - luu
https://github.com/davidbalbert/programming-journal/blob/master/2014-1-8-why-dont-i-metaprogram-more.markdown
======
MichaelGG
Does anyone have some really good examples of metaprogramming? I bought a book
on Ruby Metaprogramming and the examples seemed to be all about disguising a
string parameter as a member name. So for instance:

    
    
      foo.somefield
    

Versus:

    
    
      foo["somefield"]
    

And variations on that theme. While it's cute, I guess (you're not type
checking anyways so nothing lost, I suppose), I don't _really_ get it.

~~~
klibertp
Would you be happy with examples in other languages? I think using meta-
programming to add hash literals to CL is a rather good example:
[http://frank.kank.net/essays/hash.html](http://frank.kank.net/essays/hash.html)

There's a chapter in pg's "On Lisp" about continuation-passing-style
transformation (from sequential code to CPS) done with meta-programming. Worth
reading, too.

If you're an Emacs user, the source code of EIEIO is a good read. It's an
object system implemented on top of Elisp using it's meta-programming
capabilities.

In Smalltalk-land the most impressive example of meta-programming is certainly
a debugger. You get to inspect the state of objects while they are running,
you can modify it, and you can modify _method bodies_ while they are running.
Scary stuff.

In Python some nice meta-programming code lives in Django ORM, in Model
metaclass, and in Fields. This is the code which allows you to declaratively
define your models as classes. Similar code is used in Django Forms.

The talk "Five years of bad ideas" by Armin Ronacher is a 40-minuted tour of
some of the most advanced meta-programming available in Python.

In JavaScript every library which implements "classical classes" on top of
objects and prototypes uses meta-programming. You can read about it more in
depth in Raganwald "the art of javascript meta-object protocol" and his other
talks and posts.

Angular.js dependency injection framework is based on meta-programming;
actually I had a mixed reaction when I saw the code for this, where they
rewrite a user supplied function as a string and compile a new function out of
this string. It's a good example of meta-programming, but it's also very crude
compared to hygienic macros in Schemes for example. It lives here:
[https://github.com/angular/angular.js/blob/master/src/auto/i...](https://github.com/angular/angular.js/blob/master/src/auto/injector.js#L98)

Generally, meta-programming is a vast and varied set of techniques. It's worth
knowing about them, because most of the time you don't need them, but when you
do, you _really, really_ need them very much.

~~~
hyperpape
Yeah, I don't get the unity of it all, or why it's called "metaprogramming".
The examples always look like they fall into one of two categories:

1\. super-easy development of new parsers/compilers (lisp macros)

2\. shenanigans with dynamicism and first class functions.

Both of those are cool! But I can't figure out what they have to do with each
other, other than that you don't get much of that sort of thing in Java/C.

~~~
klibertp
Think about it this way: what can you do to code, with code? You can create
new code (simple macros, emitting optimized bytecode, etc.) or you can modify
existing code (self-modifying code, instrumentation (example: Quasar and
Pulsar in Java [http://blog.paralleluniverse.co/2013/05/02/quasar-
pulsar/](http://blog.paralleluniverse.co/2013/05/02/quasar-pulsar/)), etc.)
and that's about it. Exactly _how_ you go on about this varies _wildly_
depending on what tools you have at your disposal, but the unifying thing
about all of them is that you're writing code which acts on other code, for
some (rather fuzzy) definitions of "code" and "acting on".

One nice example of modifying code on the fly I just remembered is goto
decorator in Python: [http://code.activestate.com/recipes/576944-the-goto-
decorato...](http://code.activestate.com/recipes/576944-the-goto-decorator/)
As for code generation, if I recall correctly, Salt
([http://docs.saltstack.com/en/latest/](http://docs.saltstack.com/en/latest/))
uses YAML and Jinja2 to generate shell scripts. These are very different
techniques, but the thing they have in common is that they manipulate code,
which makes them both examples of meta-programming.

At least that's how I understand the term :)

------
norseboar
While the link focuses on Ruby, I think there's a more general reason (which
also explains why more languages don't support a lisp-like macro): cooperative
development.

When you're writing code in a vacuum, you can fill it with all the
metaprogramming you want. You probably have some preferred style, and your
metaprogramming will reflect that. In something like lisp, this gets taken to
the extreme -- code can look very different from what traditional lisp looks
like when there are macros involved.

While this is great for developing solo, or with a small group, it becomes too
much to handle as more people onboard. Every new contributor needs to learn
your particular style, and how your macros work, and then how to apply them
effectively. Its much easier when new functionality and expressiveness is
added through a common format (like adding a new method).

As a lisp fan, those methods feel clumsy to me. But if you want to do
something that's so big you need more contributors, it's worth the tradeoff.

------
endlessvoid94
It's hard to imagine what real lisp-like macros look like with other, non-
homoiconic langauges. Anyone have an example?

~~~
tel
Haskell's "Template Haskell" system is pretty sophisticated... And challenging
enough to be some deep black magic.

You end up being able to reify the entire Haskell syntax tree from "quoted"
fragments, manipulate and generate a modified tree, and then "print" it back
into program flow.

Totally capable, but not terrifically fun. It also has some compilation
restrictions which are annoying if necessary.

~~~
dllthomas
I just (last night) dug into some TH hackery. I put together a quasiquoter for
testing/debugging that would walk a do block and decorate every statement with
(`onException` ...) set up to print the source location when an exception is
thrown. I actually had to first parse with haskell-src-exts to get the
location info, and currently I'm turning it into an ExpQ by pretty-printing
and reparsing - which I don't love, but gets the job done.

[https://github.com/dlthomas/snowdrift/compare/5094b1ca0e5002...](https://github.com/dlthomas/snowdrift/compare/5094b1ca0e5002c0d12a7f714b083d88d450ddb3...e7bf8ac8b6320fcc46233248170920fc97d805c9)

------
CmonDev
Does it really matter in a dynamic scripting language? When using reflection
in a strong programming language there is a chance it will fail at runtime
instead of being checked at compile time. Ruby only fails at runtime, so as
long as the code is shorter it should not be a much bigger problem than it
already is.

------
teh_klev
Unless I'm building a framework, should I really care?

I'm a "mort" line of business apps dev (well not just that, I do lots of other
things, but hey). Do I really need to care about metaprogramming, my gut
instinct says no because our business and customer requirements change all the
time, and unpredictably. And if I was spending time thinking about "meta
programming", nothing would get done.

~~~
jfabre
No offense, but I think your comment is a bit short-sighted. Meta-programming
is just another tool in your tool-belt. It's not going to take you 6 months of
practice to "get it".

~~~
bulte-rs
I don't disagree with you, but some people might actually have problems
'understanding' metaprogramming; the same way some people have difficulties
understanding pointers, or working through TAoCP/SICP/HTDP.

Problem is, once you get it; it's unfathomable that you might not understand
it.

------
pconner
The title is misleading. By itself, it seems to imply that the author has
something against the practice of metaprogramming in general, rather than just
Ruby metaprogramming.

~~~
infraruby
You can do metaprogramming in Ruby without using the reflection features of
the language:

[http://infraruby.com/blog/ruby-metaprogramming-with-s-
expres...](http://infraruby.com/blog/ruby-metaprogramming-with-s-expressions)

[http://infraruby.com/blog/the-structure-of-s-
expressions](http://infraruby.com/blog/the-structure-of-s-expressions)

[http://infraruby.com/blog/generating-an-html-
generator](http://infraruby.com/blog/generating-an-html-generator)

