I have been using LaTeX professionally almost every day for almost 10 years, so I think I can say that, by now, I more or less know what I'm doing. I also do a lot of ordinary computer programming, in traditional languages like C++ and Visual Basic. As I compare LaTeX to these other languages, the following question often comes into my mind:

Why is LaTeX so complicated?

Despite my considerable experience with LaTeX, I still regularly encounter non-obvious behaviour and strange error messages, and there are many parts of the language that seem arcane and obtuse. Here are just a few examples:

  • Macro hell: tangled webs of junk (\relax, \csname, \let, \patchcmd, \expandafter, ...) sprinkled throughout all but the simplest macros
  • The ridiculous \makeatletter and \makeatother all over the place
  • Nonlocal error messages which can be difficult to fix
  • No straightforward types (int, bool, float) with the ordinary manipulation functions. Instead, a patchwork of different types of counters and registers, each of which have to be manipulated in their own special way (sometimes 2\mynum, sometimes 2*\mynum, sometimes \multiply \pgf@x by 2, sometimes \addtolength{\mynum}{3}, ...)
  • Loops and conditionals are much more fiddly than they should be
  • No arrays
  • Checking for equality is ridiculously awkward (\equal{\mybool}{true}, ...)
  • No straightforward subroutine syntax
  • Fixed memory limits rather than dynamically-allocated registers
  • No incremental compilation in most LaTeX engines - if I change the last line of my document, or make a tiny change to a TikZ figure, I shouldn't have to spend tens of seconds recompiling to see the effect

I could go on.

Let me be very clear about one thing: I have the greatest respect for those who developed TeX and its associated programs and packages. The system is enormously impressive and awesomely powerful. Also, every apparently-arcane feature I mention above of course exists for some good reason, and (at least) at the time it was designed, solved a real problem in (at least locally) a sensible way. And other programming languages of course have their flaws.

But surely, it is nonetheless appropriate to recognize the complexity and limitations of the system as a whole which exists now, and ask: does it have to be like this? If we could design a typesetting system completely from scratch, in 2015, couldn't we make something much simpler and more intuitive?

closed as primarily opinion-based by Kurt, Henri Menke, Paul Gessler, Paul Gaborit, cfr Jan 13 '15 at 4:11

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 11
    As you basically implied in your question: TeX is from a time when computers are very limited compared to today's machines. And typesetting is a much more complicated stuff than solving ODE's etc. numerically. So many features are 'relics' from earlier 'ages', but still necessary. – Christian Hupfer Jan 10 '15 at 11:57
  • 14
    CTAN Lists over 2000 authors. Get them in a room and let them discuss a sonsistent syntax till. I bet some guys will starve to death till any match occurs. There are developments/improvements to make some of the points you noted vanish. But in your list they just add up. – Johannes_B Jan 10 '15 at 11:57
  • 24
    LaTeX has grown over the year from the work of many people. So it is a bit like an rather old town: Some parts looks new but there are also some curious old streets and not every house fits in the environment. And like a town you can't simply simply tear everything down to build a new shining city. You can only try to improve things slowly. Btw: You should look at expl3: A lot of the things you are missing have be implemented there. – Ulrike Fischer Jan 10 '15 at 12:11
  • 12
    if you had ever seriously used another math typesetting language, especially in a production setting, you would appreciate that latex is in fact more reliable and consistent, if quirky. – barbara beeton Jan 10 '15 at 13:24
  • 11
    I think this question should be closed as “primarily opinion-based” and voted accordingly. It's just your opinion that (La)TeX is hard to use, that \makeatletter and \makeatother are ridiculous and so on. Probably also Is LaTeX outdated should be closed for the same reason, but its spirit is quite different. My opinion is that programming in TeX requires a different approach from other languages, but it's not harder or easier. – egreg Jan 10 '15 at 16:32

10 Answers 10

up vote 107 down vote accepted

Although this question (and this answer) will stir up opinion, rather than fact, and so get teleported into Moderators' Oblivion, I'm going to have a crack, with a few ideas:

  • TeX is very old. It was written when (a) there wasn't enough CPU power around, and (b) when all it basically had to do was produce something that was going to be printed. But now it has become the hammer that makes everything look like a nail (validly or no): different output formats (eg PDF, HTML); animation; ebooks; slideshows, and more.

  • There has always been a serious concern -- "Thou shalt not break a legacy document" -- which, IMO, has inhibited possible approaches to "cleaning up" the language.

  • Like all programming languages, it has suffered what I call biological decadence: new users learning bad habits from old users. Even here, on TeX.SE, it is possible to see "correct answers" languishing while "answers which merely work" get accepted.

That said, there is light on the horizon. I believe the LaTeX3 project is heading firmly in the right direction to ensure that us end users (the "authors") see much less of macro hell and expandafter purgatory than hitherto necessary. So:

  • Support the LaTeX3 project in any way you can;

  • Think very carefully about whether LaTeX is the right vehicle for your particular document in your particular epoch;

  • Here on TeX.SE, when two answers both work, favour the simpler one

  • 12
    Everyone tosses around the "very old" excuse, but C is hailed as being simple yet powerful precisely for the same reason, so I wonder if (a) is something of a red herring. Your (b) seems closer to the mark, in that TeX's scope/applicability has been augmented piecemeal over time, whereas e.g. C started out broad. A lack of foresight could still lead to patchwork quilt languages even today. – user17829 Jan 10 '15 at 15:30
  • 2
    @ChrisWhite The ideas behind TeX and C are very different. C was designed as a versatile programming language - TeX was designed as a typesetting environment. The former is by default designed for adaptation and expansion. – DetlevCM Jan 10 '15 at 18:07
  • 2
    I want to note that "simpler" does not always mean "shorter". Even to judge this, it takes some measure of experience. – Sean Allred Jan 10 '15 at 18:13
  • 24
    "Old" is probably better defined by comparing a language's date of origin to the date at which its genre began, rather than by comparing its origin to the present date. C was designed a long time ago, but it was not a pioneer in its niche of procedural programming languages. The pioneer in that niche would be FORTRAN. TeX was a pioneer in its niche of typesetting languages, and can be compared with later systems such as postscript, html, and mathml. – Ben Crowell Jan 10 '15 at 20:05
  • 7
    An opinion: just reading the goals of latex3 on the official web site is complicated. We need a pythonic-style stable (e.g. not as texmacs) document markup language to control an underlaying document preparation system (like tex). Compulsory indent to make source reading clear, simple level-1 commands, ... but 4 that, we need to collectively state the atoms of a current document, avoiding the pretext that latex should answer every problems of documents on Earth that results in the kludge latex is today. – sol Jan 12 '15 at 8:52

