Hacker News new | ask | show | jobs
by bhnmmhmd 3256 days ago
The Python example looks really inspiring, and could possibly be implemented in future versions of Python.

But as for your statement that "macros don't rely on homoiconicity", I find it hard to agree, because if that were the case, then why haven't Java or Python implemented the macro feature by now?

2 comments

Macros don't rely on homoiconicity. The raw power of Lisp macros rely on it. This is because, as you know, lisp code is lisp data. All of the functions for manipulating lists, which form the basis of a lisp language, can be used to build and emit code.

In reality, lisp macros are functions that accept lists and emit lists. The difference is they operate at compile time, so they transform code.

In fact, a common macro implementation pattern is to delegate the actual work to a function that transforms lists, with the macro passing the code as a list and returning the resultant list as expanded code. I imagine this makes macros an order of magnitude easier to test.

In other languages, it's possible and can be done as in Rust etc. It's just far far more natural to do so in a homoiconic language due to the above.

Perl 6 has macros:

Copied from: https://perl6advent.wordpress.com/2012/12/23/day-23-macros/

    macro checkpoint {
      my $i = ++(state $n);
      quasi { say "CHECKPOINT $i"; }
    }

    checkpoint;
    for ^5 { checkpoint; }
    checkpoint;
No "homoiconicity". Just two operators: "macro" which will make a macro instead of a normal function, and "quasi" which says the stuff in here is code that shouldn't be evaluated. In lisp these two operators could be "defmacro" and "quote".

Lisp has a lot of features that other languages haven't implemented. We could spend all day asking why other languages haven't implemented them yet. And it's unfortunate, because just adding the feature for macros would allow you to add a lot of those other features. Indeed, macros are such a big deal that they are probably the sole defining reason that lispers can add features from other languages so easily.

However, we need to stop pretending that code substitution is some magical, genius feature that can only exist in the utopian environment of a common lisp system. It's a simple idea that's been used since before I was born. Macros in lisp are nice because you have so much access to the language, as well as (perhaps more so than any popular language) really smart tools for manipulating the data structure your code is written in. If you have to code code, if you have to write code that manipulates other code, it's nice if that other code is in an easy to understand data structure. And even easier if you already have a bunch of functions, classes, variables, etc given to you by the language for changing that data structure. Which lisp does, and that's what makes lisp lisp.

Thank you. I never thought Perl 6 had macros. Plus, now I can see that "homoiconicity" is not required for macro systems.

> However, we need to stop pretending that code substitution is some magical, genius feature that can only exist in the Utopian environment of a common lisp system.

I couldn't agree more.