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?

12
  • 4
    Perhaps first exaplain why you want to mess with \mathrel in the first place.
    – daleif
    Oct 9 '20 at 6:10
  • 1
    And what exactly does \mathrel do wrong? Just because you can change something does not mean you should
    – daleif
    Oct 9 '20 at 6:33
  • 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. Oct 9 '20 at 7:00
  • 2
    latex relations are declared with \DeclareMathSymbol you don't need to redefine tex primitives to change their definition. Oct 9 '20 at 7: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 9 '20 at 7:30
3

\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
15
  • 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 9 '20 at 6: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 9 '20 at 7: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. Oct 9 '20 at 7: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 ? Oct 9 '20 at 7:10
  • 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. Oct 9 '20 at 8:06
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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