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

The one feature that really differentiates Lisp from other languages is its macro system. Macros allow you to give arbitrary semantic meaning to an expression. The expression (a b c) could quite literally do anything. It could set the value of b to the value of c (setf), it could call the procedure named by c with the value of b and store that value back into b, or define a class called b which has a local variable called c. Macros allow programmers to build arbitrarily complex DSLs all within Lisp.

A couple examples of some really great macros are those in PAIP[0]. In particular, look at the defrule macro[1][2] for a version of mycin[3]. The macro defrule is a DSL for creating rules about how to diagnose different bacteria. Also look at the rule macro[4][5] for defining DCGs[6], a way to parse natural language.

A great way to learn more about macros is through reading On Lisp[7], in which Paul Graham explores some of the really crazy things that are possible with macros, including implementing continuations[8], creating a DSL for ATNs[9] (another way to parse natural language), and even implementing an object system.

[0] http://norvig.com/paip.html

[1] http://norvig.com/paip/mycin-r.lisp

[2] http://norvig.com/paip/mycin.lisp

[3] http://en.wikipedia.org/wiki/Mycin

[4] http://norvig.com/paip/grammar.lisp

[5] http://norvig.com/paip/unifgram.lisp

[6] http://en.wikipedia.org/wiki/Definite_clause_grammar

[7] http://www.paulgraham.com/onlisp.html

[8] http://en.wikipedia.org/wiki/Continuation

[9] http://en.wikipedia.org/wiki/Augmented_transition_network



Lisp's macro system is so powerful that it actually turned out to be the 'curse' of Lisp:

http://www.winestockwebdesign.com/Essays/Lisp_Curse.html

However I wouldn't call it "curse" but merely the truth that Lisp programmers need a lot of self discipline to write maintainable code.

Lisp was one of the first languages I learned at university (also Pascal and Ada). Afterwards I learned almost every other new programming language. Lisp and the Scheme dialects are still the most powerful languages of all, to this day.

People who are intimidated by such a raw power should take a look at Nim (nim-lang.org). It takes the best of several modern languages and it also has an amazingly convenient and powerful macro system. For instance:

  template repeat * (body: stmt): stmt {.immediate.} =
    block:
      while (true):
        body

  template until * (cond: expr): stmt {.immediate.} =
    block:
      if cond:
        break

  var i=0
  repeat:
    echo i
    i += 1
    until i==7


Also, the language syntax is (basically) designed to be parsed in a trivially obvious way into the internal "list" (really tree, with lists as a common special case) data structure. This lets the friction of writing macros which work with code (or with structured data) be very low: the macro logic that you write is fed that parsed list and works with it directly, skipping the usual glue logic for telling a parser how to cope with syntax for a language extension.

(The "basically" caveat above is because some Lisps honor this code-is-a-list principle more than others. E.g., I have seen remarks about how modern Schemes have moved away from it at least a little bit, with syntax which is importantly not quite a list, though I don't know any of the details. And CL has other kinds of reader magic --- like one-character "reader macros" and like the implicit package which is used as a default for symbols at read time when no explicit package is given --- that can in principle complicate the obvious 1-1 correspondence between source and parsed-as-list representation, although in practice that magic is very seldom used in such a way that you need to think about it.)


> The one feature that really differentiates Lisp from other languages is its macro system.

That's not exactly true. There are many languages, both old and new, which provide macro systems comparable to defmacro and/or syntax-rules. Dylan, Nimrod, Julia and Elixir come to mind.

I personally don't think there's one feature which makes lisps this great. It's really the whole experience, from syntax to repls to tools and so on.


The counterargument has been that while other languages may provide powerful macro systems, they're not as easy to use, nor are they homoiconic.


That's not quite true either. Julia, Prolog, Io are homoiconic, for example. Ease of use is subjective, but most AST based macro systems work in the same way defmacro does, using quote and unquote. Then there's Scheme and syntax-rules, which are (arguably) even easier to get right (not necessarily to use) and which don't even need homoiconicity.


Wow, great answer, many thanks for that!




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

Search: