There is a fairly widespread consensus that macros are a bad idea in most programming languages. (For example, cf. http://scienceblogs.com/goodmath/2007/12/17/macros-why-theyre-evil/ .)

That said, I have the impression that macros are not just in LaTeX for historical reasons --- there seems to be some property of the typesetting domain that makes macros the right tool. (This seems to be related to the fact that working with LaTeX is very unlike programming in any mainstream language.) Can anyone articulate why this might be the case? Or, indeed, argue that macros are indeed a historical artefact?

Edit: this doesn't answer the question, but is closely related: https://tex.stackexchange.com/a/42749/17049

  • Does Andrew Stacey's answer to that question give you more of an idea? He gives the opinion that it helps the language "hide in the text", which is as good a reason as any. – Ryan Reich Sep 30 '12 at 4:07
  • As I understand, the word “macro” hasn't exactly the same meaning between TeX/C/Lisp/Excel/etc. – morbusg Sep 30 '12 at 10:09

First of all, one should say that in contrast to the blog post you're linking to, you don't have the choice in TeX.

The blog argues that with using macros as a fully Turing complete language on top of the real programming language, macro and execution semantics can get in each other's way (though I think the first example used, the C construct i++ is an abdomination which should be banished from the earth).

With TeX, though, macro and execution sematics are tightly entwined "by design". For instance, with all conditionals being expansion-based, you won't get tail recursion without taking care for expansion semantics.

So the question comes down to whether it was a good idea to design TeX as a macro-based language in the first place.

There are two points to consider here.

First, from a historical point of view, I don't believe TeX's macro feature was meant for programming a lot of complicated stuff. I think Knuth basically designed TeX to do most things right 'out of the box', macros mainly offering

  1. a bit of abstraction,
  2. dealing with state (like section numbers)
  3. medium-severe additional programming like the output routine (just look at the output routine in plain.tex to see what that thing was meant to look like).

Just look at the following macro packages for evidence:

  • plain.tex: 1241 lines
  • manmac.tex: 715 lines
  • gkpmac.tex: 890 lines

That should be roughly the amount of macro programming Knuth ever did...

For comparison, here some numbers from the LaTeX world:

  • latex.ltx: 8003 lines
  • hyperref.sty: 8563 lines
  • all of TikZ: more than 300000 lines (rough estimate)

I don't think TeX's macros were ever meant for doing this...

Secondly, from the present perspective the question is whether a macro language is suited for the task at hand.

I know that opinions vary widely in this respect. A lot of people absolutely abhor the way you program in TeX. I'm not sure whether there are any who really love it...

I hope both factions will speak up here, because I'd like to see the arguments again in detail.

Personally, I'm a bit programming paradigm agnostic, so I tend to see macro programming as just another thing to cope with. There are mainly two things which really annoy me about the macro programming paradigm:

  1. It is very easy to completely and almost irrevocably mess up your code. Such simple things as forgetting a mandatory macro argument or forgetting part of a conditional construct (or even forgetting a space character in the proper position) can change the semantics of your code in ways no human can imagine.
  2. Because there is no real pointer construct, some operations (like adding an item to a linear list) tend to get one more level of computational complexity than they deserve (so adding an element to a linear list will take O(n) time, accumulating to O(n²) for n operations while it should only take O(n) altogether). I'm not completely sure though whether this is strictly owing to macro programming or just a missing data structure in TeX.

On the other hand, in principle, macro execution is rather convenient as part of the whole "typesetting system" paradigm. The fact that text "typesets itself" and you don't need to explicitly print it with a printf statement, with macros interspersed which expand to more text, makes it easy to concentrate on the authoring task while writing down a document, which is what TeX is all about, after all.

I have been thinking on and off what could be an alternative to macros for augmenting text in a typesetting system, but nothing convincing occurred to me.

There have been concrete attempts to combine the typesetting capabilities of TeX with a different programming paradigm, but I don't know anything about them in detail. Hopefully some other people who know more about those attempts will also answer.

At the time being, it seems LuaTeX offers to use original TeX typesetting while at the same time doing all the programming in Lua. There are a couple of regulars here who are doing exactly that, and hopefully they can report a little on their experiences.

  • Things like adding to lists can be done using a bit of imagination (see some of Bruno's stuff in LaTeX3 using effectively \iffalse inside \edef to skip over the closing }, for example). – Joseph Wright Sep 30 '12 at 10:14
  • @JosephWright You need to expand on that. I can ask a specific question if you like. To me it seems that \edef will always need O(n) time, adding up to O(n²) for n iterations. – Stephan Lehmke Sep 30 '12 at 10:18
  • Shouldn't adding to a linear list take O(1) when using optimal data structures? The example makes it sound that you would expect O(n). – Christian Lindig Sep 30 '12 at 13:03
  • @ChristianLindig Based on Joseph's comment, I was suspecting as much. With data structures, often accumulated efforts for n operations are measured. But the way I wrote it it might really be misleading. I'll edit the post. – Stephan Lehmke Sep 30 '12 at 17:19

Most programming languages today are defined in layers: text is broken down into tokens which are mostly defined by regular expressions including a fixed set of keywords, tokens form the basis of a context-free grammar which builds an abstract syntax from the token stream. Identifiers as part of the syntax are statically scoped. The static semantics of an abstract syntax is partially defined by a type system, a well-type program has dynamic semantics ...

This clarity simply wasn't there when Knuth worked on TeX in the Seventies and I would attribute some of his design decisions to the state of the art at that time while still acknowledging that a document processing language has a different purpose than a programming language. For example, nobody today designs a language without a fixed set of keywords or some kind of module system whereas TeX's catcodes permit to re-define the syntax of the language and a module system simply doesn't exist.

The Lout system is an exercise in re-thinking TeX and Unix Troff. As a result, Lout has a more rigid static and dynamic semantics than TeX but I would argue that this difference is too small to leapfrog TeX despite all its quirks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.