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

Lisp will have played its major part when other languages have real macro systems.


Other languages don't necessarily need 'real macro systems'

Lisp does, not just because it is so hopelessly low-level (for FP), but also because once you're using s-exprs it's hard to restrain anyone from mogrifying functions.

In a suitable language like Haskell where all functions are composed, using functional composition for everything instead of low-level fiddling with "statements as data" makes a shit-ton of sense. In Haskell you can also use supercompilation to resolve as much of the graph as possible at run time. No need for macros.

Don't think that other language communities want the warts from your language, just because you are so enthusiastic about them.


To be honest I wasn't thinking of Haskell when I mentioned "other languages". Haskell has less need for macros for the reasons you mentioned. Lazy evaluation also makes macros unnecessary for creating your own conditionals. For eager-evaluation languages, or languages without such concise syntax for functional composition, macros fill a real need.


How would you do this in Haskell? http://news.ycombinator.com/item?id=222189


By the way (this is a serious question), what software products have been produced that were written in Haskell?


Besides the Glasgow Haskell Compiler (which probably doesn't count, for your purposes, but it's a good example of a large and complex program), the best example is probably Darcs (http://darcs.net/), a distributed version control system with a powerful patch composition system.

There are further answers from the Haskell wiki here: http://haskell.org/haskellwiki/Haskell_in_practice


Macros are a double edged sword. Their advantages also drags in some disadvantages. If they were only advantageous, they would have flown into mainstream languages long ago(in the full Lisp-sense where the macro is a lisp program).

But they have not. This can be due to multiple reasons: their disadvantages outweigh the advantages or that the effort of getting them into the language simply drags so many other undesirable things with it. Perhaps the advantage of a macro is perceived to be so small compared to e.g., function composition and higher order functions, that it is left out of the language.


I disagree about that. It's very, very hard to add Lisp-style macros to something like C or Java. The best attempt to do it for Java is Jonathan Bachrach's Java Syntactic Extender, but as far as I know nobody has built any software with it. It's just too hard to use.

Until you have read a clear description (e.g. Seibel) or had some experience, it's hard to see what macros are really all about.

Lisp macros are extremely important, powerful, and beneficial. Space does not permit me to go into the full explanation; see Peter Siebel's book and the great lecture he gave at Google, available on the web.

Macros allowed us to add object-oriented programming to Common Lisp. CLOS (the Common Lisp Object System) fits in very smoothly into the Common Lisp language, with a nice, clear syntax and very powerful semantics. At work, we have built an object-relational mapping system that, similarly, would be impractical (ugly and verbose to the point of unusability) without macros.


I weren't clear enough, sorry.

Yes, it is extremely hard to add lisp-style macros to C or Java because they have no s-expression structure you can work on. And they do not want an s-expression structure because it is too alien for those programmers. Thus, they perceive that macros are not worth the effort.

I think macros are left out of so many languages because people do not know how to incorporate them while retaining other desirable properties of the language (type safety for instance).

Also, macros are not the only way to build ORM systems. Python does the same with metaclassing as an example. But we can agree on that trying to map it into a statically typed language with reflection/AOP as Java did is doomed to fail I think ;)

I am not trying to say that macros are useless. I am trying to say that some languages leave them out on purpose. Many problems on which macros look nice can be solved with a little extra thought on representation. But then again, many can not.

I see the discussion of macros/no-macros a bit like the discussion on static/dynamic typing. With static typing, we know we are leaving some valid programs outside the gates of the static world. But we think that this loss is negligible compared to the benefits a static check gives us. Yet, some people oppose this viewpoint and wants the valid programs as well, because they perceive the benefits of the static typing to the negligible. Both approaches are valid, but it currently looks like it is hard to get all of the cake in one munch.


Macros haven't flown into mainstream languages, but they've been smuggled in through the back door. C++ templates were not intended to be as useful as they are, but now many of the most powerful C++ libraries use templates as a compile-time metalanguage. Java library developers have also discovered the advantages of the transformation of data into runtime code - except they use XML as the data medium instead of s-expressions, and they use Java reflection to translate the XML instead of using "read" to get a Lisp object.

Ruby and Javascript library authors use the metaprogramming capabilities of their respective languages in combination with XML or JSON or YAML data. Look at ruby on rails, or at jquery.


Why can't macro systems be part of an IDE? Is there anything macros do that can't be done at compile-time?

Startup idea: web-based language-specific IDE, with a simple interface for sharing/voting on macros between users.


The lisp macro system can more or less be done at compile time, yes, but that's not the problem with other languages. The format of lisp makes it especially easy to do macros - code is data!

Here's an example. Take, for example, this class declaration:

  (defclass dog (animal)
    ((size :accessor dog-size)
     (name :accessor dog-name :init-form "Fido")))
How do you make that into data? Easy. Just quote it:

  '(defclass dog (animal) ...)
Now take the equivalent in Java:

  public class Dog {
    int size;
    String name = "Fido";
  }
How do you get that into data? Well, I suppose the best you could do without modifications to the core language is just put it in a string. But then to do something useful you'd have to do so much tedious string parsing it wouldn't be worth it. I suppose you could invent a special ParseTree class or something, and a quote operator, and etc etc, but that wouldn't be nearly as easy as Lisp makes it.

What the previous poster was saying is that once other languages have a code representation that is easy to work with as data, and can manipulate that code as data at compile-time to produce complex macros, then Lisp might fade. (At least that's how I understood it, correct me if I'm wrong.)


Or:

1. Allow a factory for Class.

2. Make Method contain the full body contents as a list of statements, and give them a factory as well.

Then it's a matter of reasonable constructor syntax.


And a whole lot of "wait, what tree does this code map to again?"

With lisp, there's no difficulty mapping:

   int main(int x) {foo()}
to

  Method m = new Method(return:=new Type(int),
                        args  := new ArgList(
                                  new Arg(new Type(int),
                                          new Name("x"))),
                        body  := new Block(
.... I'm sure you get the point....

The syntax tree is apparent from the syntax.

  (+ 1 2 (* 3 4))
Maps to:

  '(+ 1 2 (* 3 4))


While people generally talk about using macros for code generation, macros are essentially for doing things at compile time. (Or read time, in the case of read macros, e.g. 'x -> (quote x).) Due to simplicity of Lisp syntax, the easiest way to extend the language is usually by generating code, though, so that's what they're associated with.

You can do things with the C preprocessor at compile time, it's just completely unaware of C, which really cripples it. The Lisp preprocessor (its macro system) is also running Lisp, and can easily process itself.




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

Search: