notes-computer-programming-programmingLanguageDesign-prosAndCons-macros

The Lisps are languages which are widely considered to do macros well.


examples of things that macros do that laziness doesnt:

http://www.reddit.com/r/programming/comments/ujj3/a_critique_of_abelson_and_sussman_or_why/cutzn


problems with C macros:

"

But a bigger advantage is that it makes it possible to write Lisp programs that reliably generate and transform Lisp source code. If you're not used to Lisp, it's hard to imagine how tremendously useful this is. People who come from the Perl and C world have a deep suspicion of source code transformation, because it's invariably unreliable. C's macro system, for example, is so unreliable that you can't even define a simple macro like

  1. define square(x) x*x

without falling afoul of all sorts of horrible traps. First, you have to realize that this won't work:

        2/square(10)

because it expands to:

        2/10*10

which is 2, but you wanted 0.02. So you need this instead:

  1. define square(x) (x*x)

But then you have to know that this won't work:

        square(1+1)

because it expands to

        (1+1*1+1)

which is 3, but you wanted 4. So you need this instead:

  1. define square(x) ((x)*(x))

But then you have to know that this won't work:

        x =3D 2;
        square(x++)

because it expands to

        ((x++)*(x++))

which is 159.8, but you wanted 4. So you need this instead:

        int MYTMP;
        #define square(x) (MYTMP =3D (x), MYTMP*MYTMP)

but now it only works for ints; you can't do square(3.5) any more. To really fix this you have to use nonstandard extensions, something like:

  1. define square(x) ({typedef xtype =3D x; xtype xval =3D x; xval*xva= l; })

And that's just to get trivial macros, like "square()", to work. If you want to do anything interesting, your best strategy is to give up as soon as possible. For example, let's use the C macro system to define a "strswitch" construction so that

        strswitch(expr) {
           case "foo": do_foo(); break;
           case "bar": do_bar(); break;
           default: do_default(); break;
        }

is transformed to

        _tmp =3D expr;
        if (strcmp(_tmp, "foo") =3D=3D 0) { do_foo(); }
        else if (strcmp(_tmp, "bar") =3D=3D 0) { do_bar(); }
        else { do_default(); }

at compile time. With the C macro system? Are you insane? HA HA HA HA! "

---

---

http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg01539.html

" At Sat, 25 May 2002 05:01:07 -0400 (EDT), Kragen Sitaker wrote: > I thought I'd reply to recent LL1 traffic with one message instead of > several.

> > So you can go some distance in the direction of syntactic abstraction > in Python with operator overloading. But I often wish for more, for a > variety of reasons explained in _On Lisp_. Most often, I wish for > unwind-protect macros (Scheme's with-open-file, for example, and > sometimes I wish for an analogous with-lock-held) and new binding > constructs, although I would like these to be merely a more convenient > interface to existing functions. >

I'd like to propose that there are three disciplined uses of macros:

1. data sublanguages: I can write simple looking expressions and create complex nested lists/arrays/tables with quote, unquote etc neatly dressed up with macros.

2. binding constructs: I can introduce new binding constructs with macros. That helps me get rid of lambda's and with placing things closer together that belong together. For example, one of our teachpacks contains a form (web-query ([last-name (string-append "Hello " first-name " what's your last name?"]) ... last-name ... first-name ...) with the obvious interaction between a program and a Web consumer implied. [Note: In ML you could write web-query(fn last-name => ...)string_append(...) but by golly that's a pain and an unnecessary pattern.]

3. evaluation reordering: I can introduce constructs that delay/postpone the evaluation of expressions as needed. Think of loops, new conditionals, delay/force, etc. [Note: In Haskell, you don't need that one.]

I understand that Lispers use macros for other reasons. In all honesty, I believe that this is partly due to compiler deficiencies, and partly due to "semantic" irregularities in the target language.

I challenge people to address all three issues when they say language X can do what macros can do.

-- Matthias "

"

Gee, I think there are more valid uses than that, but having not programmed in Lisp for 14 years I don't remember too many of them. But one that I used a lot when I wrote an Emacs in Lisp was something on the order of:

(defcommand move-forward "c-f" "Move the cursor forward by one" [insert Lisp code here])

This is a very modest macro that builds up a command dispatch table and a table of simple online help. I don't think this falls into any of your categories. "

---

--

"What's Wrong with C++ Templates?"

http://people.cs.uchicago.edu/~jacobm/pubs/templates.html

---

http://docs.scala-lang.org/overviews/macros/overview.html