Grundsätzliches
\relax ist ein Token (ein Primitives), das nicht expandierbar ist und nichts macht, wenn es ausgeführt wird. {} sind zwei Token, die (Standard-Kategoriecodes vorausgesetzt) eine leere Gruppe oder nicht begrenztes Argument darstellen.
Eigenschaften
\relax
@saputello hat ja schon geschrieben, dass \relax beim Schreiben mit \write als es selbst geschrieben, also nicht expandierbar ist. \relax (und jede Kontrollsequenz die mit \let äquivalent zu \relax gemacht wurde) bleibt also auch in einem \edef stehen:
zeigt im log
Das kann erwünscht oder unerwünscht sein...
{}
$a+{}$ setzt + als Relation, d.h. mit entsprechend Leerraum herum, da {} ein mathord atom erzeugt. $a+\relax$ wirkt wie $a+$ und setzt + nicht als Relation, d.h. ohne extra Leerraum.
Sowohl {} als auch \relax unterdrücken Ligaturen:
Allerdings habe ich noch nie gesehen, dass \relax dafür eingesetzt wird. Übrigens funktioniert auch {} dafür nicht zuverlässig. Zum Beispiel werden Ligaturen mit LuaTeX damit nicht unterdrückt.
Anwendungen von \relax
Assignments und \numexpr & \dimexpr
Die Nicht-Expandierbarkeit macht man sich zunutze bei Assignments, die auf der Suche nach ihrem Argument die folgenden Token expandieren bis sie auf etwas Nicht-Expandierbares stoßen:
In diesen Fällen kann man {} nicht auf gleiche Weise verwenden. Ein Beispiel, wo {} Probleme verursacht, wird gleich gezeigt. Ähnlich verhält es sich mit \ifnum:
\numexpr und \dimexpr sind hier besonders zu erwähnen. Man sollte ihre Ausdrücke immer mit einem \relax beenden, aus einem vergleichbaren Grund wie bei Assignments. \relax wird von ihnen aus dem Input-Stream entfernt, {} würde zurückbleiben. Die Tatsache, dass sie das \relax dann aus dem Imput-Stream entfernen, macht sie verschachtelt verwendbar und trotz des \relax expandierbar_.
Ein {} könnte an solchen Stellen durchaus Probleme verursachen, etwa in folgender Definition:
Open in writeLaTeX\def\mylength{100pt{}}
\hbox to \mylength {bla} % => expandiert zu \hbox to 100pt{}{bla} => wohl nicht gewünscht.
\def\mylength{100pt\relax} hätte in diesem Beispiel wie gewünscht funktioniert.
Einsatz in \write
Man kann sich die Nicht-Expandierbarkeit in einem \write auch zunutze machen, um Befehle in eine Hilfsdatei zu schreiben:
Hier wird \section lokal auf \relax gesetzt, wodurch es gefahrlos in die Hilfsdatei geschrieben werden kann. Das gleiche kann man mit {} nicht erreichen.
Namen von Befehlssequenzen
Wenn man \csname foo\endcsname aufruft und das Makro \foo vorher nicht definiert wurde, dann ist es danach äquivalent \relax:
gibt im log:
Auf dieser Tatsache beruht der Test \expandafter\ifx\csname foo\endcsname\relax ob ein Makro definiert ist. Das steht auch hinter der Technik, mit \let\foo\relax das Makro \foo zu „löschen“:
Open in writeLaTeX\documentclass{article}
\begin{document}
\newcommand\foo{foo}
\let\foo\relax% nun kann \foo mit \newcommand wieder definiert werden
\newcommand\foo{bar}
\end{document}
Die Beispiele habe ich z.T. bei David Carlisle geklaut.
beantwortet
24 Jul '13, 11:25
cgnieder
22.1k●26●34●63
Akzeptiert-Rate:
60%