[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: macros vs. blocks



On Fri, 2002-11-22 at 14:18, Guy Steele - Sun Microsystems Labs wrote:

> 
> They're so expressive, they let me express the idea that I need
> only a few relevant line numbers kept around at run time, rather
> than all of them!

I don't believe in adding a complex language feature for small runtime
savings. Lots of lines * a few bytes of bookkeeping is a very small
fraction of the memory in my computer. Say 100,000 lines * 8 bytes / 1
GB is 0.08%, a small price to pay for decent debugging.

So, I've seen a lot of examples where macros save you some typing. They
save you the (lambda () ...) and ', and they can save repeating an
expression as a string, so they might save up to 1/3 typing in some
particular cases. Realistically, it's more like a few [] and '
characters in languages with appropriate block & quote syntax.

You need something much less general than CL macros for this: functions
annotated with "make this arg a block" and "make this arg quoted" would
suffice. I think I'd still prefer to add [] and ', to make these
explicit.

I'm still looking for examples, in languages that already have the
basics like assignment, where macros make a big qualitative
simplification of the program.


> How about: macros are so expressive, that Lisp doesn't
> need primitive conditional AND and OR operators the way C has
> && and ||.  Instead they can be macros:

OK, but if you use functions + blocks, you can also have differently
named functions. For example, in Smalltalk I could add when: and and:
and even && and || functions to the boolean operators, to allow:

 x when: [y]
 x && [y]
 x && [y] && [z]

or whatever you like. In fact Smalltalk has a big roster of these,
although they tend to be wordy like ifTrue:. So this is a property of
some particular macros that CL has, not a general advantage of macros
over functions + blocks.


> Now, I *know* there are better examples out there, I just want
> somebody to bring them up.  The best I can do right now is 
> the typical with-html macros people use for generating
> markup - I've never been able to satisfactorily replace 
> those in Smalltalk or Ruby.

I wrote a big system in Perl to generate HTML using functions + blocks,
and liked it pretty well. The code looked like:

table(trow({valign => 'top'}, td(sub{
  for $x in (1..3) {
     print $x;
  }
})))

which would generate

<table><tr valign=top><td>123</td></tr></table>.

Functions like td took a block (and some optional parameters) and
printed <td ...>, called the block, then printed </td>. It was then
straightforward to write bigger functions that composed entire tables or
embedded them in a page layout. Better yet, since any piece was a
first-class object (a block) I could pass it around and keep data
structures of them, etc. It's far more flexible than the idiom of

(defmacro tr (body)
  (print "<tr>")
  ,body
  (print "</tr>")).

since you can't easily say, in such a macro-based system:

 x = ... generate inner table ...
 if using MSIE:
     x = wrap_in_outer_table(x)
 output x


Macros wouldn't have helped me write the functions like table and td
either. In fact, I generated all these functions dynamically from a DTD.

-- 
Trevor Blackwell      tlb@anybots.com       (650) 776-7870