Next: Функции и переменные для определения функций, Previous: Функции, Up: Определение функций [Contents][Index]
Подставляет значения переменных, определяемых списком 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)
Если 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
Если 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 есть список всех определенных пользователем макро-функций.
Оператор определения макро-функции ::= добавляет новую макро-функцию к этому списку,
а kill, remove и remfunction удаляют ее из него.
См.также infolists.
Интерполирует список, обозначенный атомом 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]