'complicated' - surely everyone can agree LaTeX deserves that adjective.

No, I don't really agree. I think it is fairly simple to use and personally I have always found that a WYSIWYG style editing interface (on the few times I have tried to use one) is much harder to use and less intuitive.

If you want to make a list in latex, you find a document and "view source" and find that it's

\begin{enumerate}
\item zzzz
\end{enumerate}

so once you are used to the \begin/\end environment concept (which is surely no harder than HTML's <ol> / </ol> element concept) a latex source file is pretty much self-documenting.

Now because latex is open source people modify it in all kinds of ways but the fact that it can be complicated to modify is rather different from saying that it is complicated to use. The reference in your question to standard programming concepts such as numeric types, subroutines etc. Means that you should be comparing programming functionality in Tex to (say) modifying the C++ sources of OpenOffice. It's different but not necessarily more complicated, but either are considerably more complicated than simply using the system to produce a document.

It's definitely true that the tex programming required to make a latex2e class is more intricate and less documented than would be ideal, which is something the latex3 project is trying to address, but that has little effect on most users of latex who can simply produce a document using a supplied class.

Many users use latex quite happily for decades without using any of these

Macro hell: tangled webs of junk (\relax, \csname, \let, \patchcmd, \expandafter, ...) sprinkled throughout all but the simplest macros

Similarly If you have "\makeatletter all over the place", you should ask why you have that, that is a hook to access code that the author has intentionally made hard to access from a document, so it it is not typical use it is inline modification of the code of the system, if such modifications are complicated, so be it.

  • 4
    You make important distinctions. I personally found package programming to be quite daunting (though we managed OK with your help, wouldn't you say?). But simply to use LaTeX to create content does not require the kind of complexity suggested by the OP. – Michael Grant Jan 11 '15 at 4:14
  • 1
    As my karma indicates I'm not ;-) but the StackExchange app featured this question and I was curious! I'm primarily over in Math.SE. – Michael Grant Jan 11 '15 at 12:19
  • 14
    I'm not sure that I buy this. True, LaTeX has very strong, intuitive support for certain expected types of document. But OP's comparison is to C++, not WYSIWYG. The biggest difference between LaTeX and an object-oriented language is not how easy it is to solve simple problems, but how the complexity of solutions scales with the complexity of the problem. The degree of context sensitivity and the occasional unexpected failure of macro nesting means than many complex problems in LaTeX are irreducibly so. I feel I had a better handle on C++ after 24 hours, than I have in LaTeX after 5 years. – DeveloperInDevelopment Jan 11 '15 at 14:16
  • 1
    @imsotiredicantsleep perhaps so but for producing a document (and the question is could a document production system be better) comparing with wysywig (or lout or roff or fop etc) is what counts. If you want to compare programming styles then you are not comparing something else, comparing implementing a typesetting system in C++ or in tex macros. – David Carlisle Jan 11 '15 at 14:32
  • 2
    @imsotiredicantsleep the idea that a typical author would find something with a form remotely comparable to C++ "simpler" than the current latex syntax seems somewhat bizarre:-) Such programming languages are very much a minority skill, a markup language should be for everyone. – David Carlisle Jan 12 '15 at 9:25

I think I can take a stab at this without being opinionated up to a point since I'm both a reasonably OKish TeX user (definitely not even close to TeXpertise) and I still think it is hard for anyone who is not actively participating in the development or answering with macro manipulations here or elsewhere.

I might rephrase your question as,

Why do we need to go down to the guts of TeX so often? Why is it so hard to design a consistent frontend in TeX?

This is due to, as far as I experienced with people I've helped with, three major and a couple of minor reasons.

  1. TeX as a language is weird. There is no other way around saying this. However much of this weirdness comes from the fact that it is an esoteric language or just obscure. There is no OO language that resembles TeX and at the same time also popular.

  2. People are not comfortable with moving arguments (in the sense of Dijkstra's rant about GOTO statement). That is to say, an expandable control sequence is a mystery for the programmer until it really expands to the surprise it includes. This makes it very difficult to learn the basics of TeX. Even to print what a control sequence holds you need \expandafters and \shows at the appropriate places. So debugging is very tough. And that is a major problem for the newcomer.

  3. This is probably the most relevant reason: The internet is full of contradictory or obsolete tutorials about TeX. There is no coherent way of doing something. Some people give closer-to-the-metal pure plain TeX macro solutions, some provide LaTeX package solutions etc. It's a huge mess. And unfortunately, many of these tutorials are from the 90s and 00s with which you cannot do much anymore if you combine newer packages. Also as you know, there are better practices that emerge in time Will two-letter font style commands (\bf , \it , …) ever be resurrected in LaTeX?, Are \( and \) preferable to dollar signs for math mode? and so on. Hence it is just a never ending confusion.

LaTeX3 project is a major undertaking to address these issues and it separates the programming and document level (I'm wildly approximating). That would hopefully bring some peace to the users such that many of the details you are mentioning would be swept under the programming level carpet.

I think the most important step towards fixing these issues would be solved relatively had we had an intermediate manual for LaTeX. So far either we have Hello World examples that goes up to the capabilities of whatever is available, or completely expert level hacking cookbooks. There is no mildly technical manuals for intermediate I can handle a few @ macros user. And that leaves the users separated into very distinct,

  • This is crazy, I hate it
  • This is crazy, I love it

groups.

  • 7
    I think your third point is the most important one. How often do we get to see code based on back-then-State-of-the-Art that is for todays standards just bad. A newcomer should have no need to use debugging stuff, if the great Google would sort current solutions on the top. – Johannes_B Jan 10 '15 at 12:28
  • 12
    hooray for #3. @Johannes_B is correct -- much of the "recommended" stuff out there is just plain wrong, as well as outmoded (and this includes stuff that i've written). but as for an "intermediate" manual, i'd like to recommend guide to latex by kopak & daly; it's not up-to-the minute (especially with respect to packages), but it covers the basics in a way that someone with not much experience can cope with, while providing a reliable reference for more advanced users when the need arises. – barbara beeton Jan 10 '15 at 13:31
  • 1
    @barbarabeeton It's kopka & daly. Took a while on google to find it. amazon.com/Guide-LaTeX-Edition-Helmut-Kopka/dp/0321173856. Pretty costly, though. – Ethan Bolker Jan 10 '15 at 15:39
  • 1
    @yo' haha come on. Who cares about the votes? You know that as well as I do. – percusse Jan 10 '15 at 23:54
  • 1
    @percusse Ok, then at least candidate for the TUG membership! ;) – boycott.se - yo' Jan 11 '15 at 0:05

You're looking at LaTeX from a programming point of view and claim, that compared to other programming languages it is hard to use.

In this "answer" I'm going to formulate a general statement on the aforementioned claim, then I'm going to comment on the points you listed as an example.

General

First of all one has to accept that LaTeX was never intended to be a programming language, but is designed to be a markup language. You define the visual appearance of certain elements and then annotate the document with markup command. The assignment of visuals to these markup commands is done using a macro processor, which turns out to have features found in common programming languages. People started "abusing" this macro functionality to cleverly automate parts of their document creation.

TeX was designed to do the ordinary tasks of typesetting: to make paragraphs and pages. But the underlying mechanisms that facilitate ordinary typesetting—e.g., boxes, glue, penalties, and macros—are extremely versatile; hence people have discovered sneaky ways to coerce TeX into doing tricks quite different from what its author originally had in mind. — Appendix D (p. 373) of the TeXbook

By today we have achieved awesome functionality by this, see tikz, beamer, KOMA-Script, etc.

TL;DR: LaTeX (and TeX) were never intended for programming, but people still do it.

Specific points from the question

I know some C++, so in the following I will compare your statements on TeX/LaTeX with C++.

  • Macro hell: tangled webs of junk (\relax, \csname, \let, \patchcmd, ...) sprinkled all over the place in all but the simplest macros

    C++: The first three you mentioned \relax, \csname, \let are so called primitives which can be compared to the base keywords in C++. If you look into a C++ library you will find, that all of the fancy stuff you're using (e.g. Boost) is built up by those ca. 30 base keywords such as for, return, if, class, etc. In TeX the behaviour is exactly the same: Everything is built up with those primitives.

  • The ridiculous \makeatletter and \makeatother all over the place

    C++: Macros containing an @ in their name are not intended for direct use by the author of a document. This can be seen as private members of a class which are also not intended for use by a third party.

  • Nonlocal error messages which can be difficult to fix

    C++: Ever used templates?

  • No straightforward types (int, bool, float) with the ordinary manipulation functions. Instead, a patchwork of different types of counters and registers, each of which have to be manipulated in their own special way (sometimes 2\mynum, sometimes 2*\mynum, sometimes \multiply \pgf@x by 2, sometimes \addtolength{\mynum}{3}, ...)

    C++: Here we come back to macro processor vs. programming language. In C++ the operators like *, +, etc. are part of the syntax and are interpreted by the compiler as their respective binary operation. In TeX the user might want to output *, +, etc. instead, because after all TeX is a typesetter. In TeX82 one had to fiddle with \advance .. by .. and \multiply .. by .. etc., but with the advent of e-TeX we obtained \dimexpr and \numexpr which simplify things by much. Furthermore TeX has int, bool and float (See code example Types in TeX).

  • Loops and conditionals are much more fiddly than they should be

    C++: This again falls into the category macro processor vs. programming language. In C++ loops and conditionals are part of syntax and operators like && or || have their meaning as boolean operators, whereas in TeX they are reserved for other things (typesetting vs. computing).

  • No arrays

    C++: First, this is not true, as arrays can be emulated or you can use pgf which implements quite sophisticated arrays and manipulation functions (See code example Arrays in TeX). Second, arrays are also emulated in C++. The array[index] notation is only syntactic sugar for pointer arithmetic interpreted by the compiler. In reality, if you do int array[10], the OS allocates memory for 10 ints and creates 10 ints in that chunk.

  • Checking for equality is ridiculously awkward (\equal{\mybool}{true}, ...)

    I admit that this is really annoying as TeX can only compare certain types (\ifdim, \ifnum, ...) or single tokens (\if, \ifx, ...). But with pdfTeX we have \pdfstrcmp so this is also no longer a problem. Also your example can be simplified tremendously by doing \newif\ifbool ... \ifbool true-code\fi

  • No straightforward subroutine syntax

    What about \def? Isn't the keyword for subroutines in some scripting languages (e.g. Python) also def?

  • Fixed memory limits rather than dynamically-allocated registers

    C++: I'm pretty sure C++ compilers also can run out of memory. The limits for TeX are just set rather conservative, due to its age.

  • No incremental compilation in most LaTeX engines - if I change the last line of my document, or make a tiny change to a TikZ figure, I shouldn't have to spend tens of seconds recompiling to see the effect

    C++: This claim only applies if you have independent objects which are changed and the only thing you need to do is recompile one object and link all objects together to an executable. Suppose you have a magic template which is used for the majority of your function across all objects. What happens if you change the template? Furthermore you could adapt the same behaviour in TeX. Put every part of your document in a separate file and include a global preamble in each one. Compile all your documents to PDF and concatenate all PDFs. If you then change one part you will only have to retypeset that specific one.

Types in TeX

\newcount\int
\int=2
\advance\int by -1
\the\int

\newif\ifbool
\boolfalse
\booltrue
\ifbool bool is true\fi

\newdimen\float
\float=1pt
\advance\float by 2.638pt
\the\float
\bye

Arrays in TeX

\def\set#1[#2]#3{\expandafter\xdef\csname\string#1#2\endcsname{#3}}
\def\get#1[#2]{\csname\string#1#2\endcsname}

\set\array[0]{abc}
\get\array[0]
\bye

Summary

Bottomlined I'd say that TeX/LaTeX is not hard to use at all from a programming point of view. Of course the syntax is very different from conventional programming languages like C++ and there are some quirks due to the completely different intentions of typesetting and computation.

  • 4
    I don't think I can agree with the not being a language claim. TeX is a full blown language (though for typesetting in mind). And I think you are really being pedantic about TeX with certain defensive attitude (that we all have to a varying degree). But C++ comparison is a little bit of overreach. Note that pgf arrays are macros in disguise similar to what you have. It hold arrays in a macro as text and access it via comma separation regex. C++ is a monster if compared with its memory allocations. – percusse Jan 10 '15 at 16:33
  • 6
    I don't think it's viable to claim that "LaTeX was never intended to be a programming language." We're talking about Donald Knuth here. Clearly he realized that what he'd created was a Turing-complete language. – Ben Crowell Jan 10 '15 at 19:36
  • 7
    @BenCrowell The first lines of Appendix D (p. 373) of the TeXbook state: "TeX was designed to do the ordinary tasks of typesetting: to make paragraphs and pages. But the underlying mechanisms that facilitate ordinary typesetting—e.g., boxes, glue, penalties, and macros—are extremely versatile; hence people have discovered sneaky ways to coerce TeX into doing tricks quite different from what its author originally had in mind." – Henri Menke Jan 10 '15 at 19:44
  • 3
    @HenriMenke Regarding the downvoter: somebody did not like any of the answers. So don't take it as an personal offense. – Keks Dose Jan 10 '15 at 19:51
  • 5
    While I enjoyed your detailed comparison with C++, I still have to remember my difficulties with TeX programming. I have mastered it to some degree, and I would still say that it is much more complicated than, say, C++: its lack of efficient data structures, its scoping rules which are inadequate for any programming task, its lack of builtin math... – Christian Feuersänger Jan 11 '15 at 17:36

If conventional LaTeX -- more precisely, pdfLaTeX -- doesn't meet your needs, I have two suggestions for alternatives that may work better for you:

  • If you're more of a user than a programmer and are mainly in need of a consistent interface to just about every package, consider using ConTeXt instead of pdfLaTeX. Its user interface is quite different from that of (pdf)LaTeX, but depending on how much you write, the switching cost may be worth it. ConTeXt is able to have a very consistent interface in part because it's been developed by a small group of persons who've exercised tight control over interface-related matters. (The latest version of the ConTeXt format is based on the LuaTeX engine, and hence the additional capabilities of LuaTeX accrue to ConTeXt users automatically.)

  • If you tend to program a lot of macros yourself and crave being able to work with typed variables and real functions (as opposed to setting up macros that "sort-of" behave like functions...), consider switching from pdfLaTeX to LuaLaTeX. LuaTeX is a superset of pdfTeX, and documents that compile correctly under pdfLaTeX should -- apart from having to apply a few minor changes that are related to input and font encoding matters and to font loading procedures -- compile correctly under LuaLaTeX as well. Importantly, LuaTeX and LuaLaTeX incorporate Lua as a full-fledged scripting language. Especially if you're familiar with Lua (or close competitors such as Ruby and Python) or C, learning how to write sophisticated functions in Lua and write simple TeX-side macros that interface with the Lua-side code should be a breeze for you.

  • 2
    I would use context, but tex4ht does not work with it. Which means Latex written in context can no longer be converted to html using tex4ht. This is none starter for many who like to convert Latex to HTML. – Nasser Jan 10 '15 at 15:16
  • 2
    @Nasser - I'm not a ConTeXt user myself. (Put differently, the pain of having to deal with varying package interfaces hasn't been too great for me...) However, I seem to remember that there's a pretty good ConTeXt-based method for creating XML documents. If that's correct, it shouldn't be too difficult either to create an html document directly from a document that's marked up in ConTeXt. – Mico Jan 10 '15 at 15:21
  • 5
    @Nasser The ConTeXt people have their own approach to HTML output based on the fact that ConTeXt MkIV is LuaTeX-only. There was a TUGboat by Hans Hagen about a the general area: tug.org/TUGboat/tb32-2/tb101hagen.pdf – Joseph Wright Jan 10 '15 at 15:29
  • Even after reading your meta post, re-reading the question and your answer, I don't see how this answers the question... :-/ – boycott.se - yo' Jan 10 '15 at 22:44
  • 1
    @yo' - It's an indirect answer: Instead of addressing any specific complaints, I chose to point out what I hope are viable alternatives to (pdf)LaTeX. In some important ways, ConTeXt and LuaLaTeX are both less complicated than pdfLaTeX is. – Mico Jan 10 '15 at 22:46

Here's my humble attempt to answering this question. Since David asked me in the chatroom whether my answer would include ducks, here's one for obvious reasons: Quack :)

