Code Generation is not Metaprogramming

by chromatic

I know Piers Cawley hates the word "metaprogramming" as much as I hate any of my pet peeves, but Tomasz Węgrzanowski just made a fantastic point:

Every use of text-based runtime code generation is a failure of language's reflection model.

(See Ruby and methods with weird names.)

Language--and library--designers should keep this principle in mind. One of the explicit design goals of Perl 6 is to enable all of the metaprogramming of Perl 5 without exposing as much of the machinery. (For some reason, assignment to dynamically-scoped typeglobs frightened people.)


3 Comments

Piers Cawley
2007-06-06 23:44:49
I don't like metaprogramming, but I *love* metaquoting.


Guess what ruby doesn't have. Or Perl 5 for that matter (though it's still mind boggling how far you can get in Perl 5 before you have to pull out the eval STRING). For a lot of code generation in ruby, you're stuck with only being able to interpolate datastructures whose 'inspect' method returns code to make an equivalent object - if you want to generate code that's going to manipulate an existing datastructure in place, you're screwed. If you want to use anything but the most anaemic of objects in such code, you're screwed. If you want to use closures to generate a method that can take a block, guess what?


Despite all that, it's a lovely language, and at least one of the issues (using closures to build a method that takes a block) is apparently due to be fixed in 1.9, and that will relieve a great deal of the pain.


It'll do 'til Six

Daniel Berger
2007-06-07 10:14:26
A Lisp programmer pining away for macros? Shocking. Truly.


Not gonna happen. Matz has said so more than once.


I'm not saying Ruby couldn't be improved in this area (and it is in 1.9), but basically it sounds like his primary gripe is that Ruby isn't Lisp. And the Delegator module probably does suck.

taw
2007-06-08 22:07:28
Daniel Berger: Macros aren't really needed here - if Ruby got it right methods could be added by define_method + a closure:


define_method(meth){|*args, &blk| __getobj__.send(meth, *args, &blk) }


The problem is that methods defined in such way behave differently from regular def-defined methods, and there's no way to get around this short of evaling a def-definition. As far as I know Ruby 1.9 only partially fixes that. Ruby contains many such small holes in the reflection model - some things are possibly to do by normal "metaprogramming", others need string evaling, and some cannot even be done in Ruby and must be coded in C (like support for Foo#=~/regexp/ for own classes).