11

Desired behavior

\{ and \} should turn into \left\{ and \right\{.

Attempt 1

\edef\{{\left\{}
\edef\}{\right\}}

Error message

TeX capacity exceeded, sorry [input stack size=5000].

\font@name ->
             \OT1/cmr/m/n/10 
l.16 \edef\{{\left\{
                    }
If you really absolutely need more capacity,
you can ask a wizard to enlarge me.

Attempt 2

\documentclass{standalone}

\edef\{{\left\string{}
\edef\}{\right\string}}

\begin{document}
$\{\}$
\end{document}

Result

– ̋

Error message

Missing delimiter (. inserted).

<to be read again> 
                   {
l.7 $\{
       \}$
I was expecting to see something like `(' or `\{' or
`\}' here. If you typed, e.g., `{' instead of `\{', you
should probably delete the `{' by typing `1' now, so that
braces don't get unbalanced. Otherwise just proceed.
Acceptable delimiters are characters whose \delcode is
nonnegative, or you can use `\delimiter <delimiter code>'.

! Missing delimiter (. inserted).
<to be read again> 
                   }
l.7 $\{\}
         $
I was expecting to see something like `(' or `\{' or
`\}' here. If you typed, e.g., `{' instead of `\{', you
should probably delete the `{' by typing `1' now, so that
braces don't get unbalanced. Otherwise just proceed.
Acceptable delimiters are characters whose \delcode is
nonnegative, or you can use `\delimiter <delimiter code>'.

Attempt 3

\documentclass{standalone}

\edef\{{\left\string\{}
\edef\}{\right\string\}}

\begin{document}
$\{\}$
\end{document}

Output

\–\ ̋

Related, working solutions

Doing this for \langle and \rangle works just fine:

\edef\langle{\left\langle}
\edef\rangle{\right\rangle}

Even doing this for ( and ) is a bit more complicated, but works:

\begingroup
    \catcode`(\active
    \xdef({\left\string(}
    \catcode`)\active
    \xdef){\right\string)}
\endgroup
\mathcode`(="8000
\mathcode`)="8000
  • 3
    Of course this can be done, but it's not really a good idea. See Is it ever bad to use \left and \right?. – barbara beeton May 27 at 18:10
  • 1
    You could use \DeclarePairedDelimiter from mathtools to define \braced{{x_i}^2}. – Davislor May 27 at 21:10
  • @Davislor True. It's still messier than just \{x_i^2\}, IMO. – Solomon Ucko May 27 at 21:12
  • 2
    @SolomonUcko I would strongly advise against redefining standard TeX syntax to mean something different. First, it makes the code impossible to read because the syntax means something different from what anyone reading it thinks it does. Second, any code you copy-and-paste to a new document or a new template will silently break. Third, you disable the ability to control the sizing of your braces if you want to. – Davislor May 27 at 22:31
7

The usual trick is to \let the old command to an "orig" version and use it in the definition of a changed command:

\let\leftbraceOrig=\{
\let\rightbraceOrig=\}
\def\{{\left\leftbraceOrig}
\def\}{\right\rightbraceOrig}

Result:

\begin{equation}
\{\int_{-\infty}^\infty \frac{e^{-x^2}}{2} dx \}
\end{equation}

enter image description here

  • 3
    Not really. You break usage of \{ and \} in text mode. – egreg May 29 at 9:06
  • I stand corrected – Boris May 29 at 16:20
11

It's a very bad idea, really. See Is it ever bad to use \left and \right?

However, we can find the definitions of \{ and \} in latex.ltx and see

\DeclareRobustCommand{\{}{\ifmmode\lbrace\else\textbraceleft\fi}
\DeclareRobustCommand{\}}{\ifmmode\rbrace\else\textbraceright\fi}

so it's quite simple: add

\let\{\relax \let\}\relax
\DeclareRobustCommand{\{}{\ifmmode\left\lbrace\else\textbraceleft\fi}
\DeclareRobustCommand{\}}{\ifmmode\right\rbrace\else\textbraceright\fi}

to your document preamble. The first line is to avoid warnings about the redefinition. This still allows using \{ and \} in text mode (without \left and \right, of course, which wouldn't make sense in that context).

Much better is to load mathtools and do

\DeclarePairedDelimiter{\braces}{\{}{\}}

so you can do

\braces{x} \braces[\big]{x} \braces[\Big]{x} \braces[\bigg]{x} \braces[\Bigg]{x}

for manual size selection of

\braces*{x}

for automatic size selection.

Your attempts

Attempt 1

For \edef\{{\left\{} we need to check the various expansion steps. The first level expansion of \{ is

\x@protect\{\protect\{•

(the bullet stands for a space in the control sequence name). The next expansion step is

\ifx\protect\@typeset@protect\else\@x@protect\{\fi\protect\{•

In the document preamble, \protect is the same as \@typeset@protect (both are \relax), so the true branch is followed, yielding nothing, so you end up with

\protect\{•

that becomes

\protect\ifmmode \lbrace \else \textbraceleft \fi

(because \protect is not expandable). Since you are not in math mode, the false branch is followed, leading to

\protect\textbraceleft

(there should be a trailing \fi, but that's eventually disappearing, because \edef does full expansion). It's not finished, yet, because we need to know what \textbraceleft does. We get

\protect\OMS-cmd \textbraceleft \OMS\textbraceleft

Oh, well, what's this? \OMS-cmd is something that should never appear inside an \edef, because it wants to perform assignments.

You're doomed.

Attempt 2

Your \edef\{{\left\string{} defines \{ to be \left{ (where the brace is turned into a “printable character”). This is illegal, because { as a printable character has its \delcode set to −1, so you get a “missing delimiter” error at \{.

Attempt 3

With \edef\{{\left\string\{} you get a puzzling output. You are actually applying \left to a backslash of category code 12 and this has a positive \delcode, namely "26E30F meaning that character "6E from math family 2 is used if no sizing is needed (the symbol font has indeed a backslash there) or character "0F from math family 3 otherwise (and again you get a backslash). The left brace tells TeX to print use the math code "007B, so the character in slot "7B from math family 0, which is the ordinary text font and contains the en-dash at that slot.

Why does \edef\langle{\left\langle} work?

Because \langle is defined in a very different way: its definition is

\delimiter"426830A

(with a space at the end) and so the \edef just does the same as

\def\langle{\left\delimiter"426830A }

because the expansion of \langle consists of unexpandable tokens.

  • Thanks for the very detailed explanations! Unless I'm mistaken, your last line should read \def\langle{\left\delimiter"426830A } (note the space) because \langle is defined by \def\langle{\delimiter"426830A } in order to make sure the 〈number〉 is finished. Unrelated: you might want to add to your explanations that \left and \delimiter are unexpandable (I can do it in an edit if you prefer). – frougon May 29 at 10:44
  • @frougon Yes, there should be a space at the end. – egreg May 29 at 12:36
  • @egreg Thank you very much for the esaustive answer. Is it possibile to define similar macros for round brackets and square brackets? Right now I'm looking for definitions of (, ), [ and ] in latex.ltx but it's a very long file and I don't know exactly what to look for. – sound wave Aug 14 at 23:41
4

The cause of your problem is that LaTeX defines \{ as \ifmmode\lbrace \else\textbraceleft\fi. If you are using LaTeX then your \edef goes to the branch \textbraceleft.

But you can define:

\edef\{{\left\lbrace}
\edef\}{\right\rbrace}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.