Prologue

I personally believe that complexity is in the eye of the beholder. I commented this somewhere in this site, but IMHO it's worth mentioning again: at the end of the day, complicated constructs are a matter of taste and ideology; if you grew up accustomed to a certain construct or command pattern, there's a tendency for labeling different representations of the same logic as wacky or strange or excessively verbose. And, once again, I have the impression Maslow's hammer applies here as well: "I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail."

GOM

A macro is a rule or pattern which specifies how a sequence of symbols is replaced by other sequence of symbols. When you transform the occurrence of a macro into the resulting sequence, you have what we call macro expansion.

Let's see a macro in action (C code):

#define AGE 25

...

printf("The minimum age is %d.", AGE);

It is important to observe that AGE is not a pointer; during preprocessing, every and each occurrence of it in the source code is literally replaced by its content - it's a lexical replacement.

In general, what we have here is a lexical macro, which might occur and expand during the lexical analysis. We can have a syntactic macro as well, but that's another story. :)

A macro can be simple or parametric. The latter, as the name indicates, takes arguments in order to fill in the formal parameters according to the macro definition. I won't talk about syntax here because it adds no value at the moment. :)

So, as we can guess, a macro processor (or expander) finds macros in a sequence of symbols and expands them accordingly. Simple as that. Symbols that are not macros are simply reproduced verbatim. In other words, a macro expander only "sees" macros; everything else is "discarded". A very rough and naive workflow could be represented as the following FSM:

