tl;dr: meta-programming in javascript is just called “programming” because the methods used are familiar and used for non-meta-programming tasks, unlike ruby which requires a large set of specialized knowledge that is only used within the task of meta-programming.

 

Background:

On the node.js mailing list, it was asked “why do we not hear about meta-programming in JavaScript?”, and the answers varied from “ruby rots people’s brains” to “People in the JS community don’t care that much about being super DRY code.” to more reasoned discourse like “JavaScript is a functional language, so you don’t really need it even if you knew what it meant.”

Finally, I would be remiss if I left out this delightful quip from Marak Squires:

I use to say, “I can bend space and time with .toString() and eval()”.

I’ve come to realize that it’s generally better to not bend space and time in JavaScript.

— Marak

As is my habit, I have a slightly more nuanced approach.

 

First things first.

Many nerd-rage-fests convolve towards a petty squabble over definitions. For now, wikipedia says:

Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data

sure, good enough for me.

In practice, rubyists are used to flavors of eval, define_method and the venerable method_missing.

 

Meta-Programming in JavaScript

I submit that we don’t talk about meta-programming in javascript because we just call it “programming” in javascript.

In ruby, there are special tools (instance_eval, class_eval, .send, define_method, &etc.) that you have to learn in order to have your code dynamically define the behavior of new objects and classes. Because of this special vocabulary that is not part of the day-to-day vernacular of the rubyist, the application of these techniques are given a special consideration and status.

In JavaScript, all you need are functions and objects for the vast majority of things that require the “meta-programming” arcana in ruby.

To make things a little more concrete: In ruby, extending an object or class by attaching behavior to an identifier (and binding that behavior to the object) is a special operation, that must be handled differently depending on how the behavior is defined and the kind of object being extended. In JavaScript, you just assign a variable to a property and you’re done. Since dot notation and [] property access work just about the same, there is no special knowledge required of the javascript programmer to write code that defines behavior.

To make things a little more abstract: most meta-programming is actually an application of currying or rebinding behavior to a different context. Currying is trivial in JavaScript, rebinding is a little tricky: assign to a property of the context or use call or apply. Since the javascript programmer frequently uses call in their day-to-day work, it is not “arcana” like Module#instance_method is within ruby-land.

 

But JavaScript doesn’t have method_missing!

Unfortunately, it may be coming in future versions. However, this is a moot point because method_missing is just dynamic dispatch. This is trivially accomplished in javascript, but it requires collusion between the caller and callee.