77

I've seen many programmers here at tex.se, and I'd like to know how they view TeX/LaTeX as a programming language in relation to other languages, and whether it would boost my progress as a beginner using other (non-typesetting related) languages, that is of course in an abstract or semantic sense.

15
  • 44
    I don't think that learning TeX/LaTeX will help you much with learning other programming languages as TeX/LaTeX has it own very unique issues, but knowing other programming languages and basic algorithm development will help you with TeX/LaTeX. Commented Jan 29, 2012 at 23:09
  • 2
    Well, TeX is really extremly strange programming language, mainly because nowadays "most-used languages" (don't catch me on this word) are mostly concerned of objects which are special types of variables, whereas TeX is concerned on a "flow of data and commands".
    – yo'
    Commented Jan 29, 2012 at 23:14
  • 3
    @PeterGrill Well you see, the first time I tried making a very small program in c++, it took a long while to understand the notion of calling certain libraries. It was latex that made me understand through \usepackage. Commented Jan 29, 2012 at 23:17
  • 6
    I find it a bit weird that people like to confine languages into one or the other programming paradigm, and while there are languages which takes that line of thought to the extremes (eg ruby for "purely" OO, haskell for "purely" functional, etc.), I believe most languages are multi-paradigm where you can choose a programming paradigm best suited for the problem at hand. @Ryan: check out lambda.sty; it would be interesting IMO to see through the use of that for problems apt for it.
    – morbusg
    Commented Jan 30, 2012 at 9:33
  • 2
    @AymanElmasry: You should accept an answer to this question, I think. I wouldn't mind if you accepted mine, but actually, it seems that I would get a gold badge if you accepted someone else's :)
    – Ryan Reich
    Commented Mar 1, 2012 at 22:36

8 Answers 8

154

My not-oft-enough-expressed opinion is that TeX is a terrible programming language and that anyone learning to program is well advised to avoid learning anything from it. In fact, it is much more helpful to have experience programming in order to write TeX than the opposite. Various points major and minor come to mind:

  • When writing TeX, one has to pay entirely too much attention to the exact characters in the code, up to and including newlines (!) and individual spaces (!!), which both affect its behavior subtly. This means that lots of effort goes into doing something which isn't even algorithmic.

  • Speaking of the input format, because of catcodes, it is entirely fluid. The example in this answer is extremely interesting, in sort of the same way that an okapi is interesting. So even if you think you know TeX's syntax, you (probably) only know the syntax of the plain TeX format. Or of LaTeX. Or of ConTeXt.

  • TeX is a macro language. That means that by design, its code is self-modifying, which is up there with the goto statement in terms of damage to program structure for the reasons given by Dijkstra in that article.

  • However! TeX is not a macro language, because its directives ultimately expand to typesetting primitives. This fact is prominently advertised in the TeXbook in describing TeX's modes of operation as the "eyes", the "mouth", and the "stomach"; it's the mouth that's the macro language. The aforementioned issues with input format are the "eyes"; the typesetting part is the "stomach". Except, of course, when it is not just the typesetting, for example the execution of \def directives.

  • If you read this site, you'll occasionally hear people talking about "fully expandable"; by this they mean code that is processed only in the mouth (as macros). It is not really known why this distinction exists, but as with many aspects of TeX, it may just be an artifact of its age. This is not a good advertisement for learning a programming language, all other things being equal.

  • TeX doesn't actually have programming constructs like variables or loops or conditionals. It does have registers and the \loop...\repeat construct (which works by a clever manipulation of self-modifying code) and it does have a fixed number of builtin \if's, but in general you will find yourself writing an ad-hoc, informally specified, and bug-ridden implementation of half of Common Lisp (or, since I don't actually know Lisp, perhaps I should say "of half of C"). Don't think you'll learn anything this way, other than bad habits. Unless you already know the structures you're trying to invent you will end up with spaghetti code.

  • The constructs that do exist are mostly not expandable, despite the fact that the part of TeX that constitutes a programming language is by definition the purely expandable part. The fact that some of them are expandable leads to very obscure tactics, such as the one described in this question and its answers. It is probably not reasonable to ask programmers to worry about the code branches of an if statement actually interfering with the branching code itself.

  • TeX has no concept of functions, which is one of the few things that imperative and functional languages agree on. Its macros do absorb "arguments", but because of the tricky expansion issues inherent in the macro language, those arguments are not always what is written in the code. And even if they are what's written, because of the tricky argument-grabbing issues they are still not always what (you think) is written.

  • Strangely, despite the crucial importance of things such as braces to the functioning of TeX, and despite the fact that it is a Turing-complete language, and further despite the fact that the exact format of its input is crucial to its functioning, there is no native way to easily do something like determine (expandably, of course) if the next character is a brace! See Bruno Le Floch's comment to this answer. This is actually a good lesson on the difference between "Turing-complete" and "can do anything", so in that sense, is a valuable part of one's programming education.

  • It has no debugging facilities to speak of. It does provide the ability to trace code, but this can't be controlled finely and doesn't always reveal crucial facts like "What values do all those variables have right now?". Assuming you can tell what the variables are, that is, since they are probably macros just like the "functions".

Essentially, programming in TeX is an endless parade of frustration over minutiae concerning code format, multiple rounds of parsing and subsequent (possibly partial) execution, and poorly defined program state. Although it's true that "only perl can parse Perl", at least this is true of Perl because of the overwhelming plethora of programming styles and facilities it makes available (including, yes, the ability to modify its own syntax). In TeX you can have a hard time getting it to do addition.

14
  • 6
    Agreed. The day I first implemented an if statement that tested more than one Boolean value was the day I realized what a horrible programming language TeX can be. Sometimes TeX is great, sometimes it is a Turing Tarpit.
    – Sharpie
    Commented Jan 30, 2012 at 5:50
  • 27
    It is a total Turing tarpit. I don't know why brainfuck is supposed to be such a big deal there; TeX did it earlier and far worse.
    – Ryan Reich
    Commented Jan 30, 2012 at 6:31
  • 8
    Also: 38 upvotes? Wow. So many people on this site hate TeX :)
    – Ryan Reich
    Commented Jan 30, 2012 at 18:18
  • 24
    Well, as a programming language it’s bloody awful, but as a typesetting system it’s quite alright ;-)
    – Psirus
    Commented Jan 30, 2012 at 19:48
  • 12
    @Jubobs Unfortunately, while Python's whitespace enforces coding style, TeX's inhibits it: the more space you add, the worse it gets. Safe TeX style is to write everything in an unintelligible stream, except of course for the spaces that are necessary to make it parse numbers expandably and correctly.
    – Ryan Reich
    Commented May 12, 2014 at 23:34
44

This is more of a long comment rather than an answer.

TeX is an excellent source of learning programming. It tells you how not to write code! One of the basic tenets of programming is that you should write code that is easy to read by others. I find that a lot of TeX code, especially TeX macro code written during the early days of TeX, is impossible to read. Part of the reason is the idiosyncrasies of TeX, the macro language. But a bigger reason is the horrible macro naming convention used by macro authors, especially using @ in the middle of variable names.

As an example, consider the macro \overset and \underset that are part of the amsmath package. They are defined as

 \newcommand{\overset}[2]{\binrel@{#2}%
  \binrel@@{\mathop{\kern\z@#2}\limits^{#1}}}
\newcommand{\underset}[2]{\binrel@{#2}%
  \binrel@@{\mathop{\kern\z@#2}\limits_{#1}}}

where the helper macros \binrel@ and \binrel@@ are defined in amsbsy.sty:

\def\binrel@#1{\begingroup
  \setboxz@h{\thinmuskip0mu
    \medmuskip\m@ne mu\thickmuskip\@ne mu
    \setbox\tw@\hbox{$#1\m@th$}\kern-\wd\tw@
    ${}#1{}\m@th$}%
  \edef\@tempa{\endgroup\let\noexpand\binrel@@
    \ifdim\wdz@<\z@ \mathbin
    \else\ifdim\wdz@>\z@ \mathrel
    \else \relax\fi\fi}%
  \@tempa
}
\let\binrel@@\relax

The above code would have been much easier to read, if the two macros were named \checkmathbinrel and \usemathbinrel (or something similar). Then, one could read the code to understand the intent of the macros.

Note: I do not mean to criticize the authors who wrote the code. I understand that the code was written at a time when computational efficiency was more important than readability.

Modern TeX code, whether written in LaTeX3 style or in ConTeXt style is much easier to read. For example, this is how the same macros are defined in ConTeXt:

\def\math_binrel_apply#1%
  {\begingroup
   \setbox\scratchbox\hbox
     {\thinmuskip   0mu
      \medmuskip   -1mu
      \thickmuskip -1mu
      \setbox\scratchbox\hbox{$#1\mathsurround\zeropoint$}%
      \kern-\wd\scratchbox
      ${}#1{}\mathsurround\zeropoint$}%
   \ifdim\wd\scratchbox<\zeropoint
     \endgroup
     \expandafter\mathbin
   \else\ifdim\wd\scratchbox>\zeropoint
     \endgroup
     \expandafter\expandafter\expandafter\mathrel
   \else
     \endgroup
     \expandafter\expandafter\expandafter\firstofoneargument
   \fi\fi}

\unexpanded\def\overset#1#2%
  {\math_binrel_apply{#2}{\mathop{\kern\zeropoint#2}\limits\normalsuperscript{#1}}}

\unexpanded\def\underset#1#2%
  {\math_binrel_apply{#2}{\mathop{\kern\zeropoint#2}\limits\normalsubscript  {#1}}}

Notice that proper indenting and expressive variable names make the code much easier1 to understand (perhaps at the cost of efficiency).

So, if you read a lot of TeX code, you will come across the same macro written in different styles. You can compare the two implementations to understand how to write readable code.


1: The \edef\@tempa{\endgroup ...} \@tempa trick, or the {\begingroup ... \engroup \expandafter ... \fi} trick are standard part of TeX programming.)

5
  • 14
    To my eyes, these examples are just degrees of badness. \expandafter\expandafter\expandafter my behind. Commented Jan 31, 2012 at 15:15
  • @MichaelPalmer: I am not sure how \expandafter\expandafter\expandafter is any worse than \edef\@tempa{\endgroup...}. In either case, my point is more in term of naming of variables and proper indentation. Even if you were to use the \edef...{\endgroup...} form, then, \@tempa is just horrible variable name. Something like \current_math_binrel would be better.
    – Aditya
    Commented Jan 31, 2012 at 19:15
  • 2
    Well, in my limited experience, a major part of why the naming is bad is that TeX has limited support for locality. There is no lexical scoping, so you cannot do {\def\helpermacro{...}\gdef\macro{...\helpermacro...}}, since \helpermacro needs to be in the current scope when \macro is expanded. This makes it necessary to make way too many things global, which along with a lack of a namespacing mechanism leads to obscure naming to prevent clashes.
    – Witiko
    Commented Sep 10, 2016 at 15:40
  • @Witiko: you can do \xdef for expanding \helpeemacro
    – Aditya
    Commented Sep 10, 2016 at 19:22
  • 2
    That I can. But perhaps I do not want to expand \helpermacro right away, since there are side effects.
    – Witiko
    Commented Sep 10, 2016 at 23:34
43

(This is another long comment along the lines of Aditya's answer.)

Yes, it can help you understand other languages (in a theoretical sense).

And for all the reasons that Ryan gives.

In mathematics, we're always on the look-out for the counterexample, the outlier, the slightly-odd-thing-that-still-satisfies-the-definition. Indeed, we have whole books whose titles are "Counterexamples in X" which are among the "must have" books on people's shelves. We believe that to truly understand a concept, you have to take it to its extreme and examine what happens there - it's not enough to understand the safe, cosy examples that motivated the concept. So we learn about the empty set, discrete metric spaces, non-Hausdorff manifolds, non-separable Banach spaces, the field-with-one-element (aka F_un), and many, many similar things. We do so not because we seriously want to study them, but because if we really want to understand what the statement "S^3 is a smooth manifold" means, we also need to know about the weird examples.

If all you ever want to do is learn one programming language and never be curious as to why it works the way it does, then don't bother looking at TeX. Regard it as Magic and forget about it. But if you truly want to understand what programming is about, and learn what it can really do, then you really should look at TeX because there is nothing quite like it.

Where I'd start is by looking at TeX from the point of view of its purpose (I'm extrapolating back here, I've no real knowledge about its beginnings). It is a programming language embedded into a document typesetting language, and the latter is the dominant part. So the programming language has to hide itself most of the time, which is one reason why spaces and new lines are more significant than in other languages: they are significant in the document typesetting part.

The other main unique feature of TeX is that most of its users are not programmers, and would never wish to be. So, again, its design takes that into account. A writer would expect \emph{hello} to "do what it says on the tin", and \alpha to mean "I want an alpha character right here", so expansion - rather than function calls - is closer to what the average user expects.

(But I'm no expert, and definitely not a programmer. So maybe my view is tainted by my programmatic development.)

2
  • 16
    Your nickname for TeX—"Counterexamples in Computer Science"—needs to be prominently featured on the site. :-) Commented Jan 30, 2012 at 12:56
  • +1! Though I would say that this is an excellent argument to learn TeX after learning another language, so you can reflect on it. Still, knowing it has been of great value to me in understanding the execution of algorithms, if not necessarily their clear and elegant description.
    – Ryan Reich
    Commented Jan 30, 2012 at 18:30
21

The answers so far have been fairly negative, but let me try to offer a little bit of positive spin on this. I have, in the past, tried to teach a variety of people a little bit of HTML. If they already used LaTeX, then they were already familiar with the idea of a markup language. This made things much easier. Then you can just say "Look, <i>…</i> just works like \textit{…} does. (I say LaTeX specifically, because that's what people I've talked to use. I don't know if plain TeX or ConTeXt users are any different…)

And then you can use the idea of using titlesec or a similar package to modify the title font as a way of introducing the separation of form and content that the divide between HTML and CSS is supposed to effect. (Obviously, in both cases the separation is far from complete, but still…)

So while HTML is also a fairly specific language (arguably not a programming language at all) but a familiarity with LaTeX does help in learning it.

What doing this has taught me is that most people who use LaTeX use it very badly: \section*{\it 4. Conclusion} for example. It seems like LaTeX offers so many different ways of intervening, at different levels, to produce the same or similar output. So you don't get the corrective of seeing your "program" fail often enough that you are forced into the right kind of practices. For example, python forces you to indent properly. (I actually hate semantic whitespace, but it does at least instill a good practice when beginning).

3
  • To reiterate what you've said; since LaTeX is considered more of a mark-up language, people might argue that your statement applies only to HTML. I think even python allows bad practises; like dynamic types for instance. Commented Jan 30, 2012 at 13:05
  • @AymanElmasry Yes, if you think of LaTeX as a markup language, then it's OK. But once you realise that TeX does allow for conditionals (and is Turing complete) then it doesn't look good as a general programming language.
    – Seamus
    Commented Jan 30, 2012 at 13:27
  • 4
    +1 for "most people who use LaTeX use it very badly". So true.
    – Ryan Reich
    Commented Jan 30, 2012 at 18:31
20

In 2004 Victor Eijkhout taught a course of Computer Science based on TeX as a programming language. This year he published the course notes (see http://www.lulu.com/product/paperback/the-computer-science-of-tex-and-latex/18798879). I recently bought this book and I am going to write a review for TUGboat. My initial impression from this book is that TeX as a language indeed gives you a valuable insight in many aspects of CompSci and programming.

2
17

This is an interesting question.

I agree with Peter's comment - LaTeX is not a good medium for learning about programming in general, but proficiency in other languages will help you understand LaTeX better. A good language for self-study and experimentation is Python.

The bad news is that working with a concise, flexible, powerful language such as Python will make you realize how incredibly verbose, arcane and crippling programming in TeX and LaTeX actually is. It has been said about Perl that it 'makes simple things simple and hard things possible'. About TeX, it would be fair to say that it makes simple things hard, and hard things virtually impossible.

The good news is that there now is LuaTeX, which allows you to implement all the heavy-lifting inside your own macros in Lua, which is similar to Python in spirit and also in syntax. LuaTeX means that, if you decide to study Lua, you will be rewarded with very real and immediate benefits for your work in TeX and LaTeX.

0
5

If you're looking to acquire good programming practices, TeX may not be the best choice, as others have mentioned (the expl3 package aims to correct this, but I don't have personal experience with it). However, if used judiciously, TeX can be a good programming language for learning the foundations of computer science.

The mathematical study of computer programs is couched in the language of Lambda Calculus. TeX lends itself naturally to implementing Combinatory Logic, which is an equivalent formulation of Lambda Calculus. Combinatory Logic's primitives are the operators

  • I, the identify operator, which operates on the next token, transforming it to itself. I's defining formula is (I x) = x. In TeX

    \def\I#1{#1}
    
  • K, the constant-function generator, which operates on the next token, x, transforming it to an operator that always returns x. K's defining formula is (K x y) = x. In TeX,

    \def\K#1#2{#1}
    
  • S, the application operator, whose defining formula is (S x y z) = (x z (y z)). In TeX,

    \def\S#1#2#3{#1#2{#2#3}}
    

As such, TeX's closest relatives in the world of computer languages are the family of functional languages, such as Lisp and Haskell, since they are modeled after Lambda Calculus.

However, even in this capacity, TeX is not without its quirks, for instance an empty line will automatically insert a \par token into the input stream (but you can avoid this particular problem by starting your scripts with \endlinechar=-1\relax).


By the way, chapter 5 of the book mentioned in Boris's answer is an introduction to doing Lambda Calculus in TeX.

5
  • 1
    Though this may sound fine in theory, in practice TeX's expansion cannot “be seen as a general-purpose string rewriting system” for some of the reasons mentioned in Ryan's answer: sensitivity to spaces, and mostly (IMO) the fact that TeX considers expansion as some sort of distraction from its main work of typesetting, to which it will revert at the earliest opportunity. Even if you were an expert at programming in a string-rewriting system or combinatory logic, when you encountered TeX you would still be taken aback. Mostly I'd say: its creator did not intend it for much programming. Commented Sep 1, 2017 at 14:00
  • @ShreevatsaR: Full fledged TeX has many quirks, but you can, if you want to, restrict yourself to using only those aspects of the language that you find desirable. Specifically, if you wish to use it as a combinatory-logic engine, you can restrict yourself to only using \def, control-sequences, \csname...\endcsname, { and }. If you do so, there are no quirks, and whitespace can be used liberally. You can then amp it up, if you wish, by judiciously adding to your vocabulary some programming-related primitives, say, \expandafter, \noexpand, \ifcase, \futurelet, token registers.
    – Evan Aad
    Commented Sep 1, 2017 at 14:15
  • @ShreevatsaR: In hind sight, maybe \noexpand is not such a great idea to add to your vocabulary, and if you use \csname ...\endcsname you have to include also \expandafter in your basic vocabulary, but you can give up \csname ... \endcsname if you're willing to settle for control-sequence words (i.e. those control-sequences, whose name consists only of the letters of the alphabet).
    – Evan Aad
    Commented Sep 1, 2017 at 14:26
  • @ShreevatsaR: Actually, whitespace cannot be used liberally even if you only use control sequences, since an empty line will automatically insert the token \par. So yeah, it's not an ideal language...
    – Evan Aad
    Commented Sep 1, 2017 at 14:52
  • 1
    @EvanAad See expl3 ;)
    – Joseph Wright
    Commented Sep 1, 2017 at 15:49
2

Latex, in my opinion, could be used as a very rich primer for understanding declarative programming. You layout the structure and content of a document declartively and have it rendered to eps or pdf. Even though the language has differences to mobile application frameworks such as as the Android/IOS sdk or web application development using html, css and javascript it presents the coder with the same paradigm of thought used within these contexts.

An appreciation for programming design principles, such as Separation Of Concerns which encourages modular reuse of code blocks is also an advantage of LaTex programming when separating books into chapters, chapters into sections etc.

In short there are many advantages of using this language but again context important. Programming a document layout is not the same as building an application, there are similar concepts employed in both.

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .