
Discussion about macros, Lisp, laziness etc. Too many people to cite. Alan Bawden uses macros to write assertions, and Dylan Thurston comments: ...
(assert (< x 3))
Which macro expands into:
(if (not (< x 3)) (assertion-failed '(< x 3)))
Where `assertion-failed' is a procedure that generates an appropriate error message. The problem being solved here is getting the asserted expression into that error message. I don't see how higher order functions or lazy evaluation could be used to write an `assert' that behaves like this.
This is a good example, which cannot be implemented in Haskell. "Exception.assert" is built in to the ghc compiler, rather than being defined within the language. On the other hand, the built in function gives you the source file and line number rather than the literal expression; the macro can't do the former.
--Dylan Thurston
In general this is not true, look at the macro preprocessing in C. If your parser is kind enough to yield to the user some pragmatic information about the read text, say, __LINE etc., you can code that kind of control with macros as well. Macros in Scheme are used to unfold n-ary control structures such as COND into a hierarchy of IFs, etc. Nothing (in principle) to do with laziness or HO functions. They are used also to define object-oriented layers in Scheme or Lisp. I used them to emulate curryfied functions in Scheme. I think that they are less than popular nowadays because they are dangerous, badly structured, difficult to write "hygienically". Somebody (Erik Meijer?) asked: "Don't you get dynamic scoping as well with macros?" Well, what is dynamic here? Surely this is far from "fluid" bindings, this is a good way to produce name trapping and other diseases. In Clean there are macros. They are rather infrequently used... In C++ a whole zone of macro/preprocessor coding began to disappear with the arrival of inlining, templates, etc. I think that macros belong to *low-level* languages. Languages where you feel under the parsing surface the underlying virtual machine. You can do fabulous things with. My favourite example is the language BALM, many years before ML, Haskell etc., there was a functional, Lisp-like language with a more classical, Algol-like syntax, with infix operators, etc. The language worked on CDC mainframes, under SCOPE/NOS. Its processor was written in assembler (Compass). But you should have a look on it imple- mentation! Yes, assembler, nothing more. But this assembler was so macro- oriented, and so incredibly powerful, that the instructions looked like Lisp. With recursivity, parentheses, LET forms which allocated registers, and other completely deliciously crazy constructs. In fact, the authors used macros to implement the entire Lisp machine, used to process BALM programs. //Side remark: don't ask me where to find BALM. I tried, I failed. If *YOU* find it, let me know// Another place where macros have been used as main horses was the MAINBOL implementation of Snobol4. But when people started to implement Spitbol etc. variants of Snobol4, they decided to use more structured, higher-level approach (there was even an another, portable assembler with higher-level instructions "embedded"; these avoided the usage of macros). Jerzy Karczmarczuk Caen, France