Like many koans, I'm afraid it probably only makes sense to someone who already knows; I suspect it's completely meaningless to someone who hasn't already had a chunk of direct experience.
To fix that it probably only needs one or two really good examples, though. I find the lack of examples to be the most common cause of misunderstanding. The reason the experienced person understands is because they have their own examples already.
I hope that's not true. A koan's job is to thwart understanding. This concept, on the other hand, is simple and beautiful and it ought to be possible to explain it — though perhaps not without a few well-chosen examples. (Edit: kaizen-konpusai beat me to it on the latter.) For fun, I took the liberty of revising your aphorism (don't be mad. I mean it as a tribute ;)) and adding one explanatory bit. Do you think anything has been lost?
Metaprogramming involves three things: the code as text, the code as program, and the code as data.
The text (often called the source code) is what programmers read and write. The program is what the code does. The data is how the code is represented to other programs.
A good language for metaprogramming requires two things: the program must be easily expressible as data, and the text must clearly evoke both the program and the data in the mind of the coder.
...but, AFAIK, a Koan tries to thwart understanding in order to communicate an otherwise impossible to describe concept. By preventing understanding yet asking for investigation, a koan communicates its actual content through your investigation, rather than the successful translation of the words into your thoughts.
Yes, that's more or less how I think of koans too. (There's also the fact that in the tradition that originated them, koans were given in the context of a personal relationship between teacher and student. We missed that when we turned them into intellectual gimmicks.)
But the point is that this metaprogramming business is not impossible to describe.
I'm not sure how representative I am, but as someone who doesn't really understand what meta-programming is about, my impression is that it's a combination of nonsensical comparisons (e.g. I don't understand the difference between text and data) and vacuous truths.
I suspect this is a reflection on me more than the koan, but I also think my reaction would probably not be uncommon among the unenlightened.
To give an actual answer: What's meant by "data" is a richer structure than mere text. For example, an expression tree that can be manipulated by recursive procedures to form a new expression tree.
There's an ambiguity in that definition: what does "represented" mean? It can mean "represented as source code", i.e. for consumption by the programmer, or it can mean "represented as runtime state", i.e. for consumption by the machine. The first is what the OP means by code-as-text and the second is what the OP means by code-as-data.
A program always has both kinds of representation. Without a textual representation, no one could write or read it. Without a runtime representation, it couldn't be executed. But usually it is complicated to translate between the two. In Lisp (the classic homoiconic language), these representations are so similar that it is trivial to translate from one to the other and back again. That's what makes Lisp good for metaprogramming (writing programs that manipulate other programs): it's so easy to go back and forth between the human-friendly representation (source code) and the runtime representation (data) that a whole class of new techniques arises.
What's "code-as-procedure" supposed to be? Denotation?
And how could "code-as-procedure" fail to be easy to express using "code-as-data"?
Isn't it more essential that "code-as-data" should be easy to express in "code-as-text"? (As that's where languages like Lisp and ML, that have quasiquotation, excel).
Someone yell at me if I am wrong (self taught - with all the ups and downs implied), but to me these are not good names. A few points on this:
* 'code-as' is a bit of a strange statement as it implies two-steps from an original object - as you are taking something encoded ('code') and translating it to something else ('as').
* 'code-as-text' should be 'code-as-representation' at least (you needn't represent anything as text if you dont want to - it could be coloured geometric shapes...)
* I don't understand what 'code-as-procedure' means either. Is this an abstract-syntax-tree or just platform-executable-code?
* 'code-as-data' is meaningless because everything is data, both the text and procedure... Does the OP mean something platform-executable? Or something within a type system?
Let me try to explain it using a bit more consistent terms. Code models the behaviour of a system, let's replace all instances of 'code-as' with 'behaviour-as' to avoid confusion. So we reason about the language in which a behaviour model is expressed.
'behaviour-as-text' is the serialization of the behaviour model according to the grammar of the language.
'behaviour-as-data' is the model representation as it is viewed and modified in the model.
'behaviour-as-procedure' is the meaning of the model in the sense of execution. The semantics of the model.
So this text says that the semantics of the behaviour model need to be easily expressed as data, and the textual representation of the model must clearly show both its semantics and its data representation.
So the freaky thing about metaprogramming is that the model changes itself right? The aphorism in three simple sentences:
1 "data must express procedure"
2 "text must express procedure"
3 "text must express data"
This shows that text both directly expresses procedure by rule 2, and indirectly by rule 1 via rule 3. This indirection step allows recursion to take place (i.e. the data contains a model in the same language as it is defined in) that is used for the model to reason about itself.
15 comments
[ 2.5 ms ] story [ 41.8 ms ] threadMetaprogramming involves three things: the code as text, the code as program, and the code as data.
The text (often called the source code) is what programmers read and write. The program is what the code does. The data is how the code is represented to other programs.
A good language for metaprogramming requires two things: the program must be easily expressible as data, and the text must clearly evoke both the program and the data in the mind of the coder.
...but, AFAIK, a Koan tries to thwart understanding in order to communicate an otherwise impossible to describe concept. By preventing understanding yet asking for investigation, a koan communicates its actual content through your investigation, rather than the successful translation of the words into your thoughts.
But the point is that this metaprogramming business is not impossible to describe.
I suspect this is a reflection on me more than the koan, but I also think my reaction would probably not be uncommon among the unenlightened.
> Metaprogramming is the language feature that helps you write code that you won't be able to understand once the cocaine wears off.
From: http://c2.com/cgi/wiki?HomoiconicLanguages
I didn't.
A program always has both kinds of representation. Without a textual representation, no one could write or read it. Without a runtime representation, it couldn't be executed. But usually it is complicated to translate between the two. In Lisp (the classic homoiconic language), these representations are so similar that it is trivial to translate from one to the other and back again. That's what makes Lisp good for metaprogramming (writing programs that manipulate other programs): it's so easy to go back and forth between the human-friendly representation (source code) and the runtime representation (data) that a whole class of new techniques arises.
And how could "code-as-procedure" fail to be easy to express using "code-as-data"?
Isn't it more essential that "code-as-data" should be easy to express in "code-as-text"? (As that's where languages like Lisp and ML, that have quasiquotation, excel).
* 'code-as' is a bit of a strange statement as it implies two-steps from an original object - as you are taking something encoded ('code') and translating it to something else ('as').
* 'code-as-text' should be 'code-as-representation' at least (you needn't represent anything as text if you dont want to - it could be coloured geometric shapes...)
* I don't understand what 'code-as-procedure' means either. Is this an abstract-syntax-tree or just platform-executable-code?
* 'code-as-data' is meaningless because everything is data, both the text and procedure... Does the OP mean something platform-executable? Or something within a type system?
Good topic to launch discussion on though....
'behaviour-as-text' is the serialization of the behaviour model according to the grammar of the language.
'behaviour-as-data' is the model representation as it is viewed and modified in the model.
'behaviour-as-procedure' is the meaning of the model in the sense of execution. The semantics of the model.
So this text says that the semantics of the behaviour model need to be easily expressed as data, and the textual representation of the model must clearly show both its semantics and its data representation.
1 "data must express procedure"
2 "text must express procedure"
3 "text must express data"
This shows that text both directly expresses procedure by rule 2, and indirectly by rule 1 via rule 3. This indirection step allows recursion to take place (i.e. the data contains a model in the same language as it is defined in) that is used for the model to reason about itself.