2

I would like to rename a couple of commands so that the commands match the words I think of when I want to use them.

I would like to have \iso be what is by default \cong (an equals sign with a \sim on top: ≅), and I would like \cong to be what \equiv is by default (3 parallel lines: ≡).

Currently, I have in my preamble:

\newcommand{\iso}{\cong}
\renewcommand{\cong}{\equiv}

This does not work. It changes \cong to "≡", but is also makes \iso print a "≡". I find this confusing because my understanding was that TeX read commands from top to bottom, so I assumed it would assign \iso to \cong before overwriting the definition of \cong.

Is there a simple way to accomplish this?

(PS. I'm not sure what tags are appropriate for this. Let me know if this should be categorized differently.)

  • 1
    Your reasoning is almost correct. However \newcommand{\iso}{\cong} does not make \iso equal to \cong, it makes \iso expand to \cong. But when you use \iso (which expands to \cong), \cong will typeset the \equiv symbol. Which is what you're seeing. What you want is \let\iso\cong and \let\cong\equiv. – Phelype Oleinik Sep 28 '19 at 23:36
  • @PhelypeOleinik beware robust commands when using \let:-) – David Carlisle Sep 28 '19 at 23:42
  • @DavidCarlisle what do you mean? – rosterherik Sep 28 '19 at 23:50
  • @DavidCarlisle Of course what I meant to say was: "What you want is to load letltxmacro and use \LetLtxMacro\iso\cong and \LetLtxMacro\cong\equiv. " ;-) – Phelype Oleinik Sep 28 '19 at 23:53
  • @rosterherik sorry that was aimed at Phelype who would know once reminded. better to use \LetLtxMacro from the letltxmacro package rather than \let – David Carlisle Sep 28 '19 at 23:55
  • 5
    So, the conclusion from the above comments is you need to add \usepackage{letltxmacro} in the preamable and then \LetLtxMacro\iso\cong and \LetLtxMacro\cong\equiv as @PhelypeOleinik said. This copies the definition of \cong into \iso, so that when you later change \cong, the definition of \iso is not effected. For more info on \LetLtxMacro see When to use \LetLtxMacro?. – Peter Grill Sep 29 '19 at 02:05
  • @PeterGrill thank you for the comprehensive answer. If you write it below I will accept it. – rosterherik Sep 29 '19 at 18:05
  • @PhelypeOleinik: Please post an answer so we can mark this question as answered. – Peter Grill Sep 29 '19 at 18:17

1 Answers1

5

The solution to the problem is to load the letltxmacro package and do:

\LetLtxMacro\iso\cong
\LetLtxMacro\cong\equiv

A little explanation: your reasoning that "TeX read commands from top to bottom" is correct. After you do \newcommand{\iso}{\cong}, the command \iso will make a as you expect, but not how you expect it to. After the \newcommand above (I'm ignoring the redefinition of \cong for now), every time TeX sees the control sequence \iso it will know that \iso should expand to \cong, i.e., when \iso is found it is replaced by \cong. After the replacement is done, TeX sees \cong, which will (for now) make a . So far so good.

However, now you do \renewcommand{\cong}{\equiv}. Same as defore, this tells TeX that every time it finds the control sequence \cong, it should expand to (or: be replaced by) \equiv. If you use \cong now you get the symbol as you wanted. However if you use \iso, TeX expands it to \cong, which is then again expanded to \equiv, which still prints a . Once TeX expanded a control sequence it has no memory of what it was. This means that whether you use \iso and it expands to \cong or you use \cong directly, for TeX it will be the same thing.


Of course, what you meant was to have \iso be equal to \cong and then \cong be equal to \equiv. The TeX operation to do this is \let, not \def (\def is the underlying primitive in \(re)newcommand).

After you do \let\iso\cong, when TeX finds \iso it does not expand to \cong, but to what \cong was at the time you did the \let operation. (Very, very) roughly speaking, \let\iso\cong would have the same effect as \newcommand\iso{<meaning of \cong>}. So it doesn't matter if you change the meaning of \cong (with either \let or \def), \iso already has a copy of it so it's safe.


But there's a catch: various LaTeX commands are "robust". This means that the meaning of \cong is \protect\cong&bbrk; (that's right, it is the command \cong&bbrk;, with a trailing space in the name; you can't easily access it) (there are other protection mechanisms, for example \protect\\cong, with \\ in the command name, but the moral is the same).

So even if you do \let\cong\equiv, the meaning of the internal \cong&bbrk; will remain unchanged, and things can quickly go off tracks.

So the same warning that goes for using \def with LaTeX applies to \let: don't use it, unless you are very sure of what you're doing and you are ready to face the consequence of any misuse :-)

If you are not sure, use the letltxmacro package, which provides you a safer version of \let which takes care of robust macros and does the right thing when they are robust. Note the difference of doing \let\iso\cong:

> \iso=macro:
->\protect \cong  .
l.4 \show\iso

?

and using \LetLtxMacro\iso\cong:

> \iso=macro:
->\protect \iso  .
l.4 \show\iso

?