background preloader

Metaprogramming

Facebook Twitter

D

Metaclasses. Metaprogramming: Ruby vs. Javascript. Invocation Construction Kit. Ruby Metaprogramming Simplified. For an upcoming post, I needed to get my hands on Ruby’s metaprogramming capabilities. As always, I had a hard time to get the semantics and the syntax involved right. So, this time I decided to come up with my own approach to ease unleash the power of Ruby’s metaprogramming. Simply derived from the fact that there is a variety of tutorial alike articles on metaprogramming in Ruby leads me to the conclusion that this matter is not easy to grasp. Partly due to the fact what metaprogramming is all about and partly due to the syntax and semantics involved. Metaprogramming, as defined by Wikipedia, is Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) [...] Some languages allow metaprogramming techniques to be applied at compile time, for example C++. Simplified Introduction In Ruby the behavior of individual objects or the entire population of objects (i.e the associated class) can be changed.

To make my point clear, here’s an example. Metaprogramming in Ruby: It’s All About the Self. November 15th, 2009 After writing my last post on Rails plugin idioms, I realized that Ruby metaprogramming, at its core, is actually quite simple. It comes down to the fact that all Ruby code is executed code–there is no separate compile or runtime phase. In Ruby, every line of code is executed against a particular self. Consider the following five snippets: All five of these snippets define a Person.species that returns Homo Sapien. These snippets all define a method called name on the Person class. First, it is important to understand how Ruby’s metaclass works. Person is an instance of Class, so any methods added to Class are available on Person as well. What’s going on here is that we’re adding the speak method to matz‘s metaclass, and the matz object inherits from its metaclass and then Object.

In fact, matz‘s “class” is its invisible metaclass. It turns out that all of these weird rules collapse down into a single concept: control over the self in a given part of the code. Explaining meta-programming by analogy. Functional programming is easy for programmers to understand: it is, after all, a subset of imperative (normal) programming.

It is also easy to understand the benefits of functional programming. But try to explain why meta-programming is great — or even what it is, and eyes glaze over and the idea does not stick. I'm going to make an attempt to explain it with the help of a tasty analogy here. First off, by meta-programming I mean writing a program to generate (part of) another program. In the Ruby world, some people use the term for introspection or meddling with the object system. That is not what I am talking about. Let's compare programming to having a meal. This brings out the benefits and downsides of functional programming (programming without side-effects). In cases where there are multiple implementations of a program for a similar task: for example compilers, image processors or database systems, the best are written in a non-functional style in languages like C or C++.

