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

I agree. Macros are what made lisp, not parentheses.

However, if we broaden the concept a little, we can do this type of macros for any language with a meta-layer such as MyDef. e.g. if you observe certain foreach pattern in Java, you can make a macro for that pattern and have the meta-layer look out and translate that for you (like having an automatic translator between you and javac. All you need is a scope type macro. Conventional macro packages like M4 does not provide such, but MyDef does. Example:

    &call each_member, AList
        # java code that work on $(member)
where the macro may be defined as

    subcode: each_member(list)
        Enumeration e = $(list).elements();
        while (e.hasMoreElements()){
            String name = (String) e.nextElement();
            $(set:member=name)
            BLOCK
        }
  
Where it is understood that the definition can be any literal block pattern.


    Macros are what made lisp, not parentheses.
The parentheses are huge, though. It enables "Code is data" and "Data is code" in a powerful way.

About Lisp, people always say "Macros are great" and "Code is data" and "Data is code", but it's hard to see what they mean without good examples. I mean, you can write code that writes code in any language that has a `print` statement. And obviously code is data, so what is that aside from some pseudo-philosophic BS?

There's a lot of discussion in this thread about macros - so here's an example of Code and Data Being One, for those that are unconvinced. I hope it'll shed some light.

I have a slang dictionary website. It's backed by a database now, but it used to be statically-generated HTML. I represented the data as XML. It looked something like this:

    <Term term="slick">
      <PartOfSpeech pos="adj">
        <Definition>
          impressive.
        </Definition>
        <Definition>
          smart.
        </Definition>
      </PartOfSpeech>
    </Term>
So then I needed an XML parser to parse the data. Maybe it parsed the XML into a object model that the code would navigate and output the appropriate HTML. Or maybe the code got callbacks according to node type and would output the appropriate HTML then.

XML is a pretty verbose format, so - this being a Lisp example - we could probably save some typing if we represented the data as an S-expression. The above XML would become something like this:

    (Term "slick"
      (PartOfSpeech "adj"
        (Definition
          "impressive."
        )
        (Definition
          "smart."
        )
      )
    )
But that's an idiosyncratic style.

So, let's lowercase the node types, use hyphens rather than camelCase, and remove the unnecessary line breaks. Now the data looks like this:

    (term "slick"
      (part-of-speech "adj"
        (definition "impressive.")
        (definition "smart.")))
Great. We've got our data.

Now we need to write the Lisp code to convert that S-expression data into the appropriate HTML output.

We'll need some Lisp functions to handle the nodes and their attributes (such as the definition text and part of speech) and write the HTML for them. We could use an S-expression parser library to load the data, and then walk through it and call those functions. But that's not necessarily the best way. We can simplify it by creating exactly 3 functions that take some arguments and output HTML: term, part-of-speech, and definition.

Since Lisp code is - like the data - also represented as S-expressions, once we've written those 3 functions, the data is literally executable Lisp code.


That's a great example right there.

Notice, the end result is just data, as terse and minimal as possible. But to act on (aka "interpret) that data, he wrote functions called "term", "part-of-speech" and "definition."

So now, that data is code. Code is data and data is code.


Agreed - that example is amazing. However, the devil's advocate in me can't help but ask: what if I want more than one transformation? What if I want to generate both HTML and, say, JSON for returning that information from a web service?

Hmm... it might work if I use some sort of global parameter: I first "execute the data" (damn!) with the output type set to HTML and then do it again with an output type of JSON.


There's an answer there too. In Lisp, it is possible to have local functions. In other words, you're defining a function, and inside it you have a couple of functions that are local to the containing function.

That's one way for "term" and the other items to have different definitions.

There are probably other even better ways to do it.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

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

Search: