11

Usually, e.g., when I want to have an if, I do something like this:

if(value) {
    ... whatever code ...
}

But in LaTeX, its:

\ifnum\count0<100
    ... whatever LaTeX-code ...
\fi

There are no brackets and so on, for example, which indicate where if-statements begin and where they end. Also, there are no brackets around if condition itself which is checked by LaTeX and so on.

Those are all minor differences, of course, but (from my experience) its way easier to read source from other languages than to read source which is part of a TeX-Document. This might, of course, be a personal thing because I program more often with non-LaTeX-languages than with LaTeX, but I still do not see the advantage of forcing users to use such a syntax.

Can anyone explain this to me?

7
  • 20
    when knuth created tex, he was intending it for use by himself and his secretary, and he designed the language that he thought was most appropriate for its intended use -- typesetting. he didn't foresee its adoption by so many other users. one must simply accept the fact that knuth doesn't think the same way that most other people do, and vice versa. Commented May 23, 2014 at 18:05
  • 1
    Your example is actually TeX syntax and not necessarily the same you would use in LaTeX, see etoolbox's conditionals for example.
    – cgnieder
    Commented May 23, 2014 at 18:33
  • 1
    it is not only "minor differences": try \newif\iftestA \iftestA \let\x\iftrue \else \let\x\iffalse \fi \bye. Mastering the TeX syntax with conditionals takes a lot of time! The LaTeX and etoolbox conditionals are much safer \iftest{arguments}{YES}{NO} and such style is even almost necessary in certain circumstances. Naturally, underneath, it all boils down to careful wrappers of the TeX primitives.
    – user4686
    Commented May 23, 2014 at 18:53
  • 1
    Adding to what @barbarabeeton said, Knuth intended TeX to be what he considered to be an implementation of "literate" programming, that is, writing for code humans and not for machines. Most programmers have learnt to think like a computer does (e.g. they have a for each primitive instead of recursive loops)… TeX was never meant that way – it is meant to be written in a meaningful, readable order (no libraries or functions) and self-documented. Most humans that know programming languages do not think like Knuth, and do not see code as some form of prose.
    – ienissei
    Commented May 23, 2014 at 20:50
  • 3
    Just to add my humble POV, difference is in the eye of the beholder. Syntax preference is 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 lagic as wacky or strange. :) Besides, I have the impression Maslow's hammer applies here as well. :) I remember of the arithmetic IF in Fortran and different decimal marks in ALGOL, so your mileage may vary. Personally, I believe this question turns more opinion-based. Commented May 24, 2014 at 11:13

6 Answers 6

8

TeX is not a regular programming language: it's a "macro expansion language". TeX has its origins in systems such as were used by newspapers where every article starts with "From our correspondent" or "From our financial correspondent". Typesetting systems then had a way of declaring a macro \foc or \fofc that would replace the macro by such a fixed piece of text.

Now imagine that a macro can have an argument: \foc{special}, expanding to "From our special correspondent". So: macro plus braced text gets replaced by a long string in which the argument is substituted. TeX is like that, but more complicated.

This macro mechanism also explains why \one\two{three} does not apply \one to the result of \two{three}: the macro \one takes whatever single expression comes after it, in this case \two, and expands and substitutes it.

Et cetera. So keep in mind that TeX does not have multiple passes over a text (tokenizer, syntax checker, semantic checker) but has a single pass, where stuff is either typeset, or interpreted as a macro which gets replaced by text. Or more macros. That explains a lot of the strangeness.

7

The if ... fi notation is fairly common (probably more so then) for example this shell (sh or bash) script echos yes or no depending on whether the argument is x

if [ "$1" = x ]
then

echo yes

else

echo no

fi

what you consider normal depends a lot on what you are used to C programmers might expect

(x<100)? "yes" : "no" ;

Perhaps even closer in nature, since they are both macro expansion languages of similar age, the C preprocessor tests such as

#ifdef ZZZZ
#define SOMETHING
#endif

which declares the macro SOMETHING if the macro ZZZZ is not declared and so it goes on.

5

TeX language mixes the objects which are intended to be executed and object for printing only. By default, when the object is nothing special then it is printed. This is first main difference between TeX language and common procedural languages. This approach gives you very powerful tool. This implies that the macro-expansion language is used. Compare:

hello world \end      % prints hello world in TeX
print{"hello world"}  % prints hello world in procedural language

The TeX braces {} (more precisely the characters with catcodes 1 and 2) have four different meaning in the language. This may cause a small problems sometimes but this enables amazing tricks too. The meanings are: (1) they must be always balanced (this is checked by TeX internal algorithms). (2) they affect the parameters reading and they are discarded by TeX internal algorithm when they are at the outer level in parameter text. (3) they delimit groups and borders of the boxes or math-sublists (they delimit groups too). The settings are local in such groups. (4) They delimit the text of the macro (after \def or companion).

Thus it is not so much good idea to give the fifth meaning for braces: for delimiting the conditionals. That is the reason why conditional are solved by different way. But macro programmer can prepare brace-oriented conditionals for users but he/she never uses such type of reducing.

The procedural language programmer says, for example:

if (a%2 == 0) {
  x = 1;
} else {
  x = -1;
}

but TeX macro programmer have more ways at what level of expansion the conditional is processed:

\valX = \ifodd\valA -\fi 1 
% or:
\ifodd\valA \valX = -1 \else \valX = 1 \fi

I mean that TeX is very very powerful tool but there are only few people they are able to understand it and to utilize it efficiently. Unfortunately.

2

This is mostly TeX (not the nice, structured LaTeX you normally write). Plus (La)TeX is a macro/markup language, most of what is written just gets passed through. Such languages have a distinct "feel" (if on Unix/Linux, take a peek at m4(1); check out the C/C++ preprocessor).

I just saw an announcement for lollipop here, it might be what you are looking for (I'm planning to check it out sometime).

2

Ah, a seven-year-old question with plenty of perfectly acceptable answers.

I'd note from a "why" perspective, Barbara Beeton's comment:

when knuth created tex, he was intending it for use by himself and his secretary, and he designed the language that he thought was most appropriate for its intended use -- typesetting. he didn't foresee its adoption by so many other users

and Victor Eijkhout's answer

TeX is not a regular programming language: it's a "macro expansion language".

do the most to get at the heart of the question.

Much of the primitive syntax is based around making keyboarding as ergonomic as possible for DEK's use case¹ and a lot of what's happened with macro development in the nearly 40 years since TeX82 was released has been around trying to make things more regular (the random placement of @ in “private” command names is one instance of bad irregularity). I think that Frank Mittelbach’s Teutonic temperament goes a long way to making this sort of thing happen² with expl3 and various LaTeX extensions from the team. But of course, LaTeX, having grown in a disorganized fashion over 37 years has plenty of inconsistencies to go around, including multiple key-value implementations and conditional syntaxes (e.g., as Steven Segletes gave an example, there are macros which have a general format of⁴

\somename{CONDITION}{TRUE ACTION}{FALSE ACTION}

xparse (among others) provides multiple variations of its conditional commands, e.g.,

\IfBooleanTF{ARG}{TRUE ACTION}{FALSE ACTION}
\IfBooleanT{ARG}{TRUE ACTION}
\IfBooleanF{ARG}{FALSE ACTION}

which is also present in expl 3 syntax which has, for example:

\bool_if:nT {CONDITION} {TRUE ACTION}
\bool_if:nF {CONDITION} {FALSE ACTION}
\bool_if:nTF {CONDITION} {TRUE ACTION}

(In general, expl3 is an attempt to turn TeX's macro language into something approaching a more familiar programming language, although there are some occasional oddities like using the term map for what's really a foreach).


  1. Someone can doubtless more easily dig up his comments on why he preferred {1\over 2} to \frac{1}{2} etc.
  2. I'm simultaneously awed and bemused³ by the tendency of German individuals and institutions to engage in systematic arrangement of things
  3. Yes, I meant bemused and not amused.
  4. Note that TeX's processor can get confused by having a macro name start with \if… so that naming is generally frowned upon unless it's a conditional created with the primitive \newif.
1
  • Not really the main point here, but the map is really a map (i.e. apply a function over each item, return the result being the "list" (concatenated token list, in TeX's case) of all function results) for those that are expandable. For the unexpandable ones they're probably used for... consistency (although those unfamiliar with expansion issues in TeX might get troubles.).
    – user202729
    Commented Jul 9, 2022 at 15:13
1

As others have said, it is this way because Knuth defined it this way. However, it is a simple process to define macros that do it the other way. For example, the tokcycle package (whose purpose is unrelated to this question) creates some user macros that provide an alternate syntax that may be more to your liking:

\tctestifnum{<ifnum condition>}{<true code>}{<false code>}
\tctestifcatnx <token1><token2>{<true code>}{<false code>}
\tctestifx{<ifx condition>}{<true code>}{<false code>}
\tctestifcon{<T/F condition>}{<true code>}{<false code>}

Here, \tctestifnum provides an alternate syntax for an \ifnum condition, \tctestifcatnx for a \noexpanded \ifcat condition, \tctestifx for an \ifx condition, and \tctestifcon for any generic true/false condition.

Note that, because TeX is an expansion language, there are times where the presence of \else and \fi associated with the TeX primitives can actually interfere with the desired argument expansions. Thus, this alternate syntax automatically overcomes such expansion related issues.

In the MWE, I show the macro definitions themselves. However, since they are taken directly from the tokcycle package, one could alternately just load that package to access these alternate definitions.

\documentclass{article}
%\usepackage{tokcycle}% HAS THE FOLLOWING MACROS ALREADY DEFINED
\makeatletter
\long\def\tctestifcon#1{#1\expandafter\tc@exfirst\else\expandafter\tc@exsecond\fi}
\long\def\tctestifcatnx#1#2{\tctestifcon{\ifcat\noexpand#1\noexpand#2}}
\long\def\tctestifx#1{\tctestifcon{\ifx#1}}
\long\def\tctestifnum#1{\tctestifcon{\ifnum#1\relax}}
\long\def\tc@exfirst#1#2{#1}
\long\def\tc@exsecond#1#2{#2}
\makeatother
\begin{document}
\tctestifnum{0=0}{T}{F}
\tctestifnum{0=1}{T}{F}

\tctestifcatnx 01{T}{F}
\tctestifcatnx 0A{T}{F}

\let\mymacro\relax
\tctestifx{\relax\mymacro}{T}{F}
\let\mymacro\empty
\tctestifx{\relax\mymacro}{T}{F}

\tctestifcon{\iftrue}{T}{F}
\tctestifcon{\iffalse}{T}{F}
\end{document}

enter image description here

You must log in to answer this question.

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