| This is my understanding of homoiconicity. There's a good chance that I'm wrong. Comments and clarifications welcome! ----- Is homoiconicity about concrete syntax? I think the answer is no , but I also think that this confuses lots of people because it's not explicitly stated. Then is homoiconicity about abstract syntax? Let's say we have some arbitrary language, for which there's an eval function (input: abstract syntax tree, output: some data structure) whose job is to execute/evaluate a program in that language. Homoiconicity, then, is the case where the output data structure is also an abstract syntax tree, or conversely, that an abstract syntax tree is expressed in data structures of the language. So for homoiconicity, the input and output of your eval function are of the same type (of course the type may be a complicated algebraic sum type etc.). Thus the input and output have the same domain. This means that you can take the output from eval, and throw it back into eval again without getting a type error. If the input and output types of the eval function don't match, then the language isn't homoiconic. Is this correct? What I don't get is whether the eval function is available from inside or outside the language, or both. I'm also unsure of whether homoiconicity is a property of a language, or of an implementation of a language. |
A good example is JavaScript, often called a "lisp-like" language. In JavaScript you have the function Function() which takes a String as input and produces a Function. Thus a JavaScript program can create another program which it executes within itself. But it is not homoiconic: input of Function() is a String, and its output is a Function. You can not pass the output of Function() as an input to another call of Function().