Is there any difference between { } and bgroup and egroup ?

10 views
Skip to first unread message

Sean

unread,
Nov 26, 2009, 7:05:51 AM11/26/09
to
Or they are exactly the same

Enrico Gregorio

unread,
Nov 26, 2009, 10:34:00 AM11/26/09
to
Sean <guo.xi...@gmail.com> wrote:

> Or they are exactly the same

You can't use \bgroup and \egroup to delimit arguments, for example.
In other cases they are interchangeable, in some cases you can use
\bgroup in place of { but not \egroup in place of }. :-)

\def\xxx\bgroup some text\egroup is illegal, but
\hbox\bgroup some text\egroup is legal and this feature is very
useful.

Ciao
Enrico

Dan

unread,
Nov 26, 2009, 2:33:45 PM11/26/09
to
On Nov 26, 9:34 am, Enrico Gregorio <grego...@math.unipd.it> wrote:

> Sean <guo.xiaoy...@gmail.com> wrote:
> > Or they are exactly the same
>
> You can't use \bgroup and \egroup to delimit arguments, for example.
> In other cases they are interchangeable, in some cases you can use
> \bgroup in place of { but not \egroup in place of }. :-)
>
> \def\xxx\bgroup some text\egroup is illegal

Actually, not so much illegal as mistaken: TeX will continue scanning
for parameter text until it finds an actual "{" to start the
definition text .
Then \xxx will be a command that _must_ be used with
"\bgroup some text\egroup"
following it.

>, but
> \hbox\bgroup some text\egroup is legal and this feature is very
> useful.

It makes the LRbox environment possible. A similar feature of
\halign makes it possible for tabular to act as an environment.

Token register assignment:
\toks0=\bgroup token1 token2...}
is the example where \bgroup can replace "{", but must be
terminated with an actual "}". This use of \bgroup must be
extremely rare. I have never seen it used this way.

Note that \begingroup and \endgroup can only replace
braces as an alternative way to create a local group.
They only ever match each other.


Dan

Enrico Gregorio

unread,
Nov 26, 2009, 3:43:21 PM11/26/09
to
Dan <luec...@uark.edu> wrote:

> On Nov 26, 9:34ÔøΩam, Enrico Gregorio <grego...@math.unipd.it> wrote:
> > Sean <guo.xiaoy...@gmail.com> wrote:
> > > Or they are exactly the same
> >
> > You can't use \bgroup and \egroup to delimit arguments, for example.
> > In other cases they are interchangeable, in some cases you can use
> > \bgroup in place of { but not \egroup in place of }. :-)
> >
> > \def\xxx\bgroup some text\egroup is illegal
>
> Actually, not so much illegal as mistaken: TeX will continue scanning
> for parameter text until it finds an actual "{" to start the
> definition text .
> Then \xxx will be a command that _must_ be used with
> "\bgroup some text\egroup"
> following it.

Yes, of course. I thought best to make a white lie, than to give an
explanation not clear enough to the OP. Yours is.

Ciao
Enrico

Message has been deleted

Ulrich D i e z

unread,
Nov 26, 2009, 5:27:50 PM11/26/09
to
Dan wrote:

>On Nov 26, 9:34 am, Enrico Gregorio <grego...@math.unipd.it> wrote:
>> Sean <guo.xiaoy...@gmail.com> wrote:
>> > Or they are exactly the same
>>
>> You can't use \bgroup and \egroup to delimit arguments, for example.
>> In other cases they are interchangeable, in some cases you can use
>> \bgroup in place of { but not \egroup in place of }. :-)
>>
>> \def\xxx\bgroup some text\egroup is illegal
>
>Actually, not so much illegal as mistaken: TeX will continue scanning
>for parameter text until it finds an actual "{" to start the
>definition text .
>Then \xxx will be a command that _must_ be used with
> "\bgroup some text\egroup"
>following it.

This posting does not actually refer to the OP's question
but it is about using \bgroup (and other redefinable
catcode-1-tokens) in macro-definitions:

