HiveBrain v1.2.0
Get Started
← Back to all entries
snippetModerate

How to make a language homoiconic

Submitted by: @import:stackexchange-cs··
0
Viewed 0 times
makehomoiconiclanguagehow

Problem

According to this article the following line of Lisp code prints "Hello world" to standard output.

(format t "hello, world")


Lisp, which is a homoiconic language, can treat code as data in this way:


Now imagine that we wrote the following macro:


(defmacro backwards (expr) (reverse expr))


backwards is the name of the macro, which takes an expression
(represented as a list), and reverses it. Here’s "Hello, world" again,
this time using the macro:


(backwards ("hello, world" t format))


When the Lisp compiler sees that line of code, it looks at the first
atom in the list (backwards), and notices that it names a macro. It
passes the unevaluated list ("hello, world" t format) to the macro,
which rearranges the list to (format t "hello, world"). The resulting
list replaces the macro expression, and it is what will be evaluated
at run-time. The Lisp environment will see that its first atom
(format) is a function, and evaluate it, passing it the rest of the
arguments.

In Lisp achieving this task is easy (correct me if I'm wrong) because code is implemented as list (s-expressions?).

Now take a look at this OCaml (which is not a homoiconic language) snippet:

let print () =
    let message = "Hello world" in
    print_endline message
;;


Imagine you want to add homoiconicity to OCaml, which uses a much more complex syntax compared to Lisp. How would you do that? Does the language has to have a particularly easy syntax to achieve homoiconicity?

EDIT: from this topic I found another way to achieve homoiconicity which is different from Lisp's: the one implemented in the io language. It may partially answer this question.


Here, let’s start with a simple block:

Io> plus := block(a, b, a + b)
==> method(a, b, 
        a + b
    )
Io> plus call(2, 3)
==> 5




Okay, so the block works. The plus block added two numbers.


Now let’s do some introspection on this little fellow.

```
Io> pl

Solution

You can make any language homoiconic. Essentially you do this by 'mirroring' the language (meaning for any language constructor you add a corresponding representation of that constructor as data, think AST). You also need to add a couple of additional operations like quoting and unquoting. That's more or less it.

Lisp had that early on because of its easy syntax, but W. Taha's MetaML family of languages showed that it's possible to do for any language.

The whole process is outlined in Modelling homogeneous generative meta-programming. A more lightweight introduction to the same material is here.

Context

StackExchange Computer Science Q#63464, answer score: 12

Revisions (0)

No revisions yet.