Maxima Manual: Макросы

Next: Функции и переменные для определения функций, Previous: Функции, Up: Определение функций [Contents][Index]

### 37.3 Макросы

Функция: buildq (L, expr)

  Подставляет значения переменных, определяемых списком L, в выражение expr параллельно без перевычисления expr. Результирующее выражение упрощается, но не вычисляется после выполнения `buildq`.

  Элементы списка L являются символами или операторами присваивания `symbol: value`, вычисляемые параллельно. Т.е. значение переменных в правой части присваиваний вычисляются в контексте, в котором вызван `buildq`, но не в контексте списка присваиваний L. Если для некоторых переменных в списке L не задано значений, то для них сохраняются значения из контекста вызова `buildq`.

  Переменные из списка L подставляются в expr параллельно. Т.е. значение каждой подстановки определяется до подстановки, и одна переменная не оказывает никакого влияния на другую.

  Если переменная x присутствует в expr в виде `splice (x)`, то x должна иметь значение в форме списка, и этот список будет вместо подстановки интерполирован в expr.

  Любые другие переменные в expr, не присутствующие в L, переносятся в результат буквально без изменения, даже в том случае, когда имеют значение в контексте вызова `buildq`.

  Примеры:

  Переменной `a` явно присвоено значение `x`, тогда как `b` имеет значение (а именно 29) из контекста вызова, а `c` сохраняется неизменным. Результат остается невычисленным до явного применения `''%`.

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

  Переменная `e` равна списку, который подставляется в `foo` и интерполируется в `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)

  Результат подстановки упрощается. Если бы упрощение выполнилось до подстановки, то нижеследующие результаты совпали бы.

      (%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

  Значения переменных в L присваиваются параллельно, при последовательном присваивании первый результат был бы равен `foo (b, b)`. Подстановки осуществляются параллельно. Сравните второй результат с результатом функции `subst`, которая выполняет подстановки последовательно.

      (%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)

  Составим список уравнений с переменными в левой части и со значениями этих переменных в правой. Функция `macroexpand` выводит выражение, возвращаемое `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])

  Используя функцию нескольких аргументов, создадим другую функцию, у которой некоторые аргументы имеют фиксированное значение.

      (%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)

  Категории:Определение функций ·

Функция: macroexpand (expr)

  Если `expr` является вызовом макро-функции, то `macroexpand` возвращает макро-расширение expr без его вычисления. В противном случае, `macroexpand` возвращает expr.

  Если макро-расширение expr само является макро-вызовом, то оно тоже раскрывается.

  Функция `macroexpand` не вычисляет свои аргументы. Но если раскрытие макро-функций приводит к побочным эффектам, то эти эффекты выполняются.

  См. также `::=`, `macros` и `macroexpand1`.

  Примеры

      (%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

  Категории:Применение функций ·

Функция: macroexpand1 (expr)

  Если `expr` является вызовом макро-функции, то `macroexpand1` возвращает макро-расширение expr без его вычисления. В противном случае, `macroexpand1` возвращает expr.

  Функция `macroexpand1` не вычисляет свои аргументы. Но если раскрытие макро-функций приводит к побочным эффектам, то эти эффекты выполняются.

  Если макро-расширение expr само является макро-вызовом, то оно не раскрывается.

  См. также `::=`, `macros` и `macroexpand`.

  Примеры:

      (%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

  Категории:Применение функций ·

Глобальная переменная: macros

  Значение по умолчанию: `[]`

  `macros` есть список всех определенных пользователем макро-функций. Оператор определения макро-функции `::=` добавляет новую макро-функцию к этому списку, а `kill`, `remove` и `remfunction` удаляют ее из него.

  См.также `infolists`.

  Категории:Определение функций ·Глобальные переменные ·

Функция: splice (a)

  Интерполирует список, обозначенный атомом a в выражение, но только если `splice` присутствует внутри `buildq`. В противном случае `splice` рассматривается как неопределенная функция. Если переменная a присутствует внутри `buildq` сама по себе без `splice`, то вместо a подставляется (не интерполируется) соответствующий список. Аргументом `splice` может быть только атом, но не явный список или выражение, дающее список в качестве значения.

  Обычно, `splice` применяется для задания аргументов функции или оператора. Для функции `f`, выражение `f (splice (a))` внутри `buildq` преобразуется в `f (a[1], a[2], a[3], ...)`. Для оператора `o`, выражение `"o" (splice (a)` внутри `buildq` преобразуется в `"o" (a[1], a[2], a[3], ...)`, где `o` может быть оператором любого вида (обычно оператором с многими аргументами). Обратите внимание, что оператор должен быть заключен в двойные кавычки `"`.

  Примеры:

      (%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<>

  Категории:Определение функций ·

Next: Функции и переменные для определения функций, Previous: Функции, Up: Определение функций [Contents][Index]