Quack

I'd add that this FSM is recursively called when you expand x through process(x). See the beauty in it? You always end up in searching for symbols, which only need to be reproduced verbatim, or macros, which are expanded. I think it's better with a concrete example. Let's try the following code:

\def\hello#1{Hello #1}
\def\myname{Paulo}
\hello{\myname}

Let's ignore the macro definitions for a minute and focus only on the third line: we found a parametric macro which is \hello, so let's expand it! We will end up with Hello \myname, so let's try our FSM on this sequence as well: Hello is processed as is, but \myname is yet another macro! Expanding it will give Paulo, so let's try our FSM on this sequence: Paulo is not a macro, so we simply return it as is; now back to our last last call, we have Hello Paulo which has no symbols left for analysis, so let's go back to \hello, which is correctly expanded to Hello Paulo.

In order to define macros, we need to use something. So let's introduce the concept of primitives, which are special language commands designed to help build new constructs on top of them. A primitive can define or redefine a macro, perform an integer operation, test conditional expressions, and so on. It depends on each language, so our mileage might vary.

Back to TeX. TeX is a macro expansion language, so it basically searches for macros and expands them when found. That's it. IMHO the concept is so simple yet so beautiful. It is like playing Pacman – there's nothing complicated about it: eat pills, avoid ghosts. :)

