- What's the difference between the term "parameter" and the term "argument" in TeX jargon?
- Are outermost enclosing pairs of matching curly braces of undelimited arguments to be considered components of these arguments?
- Are delimiters of delimited arguments to be considered components of these arguments?
1 Answer
With this answer
- the phrase "⟨replacement text⟩" (in angles) denotes the ⟨replacement text⟩ of a macro's ⟨definition⟩ at the time of defining that macro. Such ⟨replacement text⟩ may contain parameters (
#1
or#2
or ...). - the phrase "replacement text" (without angles) is about a (possibly empty) collection of tokens which you get at the time of expanding an instance of a macro and which consists of that macro's ⟨replacement text⟩, but with parameters (
#1
,#2
, etc.) being substituted by arguments gathered from the token-stream.
Answer to: 1. What's the difference between the term "parameter" and the term "argument" in TeX jargon?
In the TeXbook the term "parameter" occurs in several contexts:
The term "parameter" (like the term "argument") occurs in the context of macro programming. That deserves special attention. Therefore it is discussed separately, in the last section of the answer to 1.
One of the categories which character tokens can have is called "parameter". That category is denoted by the category code 6. Usually the hash character (
#
) has category 6(parameter).Quantities of fonts/font-metrics are referred to as "font parameters".
There are five kinds of so-called "internal parameters" whose values can be changed by performing assignments and where the values influence/affect/adjust the way in which the algorithms hardcoded into TeX the program work: integer parameters, dimension parameters, glue parameters, muglue parameter and token parameter.
E.g., the control word token
\parskip
usually denotes a glue parameter which affects the amount of vertical space between paragraphs of text.E.g., the control word token
\parindent
usually denotes a dimension parameter which affects the amount of space of horizontal indendation at the left of the fist line of a paragraph of text.E.g., the control word token
\escapechar
usually denotes an integer parameter for specifying the character which TeX uses for denoting a control sequence token- when
\scantokens
or\detokenize
causes virtually writing tokens unexpanded to a virtual text file (for afterwards virtually reading the virtual text file back and hereby (re)tokenizing and processing the virtual text file's content; with\detokenize
(re)tokenization is done with the\string
-catcode-régime, i.e., everything is tokenized as explicit character token, every character except space having category code 12(other), space (character code 32) having category code 10(space)), or - when actually doing unexpanded writing of tokens to screen/console/terminal or to text file, e.g., via
\meaning
,\show
,\message
,\write
or when otherwise creating a an entry of the .log-file or a message displayed on screen/on the console/on the terminal, or - when via
\string
obtaining the stringification of a control sequence token.
Additional note about internal parameters: With internal parameters the control sequences denoting them can be seen as "access points" for changing their values and for retrieving information about their current values in the context of doing some programming work/in the context of having the program TeX carry out instructions given in the language TeX:
If you say\let\tnednirap=\parindent
, then you have two access points to the same parameter, let's colloquially call that parameter the paragraph-indentation parameter:\show\parindent
reveals> \parindent=\parindent.
and\show\tnednirap
reveals> \tnednirap=\parindent.
This means that in both cases the control sequence token denoted on the left of the=
acts like that primitive which usually, in the initial state of TeX the program, where no things are redefined etc, is available via the control word token\parindent
.
If you do\parindent=20pt
, then both\showthe\parindent
and\showthe\tnednirap
reveal:> 20.0pt
.
If you do\tnednirap=25pt
, then both\showthe\parindent
and\showthe\tnednirap
reveal:> 25.0pt
.
If you additionally do\def\parindent{now parindent is a macro}
, then you cannot do things like\parindent = ...
or\showthe\parindent
or\the\parindent
successfully any more for adjusting the value of the paragraph-indentation parameter or for retrieving for whatsoever TeX-programming purposes information about the current value of the paragraph-indentation parameter.
Because now the purpose of the control sequence token\parindent
is changed: It now is a macro.
But you can still do\tnednirap = ...
for changing the value of the paragraph-indentation parameter. You also can still do\showthe\tnednirap
or\the\tnednirap
for retrieving information about the value of the paragraph-indentation parameter.
If you additionally do\def\tnednirap{now tnednirap is a macro, too}
, then you also cannot do\tnednirap = ...
etc any more.
Then you have no means any more for via input in the form of the TeX-language accessing the paragraph-indentation parameter. You cannot change the value of that parameter any more. You cannot retrieve information about its current value via\the
/\showthe
any more.
But the paragraph-indentation parameter is still there:
TeX keeps on indenting first lines of paragraphs.
According to the value which was assigned to the paragraph-indentation parameter as the last one before doing away with all access points for modifying that value.
(Of course, code, in which it is relied on one of the control word tokens\parindent
/\tnednirap
serving the purpose of accessing the paragraph-indentation parameter for changing and/or retrieving its value, will now fail.)\year
,\month
,\day
and\time
denote ordinary internal parameters in TeX. At the begin of the TeX-run their values are initialized according to the clock of the computer platform and that's it. After initialization TeX does not by itself change their values any more albeit the clock keeps on ticking. Via assignments\year=...
/\month=...
/\day=...
/\time=...
in the .tex-input their values can be changed during the TeX-run where the .tex-input is processed, whenever you like.- when
Registers allocated and used for influencing the behavior of the routines implemented in the plain TeX format, e.g., output-routines of the plain TeX format, are referred to as "pseudo parameters". The behavior adjustable by means of pseudo parameters is not hardcoded into TeX the program itself but is implemented in the format, using the language TeX.
About the term "argument":
In the TeXbook, "Chapter 24: Summary of vertical mode" you find the statement:
Some commands have arguments. In other words, one or more of the tokens that follow a command might be used to modify that command’s behavior, and those tokens are not considered to be commands themselves. For example, when TeX processes the sequence of tokens that corresponds to ‘
\dimen2=2.5pt
’, it considers only the first token ‘\dimen
’ to be a command; the next tokens are swept up as part of the operation, because TeX needs to know what \dimen register is to be set equal to what ⟨dimen⟩ value.
In the context of macro programming the terms "argument" and "parameter" deserve special attention:
In TeXbook, "Chapter 20: Definitions (also called Macros)" you find the statement:
Well, TeX has good news for you: Control sequences can be defined in terms of parameters, and you can supply arguments that will be substituted for the parameters.
Seems,
- a parameter(
#1
or#2
or ...) occurs in the ⟨parameter text⟩ and probably in the ⟨replacement text⟩ of a ⟨definition⟩ of a macro. - in TeX jargon an argument is a (possibly empty) collection of tokens gathered at the time of expanding an instance of a macro for within the ⟨replacement text⟩ of the macro's ⟨definition⟩ substituting each instance of the corresponding parameter (which is a specific one of
#1
or#2
or ...).
So in some sense you could say that
- a parameter is a "variable" of a single-step routine in the context of expansion-based macro programming (whereby at the time of defining the single-step routine the single-step routine is denoted by a ⟨control sequence⟩ which in the course of defining is turned into a macro-token),
- while an argument in this context can be considered the value of the variable at the time of carrying out during the stage of expansion the single-step routine denoted by the macro-token in question.
But maybe a certain restraint and caution in the use of the word "variable", when it relates to TeX but not to expl3, might help preventing ambiguities:
- The term "variable" is officially in use in expl3 jargon while expl3 jargon can be considered a strict superclass of TeX jargon / while expl3 jargon subsumes TeX jargon. But in expl3 jargon the term "variable" does not necessarily refer to the concept of "macro parameter during the stage of defining" and the term "value of variable" does not necessarily refer to the concept of "macro argument during the stage of expansion". Using the terms "variable" and "value of variable" both in expl3 jargon and in TeX jargon but not necessarily in expl3 jargon when it is about macro expansion might lead to ambiguities in the understanding of these terms.
- Using the term "variable" outside expl3 jargon may misguide into confusing programming paradigms of object-oriented/procedure-oriented/function-oriented computer-programming-languages like Pascal or C with the programming paradigms of the macro-based typesetting-language TeX, where in first place in the stage of expansion everything is about replacing collections of tokens by (other/possibly empty) collections of tokens.
- In TeX "variable"/"value of variable" could probably not only be applied to macro-programming where carrying out things is focused on the stage of expansion.
In TeX "variable"/"value of variable" could probably as well be applied to that stage of processing where assignments are carried out—actions like defining macros via\def
,\edef
,\xdef
,\xdef
,\chardef
and the like, performing assigning via\let
, assigning values to registers, etc., whereby the token whose meaning is about to be changed would be the "variable" and the current meaning or, e.g., with parameterless macros, the ⟨replacement text⟩, which with macro-tokens makes a part of the current meaning, would form the "value of that variable", or the register whose content is to be changed would be the "variable" and the current content of that register would form the "value of that variable".
Answer to: 2. Are outermost enclosing pairs of matching curly braces of undelimited arguments to be considered components of these arguments?
and
Answer to: 3. Are delimiters of delimited arguments to be considered components of these arguments?
Leaving the edge case of
#{
-notation (see below) aside for the moment, tokens at the time of expanding an instance of a macro forming components of the delimiter of a delimited argument of that instance are discarded when gathering the delimited argument.Outermost matching pairs of explicit character tokens of category 1/2 at the time of expanding an instance of a macro enclosing an undelimited argument of that instance are stripped off/discarded when gathering the argument.
(You did not ask about this, but let's mention it anyway:
The outermost pair of matching explicit character tokens of category 1/2 at the time of expanding an instance of a macro enclosing an entire delimited argument, so that the outermost enclosing explicit character token of category 2 is right at the left ;-) of the first token of the argument delimiter, is stripped off/discarded, too.
Explicit space tokens, i.e., explicit character tokens of character code 32 and category 10(space), are discarded while TeX is searching for the very first token of an undelimited argument.)
Such tokens in any case don't make it into the substitute of a ⟨replacement text⟩'s parameter while above it was said that it seems that in TeX jargon an argument is a (possibly empty) collection of tokens which at the time of expanding an instance of a macro does make it into the substitute of each instance of the corresponding parameter (#1
or #2
or...) occurring in the ⟨replacement text⟩ of the macro's ⟨definition⟩.
So, strictly spoken, it seems that such tokens are not to be considered components of arguments.
But at the time of expanding an instance of a macro outermost argument-enclosing explicit curly brace character tokens and tokens belonging to argument delimiters are means of determining the arguments of this instance=are means of determining those collections of tokens that do make it into the substitutes of corresponding parameters of the ⟨replacement text⟩ of that macro's ⟨definition⟩.
Some edge cases deserve special attention:
With
\def\foo#1\relax{\relax}
applying\show\foo
reveals:> \foo=macro: #1\relax ->\relax .
As seen in a comment which arrived prior to editing/extending this answer, the question might arise what is happening when expanding an instance of
\foo
is taking place:- Is it the case that the delimiter
\relax
is left in place in the token stream and the replacement text of that instance of\foo
is inserted right in front of that\relax
whereby insertion does not bring along a token\relax
? - Is it the case that the delimiter
\relax
is removed from the token stream in the course of gathering the delimited argument and a token\relax
coming from\foo
's ⟨definition⟩'s ⟨replacement text⟩ is inserted along with the rest of the replacement text of that instance of\foo
?
The latter is the case:
You have a macro argument, which according to the ⟨parameter text⟩ of
\foo
's ⟨definition⟩ is delimited by the token\relax
.Let's be aware that with that ⟨definition⟩ the token
\relax
definitely also occurs in the ⟨definition⟩'s ⟨replacement text⟩.Thus a token
\relax
being there after expanding an instance of\foo
is not due to the argument-delimiting token\relax
being left in place in the course of gathering the delimited argument, but is due to the ⟨definition⟩'s ⟨replacement text⟩ at the time of expanding that instance causing insertion of a replacement text which contains the token\relax
.In any case a token
\relax
being there after expanding an instance of\foo
has nothing to do with substituting a parameter of\foo
's ⟨definition⟩'s ⟨replacement text⟩.
Thus from a token\relax
being there one cannot conclude that that\relax
was component of a macro argument.- Is it the case that the delimiter
The edge case of
#{
-notation:When you do, e.g.,
\def\foo#1#{}
, then\show\foo
yields:> \foo=macro: #1{->{.
Here also the question arises what is happening during the expansion of an instance of
\foo
:- Is it the case that the delimiter
{
is left in place in the token stream and the replacement text of that instance of\foo
is inserted right in front of that{
whereby insertion does not bring along a token{
? - Is it the case that the delimiter
{
is removed from the token stream in the course of gathering the delimited argument and a token{
coming from\foo
's ⟨definition⟩'s ⟨replacement text⟩ is inserted along with the rest of the replacement text of that instance of\foo
?
The subtle difference to the previous case is that in this case the (unbalanced) token
{
is not in the ⟨replacement text⟩ of\foo
's ⟨definition⟩.In TeXbook, "Chapter 20: Definitions (also called Macros)", in one of the double dangerous bend paragraphs you find:
A special extension is allowed to these rules: If the very last character of the ⟨parameter text⟩ is
#
, so that this#
is immediately followed by{
, TeX will behave as if the{
had been inserted at the right end of both the parameter text and the replacement text.At first Ulrich Diez, the author of the versions of this answer up to September 18, 2023, got the phrase "as if ... had been inserted" wrong:
The wrong understanding of the phrase "as if ... had been inserted" was that this indicates that inserting does actually not take place, which in turn indicates that
{
is not inserted but is there due to having been left in place.According to that wrong understanding, as the token had been left in place, its being in the place after macro expansion would have nothing to do with it being delivered as a component of the substitute of a ⟨definition⟩'s ⟨replacement text⟩'s parameter.
Therefore such a token could not be considered a component of an argument.The esteemed user Skillmon in a comment kindly gave a pointer to ‘end match’ in the commented source code of Knuth's TeX program and to the routines for gathering tokens for an argument until criteria denoted by the ⟨definition⟩'s corresponding parameter are met, and explained that the correct understanding of the phrase "as if the
{
had been inserted at the right end of both the parameter text and the replacement text" is "as if both at the right end of the parameter text of the definition an{
had been inserted and at the right end of the replacement text of the definition an{
had been inserted".So studying the commented source code of Knuth's TeX program, written in WEB, was needed. The commented source code is available as a book whose title is "TeX the program". A somewhat stripped-down variant is available as a .pdf-file on CTAN: https://mirrors.ctan.org/info/knuth-pdf/tex/tex.pdf.
In tex.pdf, you find § 291:
- [...]
Here is an example macro definition that illustrates these conventions. After TeX processes the text
\def\mac a#1#2 \b {#1\−a ##1#2 #2}
the definition of \mac is represented as a token list containing
(reference count), letter a, match #, match #, spacer , \b, end match ,
out param 1, \−, letter a, spacer , mac param #, other char 1,
out param 2, spacer , out param 2.
[...]
If the parameter-matching part of a definition ends with ‘#{’, the corresponding token list will have ‘{’ just before the ‘end match’ and also at the very end. The first ‘{’ is used to delimit the parameter; the second one keeps the first from disappearing.
You need to do a bit more of delving into the code, but this is the starting point for finding out about
#{
-notation.So it seems, the latter is the case: At the time of expanding, you internally get a token list where you find the directive to grab tokens for an argument until finding a
{
-delimiter and where as last item a{
is placed as if a{
had been provided as the last item of the ⟨definition⟩'s ⟨replacement text⟩.Still a
{
being in the place after expansion has nothing to do with it being delivered as a component of the substitute of a ⟨definition⟩'s ⟨replacement text⟩'s parameter.
Therefore such a token cannot be considered a component of an argument.- Is it the case that the delimiter
-
-
Is the
\relax
in\def\foo#1\relax{\relax}
discarded when grabbing the first argument? The meaning of\def\foo#1#{}
ismacro: #1{->{.
the brace is discarded but a brace is inserted by the replacement text.– SkillmonSep 18 at 11:13 -
3
-
They are two
{
which TeX needs to handle correctly for its alignment state, and the first will be removed from the stream and the one at the end of the replacement text will rebalance the braces. Fromtex.pdf
section 394: "When the parameter delimiter ends with ‘#{
’, the token list will have a left brace both before and after the end_match. Only one of these should affect the align_state, but both will be scanned, so we must make a correction." The "had been" from the TeXbook can be understood as "had been in the definition" (which isn't possible due to balancing).– SkillmonSep 18 at 18:31 -
1This turned out as a phenomenal and very detailed answer, thank you very much @UlrichDiez for taking the time (and for having a closer look at the
#{
-notation). I have but one tiny detail that I found: In the\show\foo
output of the#{
-definition you have a space too much (between{
and.
).– SkillmonSep 19 at 7:29
#1
, and an “argument” as a value passed to a function in a parameter. Similar to this answer. DEK certainly expected his readers to be familiar with this usage. However, they’re often used interchangeably.