7
1

Öfters lese ich in Erklärungen, dass ein Makro nicht "expandierbar" ist.

Was ist darunter zu verstehen?

Generell muss ich feststellen, dass sich bei der TeX-Programmierung eines Vokabulars bedient wird, was in anderen Programmiersprache nicht üblich ist, z.B. eben "expandierbar" oder eben "Makro". Ich kenne den Begriff "Makro" nur aus der VBA-Programmierung. Dort hat er jedoch eine ganz andere Bedeutung.

gefragt 10 Aug '13, 11:22

dzaic's gravatar image

dzaic
631104853
Akzeptiert-Rate: 42%

bearbeitet 10 Aug '13, 12:02

cgnieder's gravatar image

cgnieder
22.1k243463

Makroprogrammierung kennt übrigens jeder C-Programmierer vom Makro-Präprozessor, also den berühmt berüchtigten #define-Konstrukten. Hauptsächlich von autoconf bekannt ist auch m4. Wer vor 30 Jahren und mehr programmieren gelernt hat, kennt das auch noch von Makro-Assemblern. Viele Editoren haben ebenfalls einen Makroprozessor eingebaut. Makro-Sprachen arbeiten generell nach dem Suchen/Ersetzen-Prinzip. Auch wenn TeX eine etwas eigenwillige Makrosprache ist.

(10 Aug '13, 15:52) saputello

Um die Frage zu beantworten, sollte zunächst geklärt werden, was ein Makro und was Expansion ist.

TeXs und damit LaTeXs Kontrollsequenzen sind entweder Primitive (= von TeX direkt bereitgestellte Kontrollsequenzen), Register (z.B. Längen) oder Makros.

Letztere wurden mit \def (ein TeX-Primitives) oder einem seiner Verwandten (oder mit LaTeXs äquivalent \newcommand und Verwandten) definiert. Das kann im Kernel des verwendeten Formats (also z.B. LaTeX) geschehen sein, in einer eingebundenen Datei (z.B. ein LaTeX-Paket) oder man hat es selbst gemacht:

\def<kontrollsequenz><parameter spez>{<ersetzungstext>}

Wenn TeXs Mund (aka mouth) ein Makro sieht, schaut es nach, wie die Definition lautet, ob und welche Parameter gelesen werden müssen und tauscht schließlich das Makro samt Parameter mit dem Ersetzungstext aus. Dieser Vorgang wird als Expansion bezeichnet. Danach schaut der Mund, was als nächstes im Inputstream kommt.

\def\bla{einem bla Makro}
\def\blub#1{einem Blub Makro mit #1}

                     ein text mit \blub\bla, geht aber weiter
eine Expansion    => ein text mit einem Blub Makro mit \bla, geht aber weiter
weitere Expansion => ein text mit einem Blub Makro mit einem bla Makro, geht aber weiter

\def\a{\b}
\def\b{\c}
\def\c{d}

\a =eine Expansion=> \b  =eine Expansion=> \c =eine Expansion=> d

Viele von TeXs Primitiven1 sind nicht expandierbar, das heißt, sie bleiben so stehen wie sie sind. Dazu gehört z.B. \relax, genauso alle, die irgendwelche Zuweisungen vornehmen (\def, \let, ...). Sie erledigen ihre Arbeit in TeXs Bauch (aka stomach). D. E. Knuth hat das im Appendix D des TeXbooks folgendermaßen beschrieben:

TeX’s control sequences are divided into two main categories, “expandable” and “unexpandable”; the former category includes all macros and \if...\fi tests, as well as special operations like \the and \input, while the latter category includes the primitive commands listed in Chapter 24. The expansion of expandable tokens takes place in TeX’s “mouth,” but primitive commands (including assignments) are done in TeX’s “stomach.” One important consequence of this structure is that it is impossible to redefine a control sequence or to advance a register while TeX is expanding the token list of, say, a \message or \write command; assignment operations are done only when TeX is building a vertical or horizontal or math list.

Das heißt also, alle Makros sind expandierbar. Jedenfalls grundsätzlich. Allerdings wird oft gesagt, das sie nicht vollständig expandierbar sind, wenn ihr Ersetzungstext nicht-expandierbare Kontrollsequenzen enthält, etwa, wenn der Ersetzungstext seinerseits Zuweisungen vornimmt: \def\foo#1{\gdef\@foo{#1}. Das oben definierte Makro \a ist übrigens vollständig expandierbar:

\a =vollständige Expansion=> d

Nicht vollständig expandierbar wäre z.B. folgendes Makro:

\def\A{\def\B{C}}

Wenn ein Makro nicht vollständig expandierbar ist, hat das Konsequenzen in Anweisungen, die ihren Inhalt vollständig expandieren (wollen/müssen), wie \edef oder \write, siehe auch diese Frage und ihre Antworten über zerbrechliche und robuste Befehle2. Dort kann es Probleme bereiten, wenn nicht geeignete Maßnahmen ergriffen werden.

\edef\keinproblem{\a}
\show\keinproblem
% im Log:
> \keinproblem=macro:
->d.

\edef\problem{\A}
% im Log:
! Undefined control sequence.

\A ->\def \B 
             {C}

Im zweiten Fall gibt es ein Problem: \edef versucht \def zu expandieren, was nicht geht, weshalb es stehen bleibt (wie es ein Buchstabe auch tun würde). Dann versucht es \B zu expandieren, was zum Fehler führt, da es nicht existiert. (Würde es schon existieren, gäbe es andere ungewünschte Effekte).

Mit e-TeX gibt es übrigens das Primitive \protected, das ermöglicht, nicht-expandierbare Makros zu definieren (\protected\def\foo#1{\gdef\@foo{#1}). Solche nicht-expandierbaren Makros werden zwar im Mund expandiert3, nicht aber in einem \edef o.ä., wo sie sich ähnlich einem \relax verhalten.


  1. siehe auch Kommentare zu dieser Antwort.
  2. Diese Art der Expansion wir in expl3 (LaTeX3s Programmierschicht) als x-Expansion ( exhaustive) genannt
  3. man korrigiere mich bitte, wenn das nicht stimmt.
Permanenter link

beantwortet 10 Aug '13, 12:32

cgnieder's gravatar image

cgnieder
22.1k243463
Akzeptiert-Rate: 60%

bearbeitet 03 Sep '13, 23:10

Du schreibst: "Viele von TeXs Primitiven sind nicht expandierbar, ..." Welches Primitiv soll denn expandierbar sein?

(10 Aug '13, 15:02) Herbert

@Herbert z.B. \csname, die ganzen \if<...> ... \else ... \fi, \input ... (die sind in TeX By Topic im Glossar der Primitiven daher auch als expandable command klassifiziert).

(10 Aug '13, 15:09) cgnieder

Dem Anfänger hilft das nicht wirklich. Streng genommen wird ja auch nicht \csname expandiert, sondern das gesamte Konstrukt aus \csname <token> \endcsname. Gleiches gilt für \if... \else ...\fi

(11 Aug '13, 07:34) Herbert
2

Hätte ich geschrieben »TeXs Primitive sind nicht expandierbar«, also ohne die Einschränkung, hätte sich bestimmt jemand beschwert, dass das so aber nicht stimmt...

(11 Aug '13, 09:35) cgnieder
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×52
×22
×18
×7

gestellte Frage: 10 Aug '13, 11:22

Frage wurde gesehen: 11,405 Mal

zuletzt geändert: 03 Sep '13, 23:10