0

It seems that I cannot modify \mathrel without breaking \overset, and I do not understand why. The following fails to compile even when the redefinition of \mathrel does exactly the same as the original version.

\documentclass{article}
\usepackage{amsmath}
\usepackage[T1]{fontenc}
\begin{document}
\let\oldmathrel\mathrel
\def\mathrel#1{\oldmathrel{#1}}
$A \overset{X}{\to} B$
\end{document}

The error message is:

Runaway argument?
\relax\@nil \binrel@@ {\mathop {\kern \z@ \to }\limits ^{X}} B$ \end \ETC.
! File ended while scanning use of \@tempb.
<inserted text> 
                \par 

What is going on?

user21820
  • 868
  • 7
  • 19
  • 4
    Perhaps first exaplain why you want to mess with \mathrel in the first place. – daleif Oct 09 '20 at 06:10
  • @daleif: I don't like the default behaviour of \mathrel. Anyway it is not relevant to my question; I'm asking why modifying it breaks \overset, and how to modify it without breaking \overset. – user21820 Oct 09 '20 at 06:17
  • 1
    And what exactly does \mathrel do wrong? Just because you can change something does not mean you should – daleif Oct 09 '20 at 06:33
  • BTW why are you even using overset here and not \xrightarrow{X} – daleif Oct 09 '20 at 06:34
  • @daleif: I use \overset in many other ways; this was just a minimal example. My question is about why the error arises and how to avoid it, not about your opinion on whether I should or should not do something. – user21820 Oct 09 '20 at 06:39
  • 3
    defining \mathrel to take a macro argument will break latex in many ways (no matter what definition you give for the macro), so without an explicit use case (where for a specific context it may be possible to do something) it is hard to know what answer you could have other than don't do that. – David Carlisle Oct 09 '20 at 07:00
  • @DavidCarlisle: There are many nice things one can achieve if \mathrel can be properly redefined. For example, if we want every relation-symbol to be blue, we can do so for inbuilt symbols like "=", but what if we don't want to repeat code for every single relation-symbol that is created in the document itself? If we can modify \mathrel, we can ensure that every newly created relation-symbol is blue. Another possible use is to allow line-breaking before each relation-symbol (not just after). Just like we can easily style each class in CSS. – user21820 Oct 09 '20 at 07:13
  • 2
    latex relations are declared with \DeclareMathSymbol you don't need to redefine tex primitives to change their definition. – David Carlisle Oct 09 '20 at 07:14
  • 2
    To expand on David’s comment: changing the definition of \mathrel will have no effect on \leq, \sim, and any of the basic relation symbol commands (except \cong, \notin and perhaps a few others) – egreg Oct 09 '20 at 07:30
  • Sadly, kvetching about how you "don't like the default behaviour of \mathrel" ìs not likely to get you very far -- in no small part because "the designer of TeX" is known not to frequent TeX.SE. It might be more productive if you explained what it is that you're trying to achieve. E.g., do you want to change the spacing around math atoms of type math-rel? If so, it suffices to change the values of certain length parameters. Or, if you want to change the status of a math-atom from math-rel to, say, math-bin, you can do so without modifying \mathrel itself. – Mico Oct 09 '20 at 07:31
  • @egreg: I know that too, but we can modify the (fixed finite) number of basic relation-symbols, and leave the rest to \mathrel. As I said, the point is to keep the styling separate from the main document. – user21820 Oct 09 '20 at 07:34
  • @Mico: I gave two examples of what I would like to do in my comment 23 min ago. If you can do both of them in a uniform way without having to manually redefine each relation-symbol created in the document, I would be interested. But when posting my question I had thought that there was a way to modify \mathrel, as doing so would allow much more than those two example usages. – user21820 Oct 09 '20 at 07:36

2 Answers2

4

\mathrel is a tex primitive command used all over the place. You shouldn't change it without really good understanding how such primitives work and without the skill to trace the code.

In your example it fails as the primitive doesn't take an argument. This means that you can do something like this:

\documentclass{article}

\begin{document}

$abc$

$a\ifnum 1=1 \mathrel \else \mathbin \fi b c$

\end{document}

enter image description here

If you add your redefinition, \mathrel will suddenly grab the \else as argument, and then the code falls apart:

\mathrel #1->\oldmathrel {#1}
#1<-\else

! Missing } inserted. <inserted text> } l.24 $a\ifnum 1=1 \mathrel \else \mathbin \fi b c$

Something similar happens with overset as the amsmath definitions uses \mathrel also inside a \if-test:

    \ifdim\wdz@<\z@ \mathbin
    \else\ifdim\wdz@>\z@ \mathrel
    \else \relax\fi\fi
Ulrike Fischer
  • 327,261
  • Ok, so basically the answer is that the designer of TeX did not care that not every mathematician likes his preferred behaviour of relation-symbols, which is why the standard user-level method of creating a new relation-symbol is not easy to modify. – user21820 Oct 09 '20 at 06:56
  • Anyway, the second part of my question is how to redefine \mathrel properly. Are you able to answer that? Or if there is a better way to create new relation-symbols without damaging the fragile internals of TeX, than to use \mathrel, please tell me. – user21820 Oct 09 '20 at 07:01
  • 1
    you should better ask a new question explaining which relation symbol you want to create and why using \mathrel doesn't work for you. – Ulrike Fischer Oct 09 '20 at 07:04
  • 1
    @user21820 \mathrel is not a user level command, except for its use as a token in \DeclareMathSymbol perhaps you should be redefining \DeclareMathSymbol ? – David Carlisle Oct 09 '20 at 07:10
  • @DavidCarlisle: \DeclareMathSymbol does not provide the general ability to create new relation-symbols out of LaTeX constructions. That is why people always say to use \mathrel. I don't see why it is not effectively a user-level command unless there is a user-level version of it. – user21820 Oct 09 '20 at 07:17
  • as you see it is not a latex command (it is not mentioned in the latex book) and does not follow the same syntax rules as any command that is described as a user command in latex. tex being a macro expansion language there is no error message or warning if you drop down and use commands from latex's internal definition language of tex primitives, but if you do that you get what you get, you are out of the realm of latex-documented behaviour. @user21820 – David Carlisle Oct 09 '20 at 07:21
  • @DavidCarlisle: I know that, but the fact remains that the only user-level way to create new relation-symbols such as "==" or "\boxed{=}" is to use \mathrel... – user21820 Oct 09 '20 at 07:30
  • @user21820 This is like saying that the only user-level way to define a new command is to use \def. At the end of the chain there is always a primitive command, but that doesn't mean that they can not be sophisticated user-level commands like \newcommand or \NewDocumentCommand which hide tex internal details from the user. – Ulrike Fischer Oct 09 '20 at 07:35
  • @UlrikeFischer: That's just evading the point I made. How would you define a new relation-symbol "\boxed{=}", if not using \mathrel? What if you have many such symbols defined within a document? How do you uniformly make all of them blue without having to change all the defined relation-symbols? – user21820 Oct 09 '20 at 07:39
  • I would use mathrel, but I would not redefine it. Beside this: as I already wrote how to do this is a new question and not something that should be discussed in comments, so ask a new question. – Ulrike Fischer Oct 09 '20 at 07:52
  • 1
    @user21820 as Ulrike says, if you want to define commands with optional arguments latex provided \newcommand and you can use \newcommand to define things, it does not redefine \def. same here you can define \mymathrel that does whatever you want and define higher level commands to use that rather than \mathrel. Documents that use the tex primitive \mathrel are, like documents that use the tex primitive \def, essentially outside the scope. They exist but you can not alter there behaviour in any coordinated way. – David Carlisle Oct 09 '20 at 08:06
  • @DavidCarlisle: I understand that. As I said in the other comment thread, before I posted this question I was not aware that \mathrel was used in such a primitive way in TeX internals, but if we want to uniformly change the styling of all relation-symbols in a document, it still seems that \mathrel is one of the things we need to change, since we do use \mathrel to define relation-symbols in a document. It seems like the only way is to not use \mathrel in the document but rather some other command, say \bluerel. If you both think so, I don't need to ask a new question. – user21820 Oct 09 '20 at 10:44
  • @user21820 there is always some way (see comments about \protected under egreg's answer) but any such definition will break something, so if I wanted to do that I certainly would not redefine \mathrel. As it is, you are going to have to redefine hundreds of commands, stix2.sty for example has over 600 relation symbols that do not use \mathrel in their definition as they are optimised out with \mathchardef so you would have to redefine the latex commands anyway so just as easy to make them use \blueref as \mathrel – David Carlisle Oct 09 '20 at 10:58
  • @DavidCarlisle: Hmm okay I suppose I don't have a choice; I have to deliberately and individually alter the definition of each relation-symbol used in the document. Although I didn't use stix2.sty in my document, your argument that we cannot anticipate what are relation-symbols is a convincing one, so thanks. The only remaining possibility is to intercept the TeX processing at the point when the thickmuskips are inserted, which I suppose is impossible. – user21820 Oct 09 '20 at 12:28
  • @user21820 if you use luatex yes (in theory) but in classic tex you don't need to define each symbol just define the declaration commands such as DeclareMathSymbol or the variant used in stix \stix@MathSymbol but if you are redefining such commands you can inject the color directly no need to redefine \mathchardef (in fact redefining mathchardef doesn't help if the symbol is defined with \mathchardef) – David Carlisle Oct 09 '20 at 13:07
0

I do not know why egreg's answer is deleted, because there was a useful comment under it (I can't remember by who) that gave a very simple solution:

\protected\def\mathrel#1{\oldmathrel{#1}}

They cautioned that it may break other packages, but using this does not cause any problems for me, so this works for me.

user21820
  • 868
  • 7
  • 19