Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm sorry for asking a dumb question; I'm a sysadmin not a software developer:

Is this similar to needing a dozen nearly-identical lines of code, writing one, then using Excel to manipulate the other 11 lines into what you want, then copying it back (and cleaning tabs in the process)?

Essentially programmatically writing the program - is that what Lisp's macros are?



    Essentially programmatically writing the program -
    is that what Lisp's macros are?
Macros are often described that way. "Lisp macros let you write code that writes code!" While that's a true statement, it's kind of useless for coming to an initial understanding of what macros let you really do.

Think of it this way. Programming languages have built-in control flow operators like if-then, do, while, and for. Macros let you write your own operators - that work just like the ones built into the language itself.

Here's an example. Let's say you want to print a list of names.

In a language without an operator specifically for going over lists - and without macros - you may have to write:

    ListIterator iterator = namesList.GetListIterator();
    while(iterator.HasMoreItems()) {
        string name = iterator.GetNextItem();
        print(name);
    }
If you have a language that supports macros, you can create a macro called forEachItemInList. And then it'll work just like it came with the language all along:

    forEachItemInList(string currentName in namesList)
    {
        print(currentName);
    }
If you count how many words the non-macro solution took, it's 13. The macro solution takes 7. Having to solve a problem with more code means more time to understand, teach, write, test, debug, and document - so savings like this can really add up.

And there's also the subjective part. Having to write code like in the first example just isn't satisfying. You have to repeat yourself constantly. You may think, "Look, I loop over lists all the time. And it's always the same pattern: I call GetListIterator(), I do a 'while' loop while it HasMoreItems(), then I call GetNextItem(), etc. Why can't I just inform the compiler of the general pattern - and then tell it how to fill in the blanks when I need to actually loop over a list?"

And that's what macros let you do.


Thanks for describing this. In one way it looks like writing a function and calling it. I suppose macros are a faster way.


Yes, except more reliable.

The fundamental unit of Lisp is expressions of the form (FOO ...). There are three basic cases.

1. FOO is one of a finite list of special forms. Those are the irreducible base of that language.

2. FOO is a function. In which case the ... is evaluated as Lisp (possibly including doing things like expand out other functions) before being passed to that function.

3. FOO is a macro. In which case the ... bit is turned into a list of things, but NOT evaluated, passed to the macro to be rewritten, and then the result is turned into an expression that is then evaluated by the same rule.

This is not completely true. There is a preprocessing step called reader macros that can do things like turn `(this expression) into (QUOTE this expression) to save typing. But those are very sparingly used.


Not a dumb question at all, and yes, that's more-or-less what Lisp macros are, albeit more elegant because you're using the same language to write your code as you use to write the macros that manipulate the code.


More or less. It allows you to write generic code you can reuse. In this case, you are extending the language. Feel free to post these "dumb" questions, or send them my way.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: