> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/es/articulos-en-profundidad/17-how-does-expandafter-work-a-detailed-macro-case-study.md).

# Cómo funciona \expandafter: un estudio detallado de macros

&#x20;[Parte 1](/latex/es/articulos-en-profundidad/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Parte 2](/latex/es/articulos-en-profundidad/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Parte 3](/latex/es/articulos-en-profundidad/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Parte 4](/latex/es/articulos-en-profundidad/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Parte 5](/latex/es/articulos-en-profundidad/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Parte 6](/latex/es/articulos-en-profundidad/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)&#x20;

## Estudio de caso: ejemplo de \expandafter de The $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Manual

El $$\varepsilon\mathrm{\text{-}{\TeX}}$$ el motor de composición tipográfica se derivó del software TeX de Knuth y originalmente se pretendía que fuera un paso «intermedio» hacia el desarrollo del [Nuevo Sistema de Composición Tipográfica](https://en.wikipedia.org/wiki/New_Typesetting_System) (NTS), escrito en el lenguaje de programación Java. $$\varepsilon\mathrm{\text{-}{\TeX}}$$ se desarrolló por primera vez a finales de la década de 1990 para añadir un conjunto de nuevos comandos primitivos que proporcionan funcionalidad adicional no disponible en el programa original de Knuth. Aunque $$\varepsilon\mathrm{\text{-}{\TeX}}$$ ha recibido actualizaciones periódicas desde su lanzamiento inicial; hoy en día no se usa ampliamente como motor de composición tipográfica independiente, aunque sus innovaciones han sido absorbidas por generaciones posteriores de TeX: pdfTeX, XeTeX y LuaTeX.

El [$$\varepsilon\mathrm{\text{-}{\TeX}}$$ manual](http://mirror.ox.ac.uk/sites/ctan.org/systems/doc/etex/etex_man.pdf) contiene un ejemplo esclarecedor de una macro que hace un uso ingenioso de `\expandafter`:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter\foo
    \expandafter{\number\numexpr#1+1\expandafter}%
    \expandafter{\number#2\expandafter}%
    \fi}
```

`\foo` implementa un mecanismo de bucle, de modo que `\foo{7}{13}` produce `7, 8, 9, 10, 11, 12, 13`; sin embargo, `\foo` no utiliza ninguna *asignaciones a variables* para controlar el proceso de bucle, lo que la convierte en una macro interesante para explorar con cierto detalle.

### Algo de contexto: expresiones y asignaciones

Un elemento importante del `\foo`es el uso del comando `\numexpr`, un comando de un conjunto de cuatro primitivas relacionadas introducidas por primera vez por $$\varepsilon\mathrm{\text{-}{\TeX}}$$: `\numexpr`, `\dimexpr`, `\glueexpr` y `\muexpr`. Su propósito es construir las llamadas *expresiones* que permiten calcular/manipular valores de TeX de tipo number, dimen, glue o muglue (respectivamente). Como se analiza en las páginas 8–9 de The $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Manual, una característica importante de *expresiones* es que su evaluación (cálculo) no requiere que TeX realice ninguna *asignaciones*.

En términos de programación, una asignación es el proceso de establecer (asignar) a una variable un valor particular; por ejemplo, asignar `\count` registro `99` para contener el valor `12345` a través de `\count99=12345`. Muchos otros tipos de asignación tienen lugar durante el procesamiento de TeX —como asignar registros de tokens para contener una serie de tokens, asignar registros de caja para contener contenido de caja, y así sucesivamente.

Para realizar una asignación, como `\count99=12345`, TeX necesita activar (ejecutar) el código interno que implementa el comportamiento de `\count` o de cualquier otra primitiva que realice algún tipo de asignación. Sin embargo, hay momentos en que TeX está realizando pura *macro* y, en esos momentos, tales asignaciones no se activan—*en ese punto del procesamiento de TeX*. Ejemplos de esta situación incluyen los siguientes comandos:

* `\edef\command {*token list*}` el comando de definición de macro de «definición expandida» que expande tokens en *lista de tokens* y almacena los resultados como la definición de `\command`.
* `\write *number* {*token list*}` expande tokens en `*token list*` y los escribe en un archivo representado por `*number*`.
* `\directlua {*token list*}` este comando primitivo de LuaTeX se utiliza para pasar código Lua al intérprete Lua incorporado. Todos los tokens en `*token list*` se expanden completamente antes de pasarse al intérprete Lua para su ejecución.

#### Ejemplo rápido de \edef

Si escribimos las siguientes macros básicas:

```
     \def\mycount{\count99=12345}
     \edef\mymacro{\mycount}
```

`\edef` expandirá `\mycount` en sus tokens constituyentes, pero no va más allá: ninguno de los comandos contenidos en la definición de `\mymacro` se activará: es decir, la asignación de `12345` a `\count99` *no ocurre en este punto*; solo cuando la invoquemos `\mymacro` tendrá lugar esa asignación cuando TeX ejecute el código para procesar la `\count` primitiva. Cuando TeX está realizando *actividades de solo expansión* cualquier asignación se activará más tarde en el procesamiento de TeX, no durante el propio proceso de expansión.

#### ¿Por qué son interesantes aquí las asignaciones?

Al escribir código para realizar un bucle —en cualquier lenguaje de programación— es habitual tener una variable designada para actuar como «contador del bucle»: se usa para controlar el número de veces que se ejecuta un bucle. Normalmente el bucle se controla comprobando si esa variable designada como contador ha alcanzado un valor determinado; esa variable se incrementa (o decrementa) en cada iteración del bucle. Sin embargo, modificar una variable contador de bucle significa asignarle un nuevo valor que, en TeX, normalmente requiere el comando primitivo `\advance` para incrementar (o decrementar) un valor almacenado en un `\count` registro. Como hemos visto, durante el proceso de pura expansión de TeX tales asignaciones (incluido el incremento de variables) no pueden tener lugar: la macro `\foo` elude ingeniosamente esta restricción.

### Volvamos a explicar \foo

La macro `\foo` puede controlar el proceso de bucle *sin* sin necesidad de asignar valores a ninguna variable: controla cuántas veces tiene lugar el bucle utilizando datos surgidos de la expansión: valores de datos almacenados en listas temporales de tokens. Usando nuestro conocimiento del uso (creación) de listas temporales de tokens en TeX, podemos examinarlo más de cerca para ver exactamente cómo `\foo` consigue sus resultados.

**Recuerde**: Estamos siguiendo la ejecución de una macro después de que el texto original de su definición —contenido en un `.tex` archivo físico— haya sido escaneado (leído por TeX) y convertido en una lista de tokens que representa la definición de la macro. En esencia, seguimos el procesamiento por TeX de esos *tokens* mientras lee y procesa tokens en la definición de la macro contenida en algún lugar de la memoria de TeX. Cualquier carácter de espacio originalmente presente en el código TeX de la definición de la macro (texto dentro del `.tex` archivo) habrá sido absorbido mientras TeX escaneaba ese texto en busca de comandos (los espacios como terminadores), o se habrán convertido en tokens, como el carácter de espacio después de la coma (`,`) en `\ifnum#1<#2,` que surgió de la conversión del carácter de final de línea (`\r`) en un espacio.

Como el código TeX en `\foo` usa múltiples `\expandafter` comandos, ayudaremos a nuestra explicación añadiendo subíndices a cada `\expandafter`, indicando a cuál nos estamos refiriendo. Además, ampliaremos la notación para los tokens procesados por `\expandafter` a $$\mathrm{T^i\_1}$$ y $$\mathrm{T^i\_2}$$, representando tokens $$\mathrm{T\_1}$$ y $$\mathrm{T\_2}$$ para `\expandafter<sub>i</sub>`: `\expandafter<sub>i</sub>` $$\mathrm{T^i\_1T^i\_2}$$

Aquí está el código de la macro anotado:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

`\foo` comienza con `\number#1` que utiliza el comando expandible `\number` para convertir el valor del primer argumento en su representación tipográfica. El `\number` comando funciona generando una lista temporal de tokens que contiene tokens de caracteres que representan los dígitos individuales contenidos en el valor numérico con el que `\number` está operando. Esa lista de tokens se convierte en la siguiente fuente de entrada de TeX. Aquí, esa lista de tokens se lee y los tokens se emiten para componer tipográficamente el valor de `#1`.

A continuación, la macro realiza la prueba `\ifnum#1<#2` para comprobar si el argumento de `#1` es menor que el argumento pasado para `#2`. Si es así, se emite (componiendo tipográficamente) un token de coma (`,`) seguido de algún espacio procedente del token que se generó a partir del carácter de salto de línea después de la coma (`,`). Ese carácter de espacio se generó por primera vez cuando TeX leyó esta línea del `.tex` archivo.

La macro continúa procesando esta siguiente sección de código, que es el núcleo de su funcionamiento:

```
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

En esencia, este código genera una serie de listas temporales de tokens que dan lugar a múltiples llamadas a la `\foo` macro, terminando cuando la prueba if `\ifnum#1<#2` ya no es verdadera. Pero *cómo* se controla el bucle porque no se están realizando asignaciones: ¿dónde está el «contador del bucle»?

Empecemos mirando el código `\expandafter<sub>1</sub>\foo\expandafter<sub>2</sub>`. Nótese que usaremos la notación con subíndices `<sub>token</sub>` (o `<sub>(token)</sub>`) para recordarnos que, aquí, TeX está leyendo/procesando valores de tokens numéricos (enteros).

Aquí tenemos los siguientes tokens como entrada para `\expandafter<sub>1</sub>`:

* $$\mathrm{T^1\_1} =$$`\foo<sub>token</sub>` que se lee y se almacena para más tarde *re-inserción* de vuelta en la entrada
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>2 (token)</sub>` que se expande

Para `\expandafter<sub>2</sub>` tenemos:

* $$\mathrm{T^2\_1} =$$`{<sub>token</sub>` que se guarda para su posterior *re-inserción* de vuelta en la entrada
* $$\mathrm{T^2\_2} =$$ `\number<sub>token</sub>` que se expande

**Nota:**`\number` es un comando expandible cuyo propósito es «convertir en tokens»: es decir, convertir una cantidad numérica en una serie de tokens de caracteres que representan esa cantidad. Cuando `\number` se expande, lo primero que hace TeX es escanear la entrada buscando enteros: un proceso que desencadena una expansión adicional.

**La clave de la historia:** Aquí, `\number` está actuando sobre la *expresión* `\numexpr#1+1` que calcula el valor de `#1+1`. El resultado de ese cálculo es procesado por `\number` para convertirlo en una lista temporal de tokens que contiene tokens de caracteres que representan el valor de `#1 + 1`. Esa lista temporal de tokens, generada por `\number`, eventualmente se leerá como el primer argumento de otra llamada a `\foo`. En lugar de incrementar un contador de bucle (mediante `\advance` y la asignación), el uso de `\numexpr` crea un nuevo valor, pero sin que sea necesaria una asignación. Mediante este mecanismo, la variable que controla el bucle (`\foo`parámetro de `#1`) se incrementa y la iteración a través del bucle se controla y se termina: ¡bastante ingenioso!

A continuación, `\expandafter<sub>3</sub>` se procesa, dando como resultado:

* $$\mathrm{T^3\_1} =$$`}<sub>token</sub>` que se guarda para su posterior *re-inserción* de vuelta en la entrada
* $$\mathrm{T^3\_2} =$$`\expandafter<sub>4 (token)</sub>`, que se expande:

Para `\expandafter<sub>4</sub>` tenemos:

* $$\mathrm{T^4\_1} =$$`{<sub>token</sub>` que se guarda para su posterior *re-inserción* de vuelta en la entrada
* $$\mathrm{T^4\_2} =$$`\number<sub>token</sub>` que se expande y convierte `#2` en otra lista temporal de tokens.

Por último,`\expandafter<sub>5</sub>` se expande:

* $$\mathrm{T^5\_1} =$$`}<sub>token</sub>` que se guarda para su posterior *re-inserción* de vuelta en la entrada
* $$\mathrm{T^5\_2} =$$`\fi<sub>token</sub>`, que es un comando expandible.

  La expansión de `\fi` termina efectivamente el `\ifnum` y, en efecto, cierra esta iteración de la macro. TeX ahora completa la reinserción de todos los tokens guardados temporalmente por los múltiples `\expandafter` comandos: esto genera una serie de listas de tokens de un solo token surgidas de los tokens guardados por cada `\expandafter`. Además, TeX también ha creado listas de tokens a través de la acción de `\number`.

### Ensamblando las listas de tokens

En esencia, la `\foo` macro genera una secuencia de listas de tokens: puede pensarse en `\foo` como una «fábrica» de listas de tokens. Esas listas de tokens son leídas por TeX para convertirse en las siguientes fuentes de entrada. La parte ingeniosa está contenida en una de las acciones anteriores de `\foo`:

```
    \expandafter1\foo\expandafter2
```

mediante la cual `\foo` se las arregla para llamarse a sí misma otra vez, pero con argumentos diferentes que se almacenan en listas de tokens construidas por `\number`. Para hacer que estas listas de tokens se comporten en conjunto como una llamada a macro, las llaves `{` y `}` se han guardado todas y se han reinsertado en la entrada (como listas de un solo token) mediante las acciones de `\expandafter` comandos.

![listas de tokens generadas por la macro \foo](/files/7fdcc021bc6e32a9c91fa9dee46b951bb26df6fb)

&#x20;[Parte 1](/latex/es/articulos-en-profundidad/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Parte 2](/latex/es/articulos-en-profundidad/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Parte 3](/latex/es/articulos-en-profundidad/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Parte 4](/latex/es/articulos-en-profundidad/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Parte 5](/latex/es/articulos-en-profundidad/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Parte 6](/latex/es/articulos-en-profundidad/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/es/articulos-en-profundidad/17-how-does-expandafter-work-a-detailed-macro-case-study.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