A few weeks ago Heiko Oberdiek pointed out that you can
define e.g., \bgroup-delimited macros where the delimiter
will _not_ be removed when grabbing the argument similar
to {-delimited macros via the #<catcode1-token>-notation.

The fun hereby is that you can let any control-sequence-
token equal to catcode-1-{, then it is a catcode-1-token.
Then you can define the macro.
Even if you afterwards redefine the catcode-1-control-
sequence, the macro will grab the argument as expected
and _leave_ the delimiter in question _in place_ - in the
example below in all cases the \foobar-token is not removed
but remains part of the message-text:


\let\foobar={
\def\test#1#\foobar argument:#1, delimiter remains in place:}
\immediate\write16{\test ARGUMENT\foobar}
\let\foobar\relax
\immediate\write16{\test ARGUMENT\foobar}
\def\foobar{That's the expansion of a nice delimiter.}
\immediate\write16{\test ARGUMENT\foobar}
\bye


As a special case, you could also write :

\def\test<parameter-text>#\bgroup definition-text}

Sincerely

Ulrich

Dan

unread,
Nov 27, 2009, 5:51:50 PM11/27/09
to
On Nov 26, 4:27 pm, Ulrich D i e z <eu_angel...@web.de> wrote:

>
> A few weeks ago Heiko Oberdiek pointed out that you can
> define e.g., \bgroup-delimited macros where the delimiter
> will _not_ be removed when grabbing the argument similar
> to {-delimited macros via the #<catcode1-token>-notation.
>
> The fun hereby is that you can let any control-sequence-
> token equal to catcode-1-{, then it is a catcode-1-token.
> Then you can define the macro.
> Even if you afterwards redefine the catcode-1-control-
> sequence, the macro will grab the argument as expected
> and _leave_ the delimiter in question _in place_ - in the
> example below in all cases the \foobar-token is not removed
> but  remains part of the message-text:
>
> \let\foobar={
> \def\test#1#\foobar argument:#1, delimiter remains in place:}
> \immediate\write16{\test ARGUMENT\foobar}
> \let\foobar\relax
> \immediate\write16{\test ARGUMENT\foobar}
> \def\foobar{That's the expansion of a nice delimiter.}
> \immediate\write16{\test ARGUMENT\foobar}
> \bye
>
> As a special case, you could also write :
>
> \def\test<parameter-text>#\bgroup definition-text}

Wow! I can't find anything in the TeXbook that would explain this.

I'm guessing this was not intentional, but rather a side effect of
the
implementation of the "#{" parameter delimiter.


Dan

Donald Arseneau

unread,
Nov 27, 2009, 7:04:01 PM11/27/09
to
On Nov 27, 2:51 pm, Dan <lueck...@uark.edu> wrote:
> On Nov 26, 4:27 pm, Ulrich  D i e z <eu_angel...@web.de> wrote:
> > A few weeks ago Heiko Oberdiek pointed out that you can
> > define e.g., \bgroup-delimited macros where the delimiter
> > will _not_ be removed when grabbing the argument similar
> > to {-delimited macros via the #<catcode1-token>-notation.
>
> > The fun hereby is that you can let any control-sequence-
> > token equal to catcode-1-{, then it is a catcode-1-token.
> > Then you can define the macro.
> > Even if you afterwards redefine the catcode-1-control-
> > sequence, the macro will grab the argument as expected
> > and _leave_ the delimiter in question _in place_

> Wow! I can't find anything in the TeXbook that would explain this.


>
> I'm guessing this was not intentional, but rather a side effect of the
> implementation of the "#{" parameter delimiter.

The implementation of #{ is just like any other delimited macro
parameter,
but to avoid consuming the left-brace (the delimiter) TeX duplicates
the
token: as the last token in the parameter list and as the last token
of the
definition. This is explained in The TeXbook and is easily seen from
\show.

Abusing the implementation is a cute trick, but it doesn't create any
new features: it is easy to do the same duplication of a cs token in
any definition

\def\foo#1#\bgroup...}

\def\foo#1\other{...\other}

Donald Arseneau

Dan

unread,
Nov 29, 2009, 12:49:14 AM11/29/09
to
On Nov 27, 6:04 pm, Donald Arseneau <a...@triumf.ca> wrote:
> On Nov 27, 2:51 pm, Dan <lueck...@uark.edu> wrote:
>
>> Wow! I can't find anything in the TeXbook that would explain this
>
> > I'm guessing this was not intentional, but rather a side effect of the
> > implementation of the "#{" parameter delimiter.
>
> The implementation of #{ is just like any other delimited macro
> parameter,
> but to avoid consuming the left-brace (the delimiter) TeX duplicates
> the
> token: as the last token in the parameter list and as the last token
> of the
> definition. This is explained in The TeXbook and is easily seen from
> \show.
>
> Abusing the implementation is a cute trick, but it doesn't create any
> new features: it is easy to do the same duplication of a cs token in
> any definition
>
> \def\foo#1#\bgroup...}
>
> \def\foo#1\other{...\other}
>
> Donald Arseneau

That's not what's strange. It's the fact that TeX treats \bgroup
different from other delimiting tokens when it really wouldn't
have to. I would have expected an error, as \bgroup is not the
same token as "{" and is also not otherwise allowed as a
"start of macro replacement text" token.

But my "Wow!" was more amazement at its discovery.

Knuth's failure (as far as I can tell) to document it
suggests strongly that this behavior was not intentional.


Dan

David Kastrup

unread,
Nov 29, 2009, 2:46:37 AM11/29/09
to
Dan <luec...@uark.edu> writes:

> On Nov 27, 6:04�pm, Donald Arseneau <a...@triumf.ca> wrote:
>> On Nov 27, 2:51�pm, Dan <lueck...@uark.edu> wrote:
>>
>> Abusing the implementation is a cute trick, but it doesn't create any
>> new features: it is easy to do the same duplication of a cs token in
>> any definition
>>
>> \def\foo#1#\bgroup...}
>>
>> \def\foo#1\other{...\other}
>>
>> Donald Arseneau
>
> That's not what's strange. It's the fact that TeX treats \bgroup
> different from other delimiting tokens when it really wouldn't have
> to.

What makes you think it does? For analyzing the parameter string, TeX
does not distinguish implicit and explicit tokens (the distinction is
only made during parameter matching when calling the macro). For
example, you can also say

\let\arg#

\def\zap\arg1\arg2\arg3{\message{\arg1\arg2\arg3}}

\zap abc
\show\zap

--
David Kastrup
UKTUG FAQ: <URL:http://www.tex.ac.uk/cgi-bin/texfaq2html>

Robin Fairbairns

unread,
Nov 29, 2009, 3:36:34 PM11/29/09
to

that one i find less surprising. i suppose i'm being na\"if?
--
Robin Fairbairns, Cambridge

Dan

unread,
Nov 30, 2009, 12:33:28 AM11/30/09
to
On Nov 29, 1:46 am, David Kastrup <d...@gnu.org> wrote:

> Dan <lueck...@uark.edu> writes:
> > On Nov 27, 6:04 pm, Donald Arseneau <a...@triumf.ca> wrote:
> >> On Nov 27, 2:51 pm, Dan <lueck...@uark.edu> wrote:
>
> >> Abusing the implementation is a cute trick, but it doesn't create any
> >> new features: it is easy to do the same duplication of a cs token in
> >> any definition
>
> >> \def\foo#1#\bgroup...}
>
> >> \def\foo#1\other{...\other}
>
> >> Donald Arseneau
>
> > That's not what's strange. It's the fact that TeX treats \bgroup
> > different from other delimiting tokens when it really wouldn't have
> > to.
>
> What makes you think it does?

\def\foo#1#\relax generates an error
\def\foo#1#\bgroup does not

Plus, I didn't realize the following:

>
> For analyzing the parameter string, TeX
> does not distinguish implicit and explicit tokens

This is only true to a limited extent: implicit # are treated
as #, but \bgroup is not treated as {, except in this one case:
"#\bgroup" is analyzed like "#{".

Also, it is natural to expect (and the TeXbook doesn't seem
to contradict this) that the "#" of "#{" is the last of the
<parameter text> and the "{" is the <left brace> in the
following (from the TeXbook, Chapter 24, in which the left
brace is required to be explicit):

<definition text> --> <parameter text><left brace>
<balanced text><right brace>

Here <control sequence> denotes a token that is either
a control sequence or an active character; <left brace>
and <right brace> are explicit character tokens whose
category codes are respectively of types 1 and~2. The
<parameter text> contains no <left brace> or
<right brace> tokens, and it obeys the rules of Chapter~20.

Chapter 20 is also does not contradict this interpretation.

Finally, I cannot find any statement in the TeXbook that TeX
does not distinguish implicit and explicit characters in
analysing parameter text.

Chapter 20 doesn't even contain the work "implicit" and the quote
above (along with the remainder of the explanatory paragraph)
fails to mention implicit characters, despite that Knuth writes
earlier in chapter 24:

When \TeX's syntax allows both explicit and implicit
characters, the rules below will be careful to say so,
explicitly.


Dan

Donald Arseneau

unread,
Nov 30, 2009, 10:11:11 AM11/30/09
to
On Nov 29, 9:33 pm, Dan <lueck...@uark.edu> wrote:

> \def\foo#1#\relax generates an error
> \def\foo#1#\bgroup does not

To focus on the interesting part:

\def\foo#1\bgroup generates an error but
\def\foo#1#\bgroup does not.

> > For analyzing the parameter string, TeX
> > does not distinguish implicit and explicit tokens
>
> This is only true to a limited extent: implicit # are treated
> as #, but \bgroup is not treated as {, except in this one case:
> "#\bgroup" is analyzed like "#{".

But David specifically stipulated "For analyzing the parameter string"
not the replacement text.

The behavior makes programming sense: when there is a # character
(catcode 6 token) check the next character (token) for a digit or {.
Such checking typically treats implicit and explicit the same.

> Finally, I cannot find any statement in the TeXbook that TeX
> does not distinguish implicit and explicit characters in
> analysing parameter text.

Yes, there are several innocuous obscure behaviors that are
not documented in the TeXbook, but were intended.

If you are hunting for a bug, then go ahead and report it;
I'm confident it is no bug. I'm not disagreeing that it is
an interesting anomaly, but I'm less surprised than you are.
I was disappointed it did not confer new abilities (like the
\expandafter\ifx\noexpand "bug" does).

Donald Arseneau

Dan Luecking

unread,
Nov 30, 2009, 4:12:38 PM11/30/09
to
On Mon, 30 Nov 2009 07:11:11 -0800 (PST), Donald Arseneau
<as...@triumf.ca> wrote:

>On Nov 29, 9:33 pm, Dan <lueck...@uark.edu> wrote:
>
>> \def\foo#1#\relax generates an error
>> \def\foo#1#\bgroup does not
>
>To focus on the interesting part:
>
>\def\foo#1\bgroup generates an error but
>\def\foo#1#\bgroup does not.
>
>> > For analyzing the parameter string, TeX
>> > does not distinguish implicit and explicit tokens
>>
>> This is only true to a limited extent: implicit # are treated
>> as #, but \bgroup is not treated as {, except in this one case:
>> "#\bgroup" is analyzed like "#{".
>
>But David specifically stipulated "For analyzing the parameter string"
>not the replacement text.

Which is why I included some stuff that you found uninteresting:
The syntax diagram in Chapter 24 suggests that "{" is never part
of the parameter string.

Also, I never mentioned replacement text. A definition consists
of a <cs> folloeded by <parameter text> followed by an explicit
<left brace> followed by <replacement text> followed by an explicit
<right brace>. And I discussed only <parameter text><left brace>

Now I see that my original statement is at least partly correct:
that this is a side effect of the implementation (see below).
(Whether Knuth knew about it or intended it is still unsettled.)

>
>The behavior makes programming sense: when there is a # character
>(catcode 6 token) check the next character (token) for a digit or {.
>Such checking typically treats implicit and explicit the same.

This is a reasonable implementation, but another would have been
to always check for an _explicit_ left brace, and have that (as the
syntax diagram suggests) put an end to the parameter text. Then go
back and process the ending #. Your description would allow
#1#\bgroup replacement text}
whereas mine would allow only
#1\bgroup{replacement text}
or
#1#{replacement text}
(with different meanings).


Dan
To reply by email, change LookInSig to luecking

Reply all
Reply to author
Forward
0 new messages