Did I mention Pacman?

Now, let's talk about LaTeX. Of course, there's much more to it, but what we have now is a whole bunch of new macros built from TeX primitives. These new elements aim at easing the TeX usage by supplying new ways of writing documents. For example, instead of writing

\par \begingroup \renewcommand \thefootnote {\@fnsymbol \c@footnote }
\def \@makefnmark {\rlap {\@textsuperscript {\normalfont \@thefnmark }}}
\long \def \@makefntext ##1{\parindent 1em\noindent \hb@xt@ 1.8em{\hss
\@textsuperscript {\normalfont \@thefnmark }}##1}\if@twocolumn \ifnum
\col@number =\@ne \@maketitle \else \twocolumn [\@maketitle ]\fi \else
\newpage \global \@topnum \z@ \@maketitle \fi \thispagestyle{plain}
\@thanks \endgroup \setcounter {footnote}{0}\global \let \thanks \relax
\global \let \maketitle \relax \global \let \@maketitle \relax \global
\let \@thanks \@empty \global \let \@author \@empty \global \let \@date
\@empty \global \let \@title \@empty \global \let \title \relax \global
\let \author \relax \global \let \date \relax \global \let \and \relax

you can now go with \maketitle. And things work.

Just a silly example on how things can be constructed on top of simple concepts: I wrote a very simple macro expander which could calculate the factorial of a number based on integer addition and multiplication. But my language doesn't have integer addition and multiplication, only integer increment and decrement operations. What did I do? :)

Behold the magic of composition of primitive recursive functions! Quack

Quack

Sum

  • Base case: sum (0, y) = y
  • Inductive step: sum (S(x), y) = S(sum (x, y))

Multiplication

  • Base case: mult (0, y) = 0
  • Inductive step: mult (S(x), y) = sum (mult (x, y), y)

Factorial

  • Base case: fact (1) = 1
  • Inductive step: fact (S(n)) = mult (S(n), fact (n))

If you guys think TeX syntax is complicated, I have good news for you: here is the code of my macro language which implements the operations above (my macro expander is available here, if someone wants to take a look at it):

Sum

\! define (\@ \wsum(\#x#\,\#y#\)w\ = 
    \w\q check condition (\$\% is zero (\&\*x*\&\) %\$\,
    \$\;y;\$\, \$\% increment (\*\| sum (
    \&\g decrement (\j\ixi\j\) g\&\, \&\iyi\&\
    ) |\*\) %\$\) q\w\@\) !\

Multiplication

\! define (\@ \wmult(\#x#\,\#y#\)w\ =
   \w\q check condition (\$\% is zero (\&\*x*\&\) %\$\, \$0$\,
   \$\% sum (\*\| mult (\&\h decrement (\u\vxv\u\) h\&\,
   \&\iyi\&\) |\*\, \*\iyi\*\) %\$\) q\w\@\) !\

Factorial

\! define (\@ \wfact(\#val#\)w\ =
   \w\q check condition (\$\% is greater than (\&\*val*\&\,
   \&1&\) %\$\, \$\< mult (\X\YvalY\X\,
   \X\;fact(\-\y decrement(\+\,val,\+\) y\-\)
   ;\X\) <\$\, \$1$\) q\w\@\) !\

My point here is: things are not complicated, they are the way they were designed. :) Take LaTeX3, for instance: they offer, amongst several things, CSV support out of the box, provided by high level commands built on top of TeX/LaTeX. Or get Heiko's hyperref where there's direct PDF manipulation. All built from the very simple yet powerful concepts discussed earlier.

IMHO LaTeX is not complicated. The question is, if you need something different for your code, you need either to use an existing package (someone wrote the code before) or provide the solution by yourself, like I did with factorial and my macro language. When the infrastructure does not offer what we need at the moment, we are completely free to implement it by ourselves. It's surely possible. :)

Mere expansions, my dears. Mere expansions. :)

  • 3
    Very elaborate for a beelike duck ;-) – Christian Hupfer Jan 11 '15 at 15:04
  • 1
    Will you be pitching A Game of Macros to HBO for their next original series? 10/10 TeX.SX users would watch. ;-) – Paul Gessler Jan 11 '15 at 16:56
  • 3
    @PaulGessler --- Will Danerys Targaryen and her dragons arrive before or after LaTeX3? – Ian Thompson Jan 11 '15 at 17:13
  • 2
    @PaulGessler, @IanThompson: added logo for educational purposes. :) – Paulo Cereda Jan 11 '15 at 17:18
  • 1
    @IanThompson I'm not sure, but maybe in the meantime there will be a PLOS ONE paper comparing the "efficiency" of writing screenplays in LaTeX vs. WordStar. – Paul Gessler Jan 11 '15 at 17:20

