Beamer alt command like visible instead of like only

Following up the discussion of diabonas answer, here my suggestion. The idea to use phantom boxes seems the way to go. Here the two alternatives are boxed so that they can be measured. The code could be improved to detect the mode (text, math, display math, etc.) by itself and avoid the re-boxing which happens in the phantom commands.

\documentclass{beamer}
\newcommand<>\Alt[2]{{%
    \sbox0{$\displaystyle #1$}%
    \sbox1{$\displaystyle #2$}%
    \alt#3%
        {\rlap{\usebox0}\vphantom{\usebox1}\hphantom{\ifnum\wd0>\wd1 \usebox0\else\usebox1\fi}}%
        {\rlap{\usebox1}\vphantom{\usebox0}\hphantom{\ifnum\wd0>\wd1 \usebox0\else\usebox1\fi}}%
}}

\begin{document}
\begin{frame}
\begin{align*}
y &= \frac{(x^2+1)\sqrt{x+3}}{x-1} \\
\ln y &= \ln (x^2+1) + \frac{1}{2} \ln(x+3) - \ln(x-1) \\
\frac{1}{y} \frac{dy}{dx}
      &= \frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\end{align*}
So
\[
\begin{split}
\frac{dy}{dx} &= \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right)
\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}
\end{split}
\]
\end{frame}
\end{document}

Here the version which checks the mode and math-style automatically. It works in all math and text modes:

\documentclass{beamer}

\makeatletter
% Detect mode. mathpalette is used to detect the used math style
\newcommand<>\Alt[2]{%
    \begingroup
    \ifmmode
        \expandafter\mathpalette
        \expandafter\math@Alt
    \else
        \expandafter\make@Alt
    \fi
    {{#1}{#2}{#3}}%
    \endgroup
}

% Un-brace the second argument (required because \mathpalette reads the three arguments as one
\newcommand\math@Alt[2]{\math@@Alt{#1}#2}

% Set the two arguments in boxes. The math style is given by #1. \m@th sets \mathsurround to 0.
\newcommand\math@@Alt[3]{%
    \setbox\z@ \hbox{$\m@th #1{#2}$}%
    \setbox\@ne\hbox{$\m@th #1{#3}$}%
    \@Alt
}

% Un-brace the argument
\newcommand\make@Alt[1]{\make@@Alt#1}

% Set the two arguments into normal boxes
\newcommand\make@@Alt[2]{%
    \sbox\z@ {#1}%
    \sbox\@ne{#2}%
    \@Alt
}

% Place one of the two boxes using \rlap and place a \phantom box with the maximum of the two boxes
\newcommand\@Alt[1]{%
    \alt#1%
        {\rlap{\usebox0}}%
        {\rlap{\usebox1}}%
    \setbox\tw@\null
    \ht\tw@\ifnum\ht\z@>\ht\@ne\ht\z@\else\ht\@ne\fi
    \dp\tw@\ifnum\dp\z@>\dp\@ne\dp\z@\else\dp\@ne\fi
    \wd\tw@\ifnum\wd\z@>\wd\@ne\wd\z@\else\wd\@ne\fi
    \box\tw@
}

\makeatother

\begin{document}

% Test the different modes and math styles
\begin{frame}
Display:
\[
\begin{split}
\frac{dy}{dx} &= \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right)
\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}.
\end{split}
\]

In-Text:
\(
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right)
\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}.
\)

Subscript:
\(
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}.
\)
\[
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}.
\]

Sub-Subscript:
\(
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}}.
\)
\[
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}}.
\]

Text-mode:
XXXX  \Alt<2>{aaaaa}{Ag}.


\end{frame}
\end{document}

The dots at the end are to visualize the constant width only.

Result


The second \Alt command in Martin Scharrer's answer is excellent; however, it can cause problems when used with Beamer's incremental overlay specifications (e.g., <+>). This is because Martin's implementation invokes the underlying \alt command using \mathpalette. \mathpalette internally uses \mathchoice, which actually typesets the contents given for each of the four math styles before deciding which to use in the final output.

Example of the issue

\documentclass{beamer}

% [Paste Martin's second set of `\Alt` macros here.]

\begin{document}

\begin{frame}
  \begin{itemize}
    \item Some stuff\dots

      \pause

    \item An equation I'll reveal in pieces:
      \[
        \frac{-4}{2} + \frac{9}{3} =
        \Alt<+>{
          \vcenter{\hbox{ ?\thinspace?}}
        }{
          \frac{-4 + 9}{2 + 3} = 1.
        }
      \]

      \pause

    \item Some more stuff\dots
  \end{itemize}
\end{frame}

\end{document}

Compiling this code yields a document with seven slides rather than the desired four, as TeX is executing the Beamer \alt macro---and thus incrementing the beamerpauses counter---four times rather than one.

Solving the problem

Move the \alt invocation outside of \mathpalette/\mathchoice. Unfortunately, this means that the new \Alt command's arguments will be typeset eight times (four for each of the \alt macro's two arguments) rather than four times as in Martin's code, but the added overhead seems necessary to make \Alt behave the same as \alt with respect to incremental overlays.

