(maxima.info)Macros


Next: Functions and Variables for Function Definition Prev: Function Up: Function Definition
Enter node , (file) or (file)node

36.3 Macros
===========

 -- 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.

     Examples

     'a' is explicitly bound to 'x', while '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 '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)

     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 '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])

     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([3], x)))
          (%i3) by3 (a + b);
          (%o3)                       3 (b + a)

 -- Function: macroexpand (<expr>)

     Returns the macro expansion of <expr> without evaluating it, when
     'expr' is a macro function call.  Otherwise, 'macroexpand' returns
     <expr>.

     If the expansion of <expr> yields another macro function call, that
     macro function call is also expanded.

     'macroexpand' quotes its argument.  However, if the expansion of a
     macro function call has side effects, those side effects are
     executed.

     See also '::=', 'macros', and 'macroexpand1'..

     Examples

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

 -- Function: macroexpand1 (<expr>)

     Returns the macro expansion of <expr> without evaluating it, when
     'expr' is a macro function call.  Otherwise, 'macroexpand1' returns
     <expr>.

     'macroexpand1' quotes its argument.  However, if the expansion of a
     macro function call has side effects, those side effects are
     executed.

     If the expansion of <expr> yields another macro function call, that
     macro function call is not expanded.

     See also '::=', 'macros', and 'macroexpand'.

     Examples

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

 -- Global variable: macros
     Default value: '[]'

     'macros' is the list of user-defined macro functions.  The macro
     function definition operator '::=' puts a new macro function onto
     this list, and 'kill', 'remove', and 'remfunction' remove macro
     functions from the list.

     See also 'infolists'.

 -- Function: splice (<a>)

     Splices (interpolates) the list named by the atom <a> into an
     expression, but only if 'splice' appears within 'buildq';
     otherwise, 'splice' is treated as an undefined function.  If
     appearing within 'buildq' as <a> alone (without 'splice'), <a> is
     substituted (not interpolated) as a list into the result.  The
     argument of 'splice' can only be an atom; it cannot be a literal
     list or an expression which yields a list.

     Typically 'splice' supplies the arguments for a function or
     operator.  For a function 'f', the expression 'f (splice (<a>))'
     within 'buildq' expands to 'f (<a>[1], <a>[2], <a>[3], ...)'.  For
     an operator 'o', the expression '"o" (splice (<a>))' within
     'buildq' expands to '"o" (<a>[1], <a>[2], <a>[3], ...)', where 'o'
     may be any type of operator (typically one which takes multiple
     arguments).  Note that the operator must be enclosed in double
     quotes '"'.

     Examples

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


automatically generated by info2www version 1.2.2.9