Macros (Manual de Maxima 5.44.0)

Siguiente: Funciones y variables para la definición de funciones, Anterior: Funciones, Subir: Definición de Funciones [Índice general][Índice]

### 36.3 Macros

Función: buildq (L, expr)

  Sustituye en paralelo las variables nombradas en la lista L en la expresión expr, sin evaluar ésta. La expresión resultante se simplifica pero no se evalúa hasta que `buildq` termine de hacer las sustituciones.

  Los elementos de L son símbolos o expresiones de asignación del tipo `symbol: value`, evaluadas en paralelo. Esto es, el valor de una variable en la parte derecha de una asignación es el valor que toma dicha variable en el contexto desde el que se invoca a `buildq`. En caso de que a una variable de L no se le haga una signación explícita, su valor en `buildq` es el mismo que tiene en el contexto desde el que se llama a `buildq`.

  Las variables referenciadas en L se sustituyen en expr en paralelo. Esto es, la sustitución para cada variable se determina antes de que se hagan las sustituciones, de forma que la sustitución de una variable no tiene efecto alguno sobre las otras.

  Si alguna variable x aparece como `splice (x)` en expr, entonces a x se le debe asignar una lista, la cual será interpolada en expr en lugar de hacer una simple sustitución; ver ejemplo más abajo.

  Cualesquiera otras variables de expr que no aparezcan en L se traspasan al resultado tal cual, incluso cuando tienen asignados valores en el contexto desde el que se llama a `buildq`.

  Ejemplos:

  `a` queda asociada explícitamente a `x`, mientras que `b` tiene la misma asociación (29) que en el contexto de llamada y `c` es traspasado al resultado sin ser sustituido. La expresión resultante no se evalúa hasta que no se le obligue a ello mediante la evaluación explícita `''%`.

      (%i1) (a: 17, b: 29, c: 1729)$
      (%i2) buildq ([a: x, b], a + b + c);
      (%o2)                      x + c + 29
      (%i3) ''%;
      (%o3)                       x + 1758

  En este ejemplo, `e` se asocia a una lista, la cual aparece como tal en los argumentos de `foo` e interpolada en los argumentos de `bar`.

      (%i1) buildq ([e: [a, b, c]], foo (x, e, y));
      (%o1)                 foo(x, [a, b, c], y)
      (%i2) buildq ([e: [a, b, c]], bar (x, splice (e), y));
      (%o2)                  bar(x, a, b, c, y)

  Como se ve a continuación, el resultado se simplifica tras las sustituciones. Si la simplificación se realizase antes que las sustituciones, ambos resultados serían iguales.

      (%i1) buildq ([e: [a, b, c]], splice (e) + splice (e));
      (%o1)                    2 c + 2 b + 2 a
      (%i2) buildq ([e: [a, b, c]], 2 * splice (e));
      (%o2)                        2 a b c

  Las variables de L se asocian en paralelo; si se hiciese secuencialmente, el primer resultado sería `foo (b, b)`. Las sustituciones se llevan a cabo en paralelo. Compárese el segundo resultado con el resultado de `subst`, que hace las sustituciones de forma secuencial.

      (%i1) buildq ([a: b, b: a], foo (a, b));
      (%o1)                       foo(b, a)
      (%i2) buildq ([u: v, v: w, w: x, x: y, y: z, z: u],
                    bar (u, v, w, x, y, z));
      (%o2)                 bar(v, w, x, y, z, u)
      (%i3) subst ([u=v, v=w, w=x, x=y, y=z, z=u],
                   bar (u, v, w, x, y, z));
      (%o3)                 bar(u, u, u, u, u, u)

  Se construye a continuación un sistema de ecuaciones con algunas variables o expresiones en el lado izquierdo y sus valores en el derecho; `macroexpand` muestra la expresión devuelta por `show_values`.

      (%i1) show_values ([L]) ::= buildq ([L], map ("=", 'L, L));
      (%o1)   show_values([L]) ::= buildq([L], map("=", 'L, L))
      (%i2) (a: 17, b: 29, c: 1729)$
      (%i3) show_values (a, b, c - a - b);
      (%o3)          [a = 17, b = 29, c - b - a = 1683]
      (%i4) macroexpand (show_values (a, b, c - a - b));
      (%o4)    map(=, '([a, b, c - b - a]), [a, b, c - b - a])

  Dada una función con varios argumentos, se crea otra función en la cual algunos argumentos son fijos.

      (%i1) curry (f, [a]) :=
              buildq ([f, a], lambda ([[x]], apply (f, append (a, x))))$
      (%i2) by3 : curry ("*", 3);
      (%o2)        lambda([[x]], apply(*, append([3], x)))
      (%i3) by3 (a + b);
      (%o3)                       3 (b + a)

Función: macroexpand (expr)

  Devuelve la macroexpansión de expr, sin evaluarla, cuando `expr` es una llamada a una función macro; en caso contrario, `macroexpand` devuelve expr.

  Si la expansión de expr devuelve otra llamada a una función macro, esta llamada también se expande.

  La función `macroexpand` no evalúa su argumento. Sin embargo, si la expansión de una llamada a función macro tiene efectos laterales, éstos se ejecutan.

  Véanse también `::=`, `macros` y `macroexpand1`.

  Ejemplos:

      (%i1) g (x) ::= x / 99;
                                          x
      (%o1)                      g(x) ::= --
                                          99
      (%i2) h (x) ::= buildq ([x], g (x - a));
      (%o2)            h(x) ::= buildq([x], g(x - a))
      (%i3) a: 1234;
      (%o3)                         1234
      (%i4) macroexpand (h (y));
                                    y - a
      (%o4)                         -----
                                     99
      (%i5) h (y);
                                  y - 1234
      (%o5)                       --------
                                     99

Función: macroexpand1 (expr)

  Devuelve la macroexpansión de expr, sin evaluarla, cuando `expr` es una llamada a una función macro; en caso contrario, `macroexpand1` devuelve expr.

  La función `macroexpand1` no evalúa su argumento. Sin embargo, si la expansión de una llamada a función macro tiene efectos laterales, éstos se ejecutan.

  Si la expansión de expr devuelve otra llamada a una función macro, esta llamada no se expande.

  Véanse también `::=`, `macros` y `macroexpand`.

  Ejemplos:

      (%i1) g (x) ::= x / 99;
                                          x
      (%o1)                      g(x) ::= --
                                          99
      (%i2) h (x) ::= buildq ([x], g (x - a));
      (%o2)            h(x) ::= buildq([x], g(x - a))
      (%i3) a: 1234;
      (%o3)                         1234
      (%i4) macroexpand1 (h (y));
      (%o4)                       g(y - a)
      (%i5) h (y);
                                  y - 1234
      (%o5)                       --------
                                     99

Variable global: macros

  Valor por defecto: `[]`

  La variable `macros` es la lista de las funciones macro definidas por el usuario. El operador de definición de funciones macro `::=` coloca la nueva función macro en esta lista, mientras que `kill`, `remove` y `remfunction` eliminan las funciones macro de la lista.

  Véase también `infolists`.

Función: splice (a)

  Interpola la lista nombrada por el átomo a dentro de una expresión, pero sólo si `splice` aparece dentro de `buildq`; en otro caso, `splice` se considera una función no definida. Si a aparece dentro de `buildq` sin `splice`, entonces queda sustituida por una lista dentro del resultado. El argumento de `splice` debe ser un átomo, no pudiendo ser una lista literal ni una expresión que devuelva una lista.

  Normalmente `splice` suministra los argumentos para una función u operador. Para una función `f`, la expresión `f (splice (a))` dentro de `buildq` se convierte en `f (a[1], a[2], a[3], ...)`. Dado un operador `o`, la expresión `"o" (splice (a)` dentro de `buildq` se convierte en `"o" (a[1], a[2], a[3], ...)`, donde `o` puede ser cualquier tipo de operador, normalmente uno que admita varios argumentos. Nótese que el operador debe ir encerrado entre comillas dobles `"`.

  Ejemplos:

      (%i1) buildq ([x: [1, %pi, z - y]], foo (splice (x)) / length (x));
                             foo(1, %pi, z - y)
      (%o1)                -----------------------
                           length([1, %pi, z - y])
      (%i2) buildq ([x: [1, %pi]], "/" (splice (x)));
                                      1
      (%o2)                          ---
                                     %pi
      (%i3) matchfix ("<>", "<>");
      (%o3)                          <>
      (%i4) buildq ([x: [1, %pi, z - y]], "<>" (splice (x)));
      (%o4)                   <>1, %pi, z - y<>

Siguiente: Funciones y variables para la definición de funciones, Anterior: Funciones, Subir: Definición de Funciones [Índice general][Índice]