Also, it's a minor thing, but adding a \leavevmode before typesetting the \Alt content box seems to make the command behave a bit less surprisingly in some cases, e.g., at the start of a list item.

Revised code (supports incremental overlays)

\usepackage{etoolbox} % For `\ifbool`, `\ifnumcomp`.

\makeatletter
\newcommand*\Alt{\alt{\Alt@branch0}{\Alt@branch1}}

\newcommand\Alt@branch[3]{%
  \begingroup
  \ifbool{mmode}{%
    \mathchoice{%
      \Alt@math#1{\displaystyle}{#2}{#3}%
    }{%
      \Alt@math#1{\textstyle}{#2}{#3}%
    }{%
      \Alt@math#1{\scriptstyle}{#2}{#3}%
    }{%
      \Alt@math#1{\scriptscriptstyle}{#2}{#3}%
    }%
  }{%
    \sbox0{#2}%
    \sbox1{#3}%
    \Alt@typeset#1%
  }%
  \endgroup
}

\newcommand\Alt@math[4]{%
  \sbox0{$#2{#3}\m@th$}%
  \sbox1{$#2{#4}\m@th$}%
  \Alt@typeset#1%
}

\newcommand\Alt@typeset[1]{%
  \ifnumcomp{\wd0}{>}{\wd1}{%
    \def\setwider   ##1##2{##2##1##2 0}%
    \def\setnarrower##1##2{##2##1##2 1}%
  }{%
    \def\setwider   ##1##2{##2##1##2 1}%
    \def\setnarrower##1##2{##2##1##2 0}%
  }%
  \sbox2{}%
  \sbox3{}%
  \setwider2{\wd}%
  \setwider2{\ht}%
  \setwider2{\dp}%
  \setnarrower3{\ht}%
  \setnarrower3{\dp}%
  \leavevmode
  \rlap{\usebox#1}%
  \usebox2%
  \usebox3%
}
\makeatother

As a further revision to Martin Scharrer's and bcat's nifty answers, here is a version that allows one to specify the position (l, c, or r) of the smaller text within the larger box:

\usepackage{etoolbox}
\usepackage{mathtools}

\makeatletter
% Detect mode. mathpalette is used to detect the used math style
\newcommand<>\Alt[3][l]{%
  \begingroup
    \providetoggle{Alt@before}%
    \alt#4{\toggletrue{Alt@before}}{\togglefalse{Alt@before}}%
    \ifbool{mmode}{%
      \expandafter\mathpalette
      \expandafter\math@Alt
    }{%
      \expandafter\make@Alt
    }%
    {{#1}{#2}{#3}}%
  \endgroup
}

% Un-brace the second argument (required because \mathpalette reads the three arguments as one
\newcommand\math@Alt[2]{\math@@Alt{#1}#2}

% Set the two arguments in boxes. The math style is given by #1. \m@th sets \mathsurround to 0.
\newcommand\math@@Alt[4]{%
  \setbox\z@ \hbox{$\m@th #1{#3}$}%
  \setbox\@ne\hbox{$\m@th #1{#4}$}%
  \@Alt{#2}%
}

% Un-brace the argument
\newcommand\make@Alt[1]{\make@@Alt#1}

% Set the two arguments into normal boxes
\newcommand\make@@Alt[3]{%
  \sbox\z@ {#2}%
  \sbox\@ne{#3}%
  \@Alt{#1}%
}

% Place one of the two boxes using \rlap and place a \phantom box with the maximum of the two boxes
\newcommand\@Alt[1]{%
  \setbox\tw@\null
  \ht\tw@\ifnum\ht\z@>\ht\@ne\ht\z@\else\ht\@ne\fi
  \dp\tw@\ifnum\dp\z@>\dp\@ne\dp\z@\else\dp\@ne\fi
  \wd\tw@\ifnum\wd\z@>\wd\@ne\dimexpr\wd\z@/2\relax\else\dimexpr\wd\@ne/2\relax\fi
  %
  \ifstrequal{#1}{l}{%
    \rlap{\iftoggle{Alt@before}{\usebox\z@}{\usebox\@ne}}%
    \copy\tw@
    \box\tw@
  }{%
    \ifstrequal{#1}{c}{%
      \copy\tw@
      \clap{\iftoggle{Alt@before}{\usebox\z@}{\usebox\@ne}}%
      \box\tw@
    }{%
      \ifstrequal{#1}{r}{%
        \copy\tw@
        \box\tw@
        \llap{\iftoggle{Alt@before}{\usebox\z@}{\usebox\@ne}}%
      }{%
      }%
    }%
  }%
}
\makeatother

Unlike bcat's macro, I use \mathpalette and avoid the bug in Martin's answer by toggling a flag inside \alt; the flag says whether the first or second argument of \Alt should be set.

This was my first attempt at writing a nontrivial macro involving plain TeX, so please let me know if there are better style practices I should use.