To understand the design of the current LaTeX (LaTeX2e) and what might be regarded as design lessons for the future, we need to look at the components and history of La(TeX). Some of this is covered in either other answers here or other answers on the site, but it seems most natural to treat the relevant items in one place. I want to cover this background first then move on to the specific points in the question.

Background: Layers

Working with LaTeX means understanding different layers of interaction. These layers may or may not imply different people being involved in the process or may be the same person: that will depend on the situation one finds themselves in. I am going to take the layers from what I regard as the 'top' to the 'bottom'.

The top layer to consider is that of document author. At this level, most of the input is structurally rather than visually oriented and as already argued by others at this level LaTeX is similar in ease of use (or otherwise) as other mark-up based input formats. (I would argue that LaTeX is similar to HTML and thus less dense than XML but more complex than Markdown, for example.)

\documentclass{article}
\begin{document}
Some text \emph{more text} \(y = mx + c\).
\begin{itemize}
  \item First item
  \item Second item
\end{itemize}
\end{document}

The layer below this is that for the document designer: broadly stuff that belongs in the document class (or the equivalent added to the preamble). The situation here is more mixed, at least in part because in LaTeX2e separation of this layer and the layers below is somewhat mixed. As such, I will deal with design and programming (the next layer down) together.

At the layer of programming LaTeX2e, it is important to keep in mind the difference between TeX and LaTeX. In particular, we need to think about the differences in design for these two parts.