EVAL-STRING OR EVAL? ; The problem that could be solved using metaprogramming ; techniques was discussed today on Newlisp forum. Programmer ; newdep proposed integration of unary predicates (the ; functions accepting only one argument and returning true or ; false) and "if" primitive. Instead of, for example, printing ; ; (if (integer? X) (print "integer! ") (print "isn't integer")) ; ; newdep thought about following: ; ; (if-integer x (print "integer!) (print "isn't integer")) ; ; In further discussion it was noted that such macro would be ; smarter, but less general.

(define-macro (if-integer) (if (integer? ; We'll first define helper function - almost the metapredicate: ; predicate predicate? (define (predicate? ; Now we should loop through all predicates and do what cormullion ; done for integer. (dolist(i (symbols)) (when (predicate? ; Then using s-expressions and eval (dolist(i (symbols)) (when (predicate? Hash_initializer() Earlier this week I was doing a code review for a candidate for ThoughtWorks. One of the bits I ran across was an object constructor that looked something like this: class MyClass def initialize(name, price, is_cool, is_neato, is_rad) @name = name # et cetera endend Not so bad, really, when you're looking right at the signature for the constructor. But when it's called from another file... MyClass.new("bob", "1.00", true, false, true)MyClass.new("fred", "2.00", false, true, true)# et cetera ... the purpose of the first two parameters may be easy to infer, but the last three?

Which order were those descriptors in anyway? Class MyClass def initialize(args) args ||= {} # in case MyClass#new is called without any args @name = args[:name] || "" # et cetera endend This frees things up a bit, and allows for parameters to be specified in any order, with reasonable defaults for any that might be left out. 1. module ClassExtension 2. 3. if !

And instantiating a MyClass stays what you would expect: Template Metaprogramming Made Easy (Huh?) “I’ve been doing some template metaprogramming lately,” he said nonchallantly. Why is it funny? Because template metaprogramming is considered really hard. I mean, über-guru-level hard. I’m lucky to be friends with two such gurus, Andrei Alexandrescu who wrote the seminal “Modern C++ Programming,” and Eric Niebler, who implemented the Xpressive library for Boost; so I know the horrors. But why is template metaprogramming so hard? So, I’ve been doing some template metaprogramming lately… in D. It’s not your father’s language The key to understanding metaprogramming is to realize that it’s done in a different language than the rest of your program. Frankly, I don’t know why mutation should be disallowed at compile time (all template calculations are done at compile time). Once you disallow mutation, you’re pretty much stuck with functional paradigm.

You’d think functional programmers would love template metaprogramming; except that they flip over horrendous syntax of C++ templates. -Lists. Why? Language Archaeology ... and Metaprogramming. Computing ThoughtsWhy? Language Archaeology ... and Metaprogrammingby Bruce EckelJune 16, 2009 Summary I showed up at the organizational meeting for the ANSI/ISO C++ standards committee because Bjarne Stroustrup asked me to. I knew him from my early C++ work and from conferences, and I suspect he considered me a friendly influence. I had no intention of committing to the time, money and travel necessary to meet three times a year, for a week each time, but the organizational meeting was in Washington DC and I was living in Pennsylvania at the time so I thought "what the heck, I'll drive a few hours and check it out.

" Note: My keynote at the upcoming EuroPython conference, June 30-July 2 in Birmingham, UK will be on language archaeology. What I found at the C++ committee meeting were most of the smartest people in the C++ community, gathered together in one place, available to answer my questions. I was hooked, and kept attending for about 8 years. Here's an example: object creation. The Core of the Evaluator. Next: Representing Expressions Up: The Metacircular Evaluator Previous: The Metacircular Evaluator The evaluation process can be described as the interplay between two procedures: eval and apply. Eval Eval takes as arguments an expression and an environment. It classifies the expression and directs its evaluation. Eval is structured as a case analysis of the syntactic type of the expression to be evaluated. In order to keep the procedure general, we express the determination of the type of an expression abstractly, making no commitment to any particular representation for the various types of expressions.

Primitive expressions For self-evaluating expressions, such as numbers, eval returns the expression itself. Eval must look up variables in the environment to find their values. Special forms For quoted expressions, eval returns the expression that was quoted. A begin expression requires evaluating its sequence of expressions in the order in which they appear. Combinations Apply Conditionals. Metaprogramming still needs programming discipline. This post will be a little bit more technical than previous posts, but I’ll try to keep it comprehensible to those who don’t already know what I’m talking about.

Now meta-programming is a very important idea, and I would go so far as to say that everyone who is at all serious about programming should learn about and understand meta-programming, even if only at a basic level. Meta-programming is often considered an advanced topic, and there certainly are advanced forms of it and advanced ideas that fall under its domain, but I think that anyone who is smart enough to program at all is smart enough to understand and perform basic meta-programming. Now, since meta-programming is very important, has deep things to say about computation, and is intellectually stimulating, many people find it very exciting and even beautiful.

I will confess: I am one of those people. Take DRY for example. The reason for this is simple. Truth in Metaprogramming. The Ruby Object Model - Structure and Semantics. 2009-03-03 As part of my compiler project, one of my imminent decisions is what object model to use, and sine I like Ruby it seemed a good time to go through Ruby and look at the guts of the Ruby object model. If you've dabbled in meta-programming etc. for Ruby this post probably doesn't contain much new stuff for you.

If you're a beginner you may want to look at a tutorial instead. If you're somewhere in between, hopefully there may be some insights here and there - especially if you're interested specifically in how things work "under the hood" rather than just what is visible to Ruby. The information in this post is based largely on the Ruby 1.8.x interpreter (you'll see it referred to as MRI as well - Matz Ruby interpreter - to distinguish it from other Ruby implementations), and we'll look at code fragments, as well as a diagram or two to illustrate.

Suggested reading The Ruby object model can make you go insane. Ruby Objects Conceptually, Ruby objects consists of the following: Send #! Joose 2.0 released. Tuesday, February 3rd, 2009 Class ( "Point" , { has: { methods: { clear: function ( ) { this . x = 0 ; this . setY ( 0 ) ; Malte Ubl and the Joose folk are always pushing the boundaries on munging JavaScript to their whim. Support for types and type coercions in attributes and method signatures: JavaScript purists might find this a little disturbing but Joose now supports type declaration.

Here is the documentation. Builtin support for turning a class into a singleton Class ( "MySingleton" , { does: [ Joose. Test: { init: function ( ) { return [ ] } var single = MySingleton. getInstance ( ) ; Support for Rhino without need for special configuration The default namespace for types (which used to be experimental) is now Joose.Type Experimental support for multi method dispatch. Made integrating Joose with other class builders easier. Fixed type checks for arrays (thanks Silvan). Fixed an issue when overriding getters and setters defined in a super class. Joose-js - Google Code. Ziggurat. Writing Domain Specific Languages. I received an email from Erik Kastner recently, in which he asked me, “How do you get to the point where you are writing Domain Specific Languages?” I had never really thought critically about the process of writing a DSL. It’s like, if someone were to ask you, “how do you get to the point where you are programming computers?”

For me, at least, it was something I just gradually started playing with, a little at a time. I certainly don’t consider myself an expert on the topic, but what follows are some of my thoughts regarding DSL creation. On the technical end, the trick to writing DSL’s in Ruby is really knowing what you can and can’t do with Ruby’s metaprogramming features. For instance, how would you: write a method that works just like attr_reader? The fascinating thing is that, in my experience, most well-written Ruby programs are already a DSL, just by nature of Ruby’s syntax. As with any interface, GUI or otherwise, mockups are critical in the design phase. Instantiation. Symbols. Metaprogramming from the ground up: avoid C. Long ago, assembly languages were endowed with expressive macroprocessing facilities. But it still sucked to write in non-portable languages with incompatible proprietary such metalanguages.

And thus, I wanted to metaprogram in something reasonably portable, which at the time pretty much meant C. The first obvious choice was to look at what the standard C pre-processor, CPP offered. So as to prevent people from shooting themselves in the foot, the language designers made sure the macro expansion algorithm would terminate, by disabling recursion on already-expanded tokens in expressions where the token was already processed.

Some people, notably hbaker, thought of using #include as a recursion mechanism. Unhappily, this isn't enough, because you cannot store infinite state in a CPP program: there is a finite number of variable-setting clauses in a program, each to a fixed variable known at compile-time, which leads to a finite number of variables usable in tests. Eavesdropping on Expressions. Update: Slightly more complete examples. I found a nice little technique for debugging Ruby code today. Ever had a situation where you wanted to insert some debugging code in the middle of an expression? The usual way is to break up the expression and use intermediate variables to get at the value, but it turns out that’s really not necessary in Ruby.

Check this out: class Object def tap yield self self end end Then, you can insert your debugging tap just about anywhere without disturbing the flow of data. First, let’s look a “pipeline” of sorts. blah.sort.grep( /foo/ ).map { |x| x.blah } Let’s imagine that there’s a bug here somewhere — we’ve verified that x.blah does the right thing, but the values coming from upstream are suspect. Xs = blah.sort.grep( /foo/ ) p xs # do whatever we had been doing with the original expression xs.map { |x| x.blah } With Object#tap, this becomes much easier — you can just slip it in without radically modifying the code: ( k + 1 ) / ( ( q - t ) / 2 ) Metaclasses in Python 3.0 [1 of 2] The ExplorerMetaclasses in Python 3.0 [1 of 2]by Michele SimionatoAugust 9, 2008 Summary This is the English translation of an article I wrote some time ago for Stacktrace: For convenience, I have split it in two posts. I heard for the first time the word "metaclass" in 2002, when I begun studying Python.

I was very active in the Python newsgroup then, and I received from David Mertz an invitation to write a joint paper about metaclasses. That was my very first paper outside Physics and since then I have had a particular affection for the subject. At the time the topic was hot since the metaclass mechanism had been just reformed (that was around the time Python 2.2 came along).

Nowadays the subject is still hot since with Python 3.0 coming in October we will have another reform of the metaclass mechanism. The reform is for the better. A metaclass is nothing else than a subclass of the builtin metaclass type: Python isn't just Java without the compile. Metaprogramming Roundup: Speed, Ruby Macros, Screencasts. Domain Specific Languages in Erlang. C preprocessor bignums. Python’s Enhanced Generators. Using Metaprogramming for a RPG Battle Engine. Generative Programming. Meta-Programming with Scala Part I: Addition. Python Metaprogramming. Pegtl. Anonymous Code Blocks in Python. A Tutorial on Behavioral Reflection and its Implementation. C++: How to create variable length arrays on the stack. Meta-level thinking.