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

ewlength\mylength \setlength\mylength{10pt} is LaTeX syntax while

ewskip\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 (

ewcount ), dimensions (

ewdimen ), 'glue' (

ewskip ) and tokens (

ewtoks ). There is also a macro

ewif 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

ewif . As a macro language, parts of a process can be divided up by creating separate macros using \def /

ewcommand .

'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).