[Please take this question for a moot point/an "academical" issue.]
The LaTeX-kernel-command \newcommand
was invented decades before expl3, xparse and \NewDocumentCommand
were available.
\newcommand
brings along the concept of an optional argument whereby tokens forming an optional argument need to be nested between [
and ]
.
With macros defined in terms of \newcommand
that process optional arguments, only the presence of an opening square-bracket [
is detected as an indicator for the presence of an optional argument. The presence of a matching ]
is not detected.
In short you can say:
With this concept, indicator for the presence of an optional argument is the presence of an opening square-bracket [
. The optional argument itself is delimited by ]
.
Delimiting optional arguments (by ]
) can be a source of problems, e.g., (]
-)delimiter-matching when it comes to nesting optional arguments within optional arguments without being aware of the need of nesting the entire content of an optional argument between curly braces.
My question is:
Why was it decided to have optional arguments not only preceeded by a specific character-token ([12
) but also delimited by another specific character-token (]12
)?
Why optional arguments as delimited arguments?
Why optional arguments as ]12
-delimited arguments?
If delimiting was omitted, one could, instead of a preceding [
, have chosen, e.g, a preceding ?
for marking the presence of an optional argument.
Syntax of a macro \mymacro
processing an optional argument would be:
\mymacro?{optional}{non-optional}
respective \macro{non-optional}
.
(There not being a delimiter implies there not being problems with missing delimiters or delimiter-matching in case of nesting things.)
\mymacro?{optional}{non-optional}
to be a particularly intuitive syntax.[
and]
globally active and define them to be what is currently[{
and}]
. This would work fine withxparse
ifo
is redefined to bed[]
with[
and]
active.[
and active]
would still be treated/removed as parameter-text/argument-delimiters and therefore would never be carried out... Besides this: How to define a macro whose toplevel-expansion yields unbalanced curly braces? With macros you always need brace-hacks for removing/neutralizing braces and this way creating a set of unbalanced braces.Brace-hacks in turn imply several expansion-steps.\def[{\oldleftbrack\bgroup}
and\def]{\egroup\oldrightbrack}
. Commands defined withxparse
are perfectly able to respect balanced brackets, and meanwhile, stuff like\foo[key=\baz[other key=2,some third key=3]]
now works without issues.,
in your nested key list (well depending on the implementation I suppose it might help a bit, but that isn't at all clear)