TeX works using a macro expansion language which is Turing complete but which was not written to do general programming in that sense. Knuth wrote TeX driven by the desire to typeset The Art of Computer Programming properly. The language itself is therefore strongly tied to the requirements for typesetting, in particular the idea that control sequences should fit 'naturally' into a document. Knuth designed this system in the late 1970s, and the programming structures available in TeX reflect this. Knuth also anticipated that TeX documents would be relatively 'programming light': one can see this in for example the source of The TeXbook. [It's also fair to say that Knuth's approach is that each document should be independently written: plain TeX users tend to regard LaTeX's attempts to provide single structure on top of this to be counter-productive.]

LaTeX2e programming is made up of a mix of TeX primitives and a selection of macros added by a number of people. The LaTeX2e kernel (latex.ltx) is about 8000 lines long, and only a small part of this what one might regard as programming tools. That again reflects history: LaTeX was originally written in the mid to late 1980s, and when the current team took over in the early 1990s it was not realistic to add a large formal programming layer to LaTeX. Instead, the current kernel provides a somewhat limited set of such tools and relies on the use of TeX primitives for a large amount of programming. There are differences in approach between TeX primitive syntax and LaTeX2e macro syntax, and this is reflected in some of the interface design at this level.

One thing that LaTeX2e does, inherited from plain TeX, is to separate internal (programming level) commands from 'general' (document level) ones using the @ symbol in their names. Thus while not totally formalised in LaTeX2e, in general code inside \makeatletter ... \makeatother is 'programming' LaTeX rather than 'document input'.

It is worth noting that the LaTeX team is well-aware of the issues that a lack of totally 'clean' layer separation presents. Indeed, from the earliest days of the team maintaining LaTeX (early 1990s) there has been a desire to develop a clear programming layer which does not mix TeX primitives with LaTeX-provided macros. However, whilst this could be done in the 1990s the result was a system which was not actually able to carry out typesetting on real documents (lack of memory). Thus it has only been in relatively recent years that real steps have been possible in this direction.

Background: Stability

The above lays out the background to the structure of LaTeX2e but one might ask what decisions made in the late 1970s to early 1990s have on LaTeX today (2015). A key design element in Knuth's original design was the idea of archival source stability. Mathematical discoveries remain valid over time, and as such the text of publications does not 'age' in the same way it does in some other areas. Thus TeX sources from the early 1980s should ideally remain usable today with little or no change in the typeset output. (Some bug fixes do have an impact, of course.) This idea of stability has carried through into LaTeX: the design of LaTeX2e (released in 1994) was intended to allow older LaTeX2.09 documents to continue to compile despite some significant changes in the recommended interfaces.

Stability imposes significant restrictions on what can be changes in the LaTeX kernel. Over time, people have come to rely on many 'internal' details of the kernel, not just on the documented interfaces. This makes addressing issues within the current kernel very challenging. These issues do not mean that people have not addressed some of the programming questions for current LaTeX use, but these add-ons then can bring their own interfaces and thus potential confusions.

Specific concerns

Many of the issues raised in the question are focussed on the programming layer. I will not take each point in the question separately as some run together and because it is clear that some are examples.

  • 'Macro hell' It's difficult to know what to say here beyond 'TeX is a macro expansion language'. Commands such as \relax or \expandafter are TeX primitives, while \patchcmd is a macro which can be used to help with some programming tasks. This is simply how TeX is programmed: see below for possible alternative approaches.

  • Intermixing of programming into preambles This is what one often sees with \makeatletter blocks in document preambles. Whilst there are places where there are no good interfaces either in the kernel or in packages, most of the time there are better ways to tackle large-scale programming tasks in LaTeX, for example putting such code into a 'personal' package.

  • Variable types and syntax TeX provides macros and a number of register types. The syntax for manipulating registers at the primitive level is somewhat different from that used in LaTeX document syntax, and as such LaTeX provides its own interfaces for common 'document level' requirements in this regard. For example

    \newlength\mylength
    \setlength\mylength{10pt}
    

    is LaTeX syntax while

    \newskip\myskip
    \myskip=10pt
    

    is TeX primitive syntax. Often for programming it is useful to manipulate using the TeX syntax: as noted above, LaTeX2e does not provide a full programming layer of its own and this is one of the compromises made.

    In terms of the variable types available, TeX registers are available for integers (\newcount), dimensions (\newdimen), 'glue' (\newskip) and tokens (\newtoks). There is also a macro \newif for creating switches. Notably, there is no 'float' type. Knuth was writing TeX before the idea of a cross-architecture float type and wanted to ensure the same outcomes on different (mainframe) systems. As such, TeX uses integers internally even with for example dimension registers (which are represented as values in pt). Moreover, for the task of typesetting there is no need for floats, certainly not beyond what can be achieved using dimensions. Again, see below for alternatives in this area.

  • Programming structures Loops are implemented in TeX and LaTeX using the syntax \loop ... \repeat, while conditionals (normally) use switches created using \newif. As a macro language, parts of a process can be divided up by creating separate macros using \def/\newcommand.

  • 'String' comparisons As with other areas, classical (La)TeX programming doesn't really use the idea of text-only ('string') comparisons a lot. These are normally done at the TeX level using

    \def\tempa{<text>}%
    \def\tempb{<other text>}%
    \ifx\tempa\tempb
      ...
    

    This is provided by the ifthen package wrapped up as \equal. With a modern TeX system, the primitive \pdfstrcmp (or an equivalent) is available and a 'string' comparison can be made. At the primitive level

    \ifnum\pdfstrmcp{<text>}{<other text>}=0 %
      ....
    

    ('Strings' are not something TeX works with: it's all about token lists.)

  • Memory For almost all typesetting tasks there is no need to worry about memory on a modern system. Changing the memory allocation in TeX from fixed to dynamic is non-trivial and as it's almost always not needed it's only been done in LuaTeX (where as detailed in What are the incompatibilities of pdftex, xetex and luatex? other things have been done to break back-compatibility). If you are running into memory issues, almost certainly you've got an infinite loop or similar.

  • Recompilation There is no easy way to be sure that changing one thing in LaTeX input won't change the entire document. As a macro language, any piece of input could completely alter the interpretation of following code. Simply removing a word from a sentence can alter line breaking, which could knock-on to affect page breaking and thus the entire set up of a document.

Programming alternatives

As mentioned, the current mix of TeX and LaTeX programming conventions in LaTeX2e is a compromise that was necessary to allow LaTeX to work at all when it was released. The team have for many years been working on a programming layer, expl3, which is intended to be self-contained and to provide a range of tools. This does address some of the complexities of programming LaTeX but of course is still based on the underlying macro expansion basis: as such, it may or may not be viewed as 'too complicated'.

LuaTeX offers the Lua scripting language built-in, and this can be used to program outcomes in a more 'modern' sense. One can write a lot of code in Lua, as is for example done in ConTeXt. There are though still complexities in the need to have interactions at the typesetting level.

Looking more widely, as detailed in Alternatives to LaTeX there are non-TeX based approaches to programming-based typesetting. I'd point in particular to the Patoline answer, as this picks up an idea several people have in one way: reading the entire document into a more structured form which is then typeset using a 'modern' language. The question with these systems is partly one of take-up (LaTeX is widely used: they have to deliver a lot to displace it) and partly one of 'edge cases' (can such approaches tackle cases where in (La)TeX one would 'drop down' to the macro level to alter behaviour).

In order to understand the complexities of programming TeX (I am using the word TeX to denote all its related engines and formats) we need to keep in mind that people have some thousand of years of accumulated tradition about how documents should be printed to satisfy esthetic and utilitarian criteria. With that much of history, there is a rich collection of examples, and people are just as prolific in inventing new styles now as they ever were, so there seems to be no limit to the expectations for document preparation systems. What defines a document is also rapidly evolving.

Furthermore, every user of LaTeX is an “expert” in what his or her document should look like. As the output is visible, it can readily be compared against some physical or mental image. To an occassional user this immediate feedback, is different to the reaction of an occassional user to a new programming language, for example Haskel, its monads and other concepts that might be unfamiliar with.

A basic misconception as to what TeX is, stems from the fact that most users of TeX do not spend an adequate amount of time to understand the requirements for a Typographical Engine and the solution that TeX solved using, glue penalties and boxes. To any programmer the 250 basic commands of TeX and at least the 60 parameters make no sense, until they spent the necessary time to understand what typography is and TeX’s basic typographical model.

User Programming Interfaces: What does the user have to face?

One of the rivals of TeX as a typesetting engine---and perhaps its only only rival---is Adobe’s InDesign, which of course comes with a Graphical User Interface, bells and whistles, a price tag and no guarantees for backward compatibilities. Scripting it is another story. Here is an extract in JavaScript to set up parameters for a text box. These settings take more than two pages in the example and I am just providing a fragment of the code to give you a taste of what is involved.

var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var myTextFrame = myPage.textFrames.add();
myTextFrame.contents = "x";
var myTextObject = myTextFrame.parentStory.characters.item(0);
myTextObject.alignToBaseline = false;
myTextObject.appliedCharacterStyle = myDocument.characterStyles.item("[None]");
myTextObject.appliedFont = app.fonts.item("Minion ProRegular");
myTextObject.appliedLanguage = app.languagesWithVendors.item("English: USA");
.
.
.
myTextObject.capitalization = Capitalization.normal;
myTextObject.composer = "Adobe Paragraph Composer";
myTextObject.desiredGlyphScaling = 100;
myTextObject.desiredLetterSpacing = 0;
myTextObject.desiredWordSpacing = 100;
myTextObject.dropCapCharacters = 0;

If typing:

myTextObject.appliedFont = app.fonts.item("Minion ProRegular");

is more intuitive than:

\setmainfont{Minion Pro Regular}    

is highly debatable.

Of course the complexities of a modern and more capable typographic engine, requires tremendous efforts, especially in incorporating OpenType fonts which are themselves programs rather than static tables. A look at the HarfBuzz or ICU Engine code repositories can give you an idea of the magnitude of programming effort required.

Programming TeX/LaTeX comes in flavors and one needs to distinguish between document settings, the mark-up language, the presentation language, the page description language and the scripting language. I will deal with each one separately.

Document Settings

One has to differentiate about settings and programming. For example a setting can modify a documents main font, where programming LaTeX to offer a facility to deal with fonts is a much different task. My own efforts currently is to provide such a facility that can virtually transform documents from one style to another.

Mark-up language

The requirements of good typesetting of complex documents, such as those normally associated with TeX cannot be reasonably carried out using a GUI. For us TeX users our documents are the GUI and LaTeX type mark-up is almost by now a de facto standard for human produced documents. XML and its ugly sister HTML is really for computers.

Presentation Language

By presentation language, I mean the language such as those used in a LaTeX preable or CSS for HTML. In many aspects these languages also need to be turing complete.

Scripting or Writing Extensions

The OPs question dealt mostly with this aspect, and the valid in many respects criticism picked up on the name and syntax on the more esoteric commands of TeX’s language. For example \@makeatletter and \@makeatother. Of course (since you are writing in a document) you need to tell the Typesetter that some of the letters in your program are special. This is not unusual in computer languages.

Here TeX’s way of saying \catcode@=11or\catcode@=12 is perhaps a better choice? or you can mould it into \begin{script} and \end{script}? I am not sure. One when learning to program tends to adopt to the idiosyncrancies of the computer language rather the other way around. Programming in Haskell for example is much more different than C, and even the machine you are programming in can leave traces of its idiosynchrancies in the code itself.

Can we do better?

Before delving into the topic deeper, I would like to suggest that the “persona” of a LaTeX user needs to be defined. Who are the likely users? Of course suggestions in other posts that your grandmother cannot use it, or the typical user needs to open it and start typing are irrelevant, as in my opinion the typical “persona” of a LaTeX user is a person with a good background with a University Degree or equivalent experience or a student studying for higher degrees, computer scientists, mathematicians and the like.

As I mentioned earlier, I do not think the syntax is a hindrance, but some of the limitations of TeX are showing and yes we can do better with newer systems.

  1. Improvements in mark-up commands and a simpler interface in programming presentational aspects of a document are possible within the current system.

  2. Output routines. TeX as it stands cannot produce automated documents that flow text from on box to another, especially across pages; other limitations are multicolumn documents with assymetric columns, the flowing of figures in such layouts and the production of document designs based on spreads rather than pages. (I am writing this with extreme caution as David Carlisle will probably prove me wrong).

In modern computer lingua the above requirement is a 'pluggable' design for output routines.

  1. Most programs are piped into other programs. For example TeX outputs into a dvi file and another program does further processing. TeX's format of the dvi file is very difficult to use further down the line. For example it does not mark the end of lines.

The most promising system currently is the Lua interface. Conceptually one can intercept TeX's processing and carry out complex transformations.

Before anyone contemplates any re-write the reasons as to why TeX survived for so long and still competes so well with rival software needs to be analysed. In my opinion it was its adaptability, a successful and very well thought typographical layout engine, the fact that it does require study before coding, therefore attracting people that have develop the abilities to provide high quality extensions via packages. There are many other reasons and this site has many examples. Wiping out all this code and starting from scratch will present many difficulties. I started with a slide rule and have seen a lot of software come and go, TeX, Unix, Lisp and C will outlive me. Perhaps also Emacs! We can do better yes, but simpler no.

I'm using TeX now for about two years, and I agree it's difficult. It is even more difficult to persuade others to start using it. On the other hand, I can't see any alternative giving me the same flexibility and possibility's as LaTeX. Being a very very experienced WORD and math type user for more then 20 years, after discovering LaTeX I never use those programs anymore. When I have problems typing something in LaTeX, I'm always searching on this site, and it never let me down. Starting to look on different sites gave me problems. LaTeX becomes more and more difficult if you start interfering with the layout of LaTeX, and THAT was just the start of LaTeX. Just focus on the content...

  • 2
    I do not see how this post attempts to answer the question. The fact that the question is subjective (and therefore it's difficult to write a good answer to it) does not mean, in my opinion, that the answer should show the same level of quality. – boycott.se - yo' Jan 10 '15 at 21:48
  • I can agree with your opinion about this. But the meaning of my answer was more. Is it difficult or do we make it difficult the better we come. When I was reading the very start of Donald Knuth: TeX was designed with two main goals in mind: to allow anybody to produce high-quality books using a reasonably minimal amount of effort, and to provide a system that would give exactly the same results on all computers, at any point in time. It really is in that idea that I think the answer is an answer... – Arne Timperman Jan 11 '15 at 9:27

I can not judge whether TeX is difficult from a programmers point of view. I'm a user with a minor knowledge by far. But if you publish a software for typesetting scientific articles, there will be such users.

My assumption why TeX is so hard to use for people like me: Because it has been designed without the faintest idea of such users. Which is quite often the case with open source software and the weakest point of the whole idea.

Writing a software from both sides -- creating a solid technical base for decades while resisting the temptation to dive into complexity and to accomodate the users need of an intuitive way to use it -- seems a non trivial problem.

For this reason I really appreciate the development of KOMA-script: Markus Kohm created a more and more intuitiv set of commands for users. If more people thought about how to make their package easier to use, we were much better off.

But this is hard work, without the fun factor of creating something new.

  • 4
    It's been said that Don Knuth was motivated to create TeX and Metafont in the mid-1970s because the TAOCP trilogy needed to be reprinted. (The first edition had been typeset using rapidly obsolescent hot-metal technology, but the second edition was not -- and was a typographic disaster.) If that's the case, I suppose one should not say that TeX was created without a (very specific!) user in mind. Of course, some methods for inputting documents and reading them are quite different today from what they were 40+ years ago. It's unfortunate that TeX hasn't stayed in touch with modernity better. – Mico Jan 10 '15 at 16:00
  • 2
    @Mico: This seems obvious when you consider the chatty, 'interactive' error messages. How many people want to hold a conversation with a computer program that refers to itself as 'I' :-) – jamesqf Jan 10 '15 at 19:09
  • @jamesqf - My comment was directed at KeksDose's observation that TeX was designed "without the faintest idea of users". Incidentally, my hunch is that nobody wants to hold a conversation with a computer software, regardless of how the program addresses itself ("I", "we", "your humble servant", or anything else). – Mico Jan 10 '15 at 19:26
  • @Mico -- not only has "it been said", but knuth himself says that this was the reason. reference: Mathematical Typography, the published version of knuth's 1978 gibbs lecture, starting at the bottom of p.351. – barbara beeton Jan 10 '15 at 20:15
  • Thanks, @barbarabeeton. I didn't have this piece at hand when I wrote my comment, so that's why I chose the indirect locution. In hindsight, doing so may not have done much good. – Mico Jan 10 '15 at 20:20

protected by Ian Thompson Jan 11 '15 at 13:11

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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