Function: buildq (<L>, <expr>) Substitutes variables named by the list <L> into the expression <expr>, in parallel, without evaluating <expr>. The resulting expression is simplified, but not evaluated, after
buildq carries out the substitution.
The elements of <L> are symbols or assignment expressions
<symbol>: <value>, evaluated in parallel. That is, the binding of a variable on the right-hand side of an assignment is the binding of that variable in the context from which
buildq was called, not the binding of that variable in the variable list <L>. If some variable in <L> is not given an explicit assignment, its binding in
buildq is the same as in the context from which
buildq was called.
Then the variables named by <L> are substituted into <expr> in parallel. That is, the substitution for every variable is determined before any substitution is made, so the substitution for one variable has no effect on any other.
If any variable <x> appears as
splice (<x>) in <expr>, then <x> must be bound to a list, and the list is spliced (interpolated) into <expr> instead of substituted.
Any variables in <expr> not appearing in <L> are carried into the result verbatim, even if they have bindings in the context from which
buildq was called.
a is explicitly bound to
b has the same binding (namely 29) as in the calling context, and
c is carried through verbatim. The resulting expression is not evaluated until the explicit evaluation
(%i1) (a: 17, b: 29, c: 1729)$ (%i2) buildq ([a: x, b], a + b + c); (%o2) x + c + 29 (%i3) %; (%o3) x + 1758
e is bound to a list, which appears as such in the arguments of
foo, and interpolated into the arguments of
(%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)
The result is simplified after substitution. If simplification were applied before substitution, these two results would be the same.
(%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
The variables in <L> are bound in parallel; if bound sequentially, the first result would be
foo (b, b). Substitutions are carried out in parallel; compare the second result with the result of
subst, which carries out substitutions sequentially.
(%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)
Construct a list of equations with some variables or expressions on the left-hand side and their values on the right-hand side.
macroexpand shows the expression returned by
(%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])
Given a function of several arguments, create another function for which some of the arguments are fixed.
(%i1) curry (f, [a]) := buildq ([f, a], lambda ([[x]], apply (f, append (a, x))))$ (%i2) by3 : curry ("*", 3); (%o2) lambda([[x]], apply(*, append(, x))) (%i3) by3 (a + b); (%o3) 3 (b + a)
(%o1) true (%i2)