Nächste: , Vorige: , Nach oben: Funktionsdefinitionen   [Inhalt][Index]

25.2 Makros

Funktion: buildq (L, expr)

Die Variablen der Liste L werden in den Ausdruck expr substituiert. Die Substitution wird parallel ausgeführt. Das Ergebnis der Substitution wird vereinfacht, aber nicht ausgewertet.

Die Elemente der Liste L sind Symbole oder Zuweisungen der Form symbol: value. Die Zuweisungen werden parallel ausgewertet. Der Wert einer Variablen auf der rechten Seite einer Zuweisung ist der globale Wert in dem Kontext in dem buildq aufgerufen wird und nicht der lokale Wert einer vorhergehenden Zuweisung. Erhält eine Variable keinen Wert, dann behält die Variable den globalen Wert.

Dann werden die in der Liste L enthaltenen Variablen parallel in den Ausdruck expr substituiert.

Enthält expr Ausdrücke der Form splice(x), muss die Variable x eine Liste sein. Die Liste wird in den Ausdruck eingefügt. Siehe auch splice.

Variablen in in dem Ausdruck expr, die nicht in L enthalten sind, werden nicht durch einen Wert ersetzt, auch wenn es eine globale Variable mit demselben Namen gibt, da der Ausdruck nicht ausgewertet wird.

Beispiele:

Der Variablen a wird der Wert zugewiesen. Die Variable b erhält den globalen Wert. Die Variable c hat keinen Wert. Das Ergebnis ist ein nicht ausgewerteter Ausdruck. Die Auswertung wird mit dem Quote-Quote-Operator '' erzwungen.

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

e ist eine Liste, die einmal als Argument der Funktion foo vorliegt und zum anderen in die Argumentliste der Funktion bar eingefügt wird.

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

Das Ergebnis wird nach der Substitution vereinfacht, ansonsten hätten die beiden folgenden Beispiele dasselbe Ergebnis.

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

Die Variablen der Liste L erhalten ihren Wert parallel, ansonsten wäre das erste Ergebnis foo(b,b). Substitutionen werden parallel ausgeführt. Im Gegensatz dazu werden die Substitutionen mit der Funktion subst nacheinander ausgeführt.

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

Konstruktion einer Liste mit Gleichungen mit Variablen oder Ausdrücken auf der linken Seite und deren Werten auf der rechten Seite. Die Funktion macroexpand expandiert das Makro show_values.

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

Konstruktion einer Funktion.

(%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)
Funktion: macroexpand (expr)

Ist das Argument expr ein Makro, wird das Makro expandiert, ohne dass es ausgewertet wird. Ansonsten wird expr zurückgegeben.

Ist die Expansion des Makros selbst ein Makro, wird dieses Makro wiederholt expandiert.

macroexpand wertet das Argument expr nicht aus. Hat die Expansion des Makros Seiteneffekte, dann werden diese ausgeführt.

Siehe auch ::= und macroexpand1.

Beispiele:

(%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
Funktion: macroexpand1 (expr)

Gibt die Makro-Expansion von expr zurück, ohne das Ergebnis auszuwerten. Ist expr keine Makro-Funktion gibt macroexpand1 das Argument expr zurück.

macroexpand1 wertet das Argument nicht aus. Hat die Expansion des Makros Seiteneffekte, dann werden diese ausgeführt.

Enthält die Expansion expr wiederum Makros, werden diese im Unterschied zur Funktion macroexpand nicht expandiert.

Siehe auch ::= und macroexpand.

Beispiele:

(%i1) g (x) ::= x / 99;
                                    x
(%o1)                      g(x) ::= --
                                    99
(%i2) 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
Optionsvariable: macroexpansion

Standardwert: false

macroexpansion kontrolliert die Expansion von Makros.

false

Die Expansion des Makros wird nicht für die aufrufende Funktion ersetzt.

expand

Wird die Makro-Funktion das erste Mal ausgewertet, wird die Expansion des Makros gespeichert. Weitere Aufrufe werten das Makro nicht erneut aus. Seiteneffekte, wie Zuweisungen an globale Variablen, werden nur bei der ersten Auswertung wirksam. Die Expansion des Makros beeinflusst nicht andere Ausdrücke, die das Makro ebenfalls aufrufen.

displace

Wird die Makro-Funktion das erste mal ausgewertet, wird die Expansion des Makros in den aufrufenden Ausdruck eingesetzt. Weitere Aufrufe werten das Makro nicht erneut aus. Seiteneffekte, wie Zuweisungen an globale Variablen, werden nur bei der ersten Auswertung wirksam. Die Expansion des Makros beeinflusst nicht andere Ausdrücke, die das Makro ebenfalls aufrufen.

Beispiele:

Hat macroexpansion den Wert false, wird eine Makro-Funktion jedes mal aufgerufen, wenn der aufrufende Ausdruck ausgewertet wird. Der aufrufende Ausdruck wird nicht modifiziert.

(%i1) f (x) := h (x) / g (x);
                                  h(x)
(%o1)                     f(x) := ----
                                  g(x)
(%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                       return (x + 99));
(%o2) g(x) ::= block(print("x + 99 is equal to", x), 
                                                  return(x + 99))
(%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                       return (x - 99));
(%o3) h(x) ::= block(print("x - 99 is equal to", x), 
                                                  return(x - 99))
(%i4) macroexpansion: false;
(%o4)                         false
(%i5) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x 
                            a b - 99
(%o5)                       --------
                            a b + 99
(%i6) dispfun (f);
                                  h(x)
(%t6)                     f(x) := ----
                                  g(x)

(%o6)                         done
(%i7) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x 
                            a b - 99
(%o7)                       --------
                            a b + 99

Hat macroexpansion den Wert expand, wird eine Makro-Funktion nur einmal aufgerufen. Der aufrufende Ausdruck wird nicht modifiziert.

(%i1) f (x) := h (x) / g (x);
                                  h(x)
(%o1)                     f(x) := ----
                                  g(x)
(%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                       return (x + 99));
(%o2) g(x) ::= block(print("x + 99 is equal to", x), 
                                                  return(x + 99))
(%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                       return (x - 99));
(%o3) h(x) ::= block(print("x - 99 is equal to", x), 
                                                  return(x - 99))
(%i4) macroexpansion: expand;
(%o4)                        expand
(%i5) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x
                            a b - 99
(%o5)                       --------
                            a b + 99
(%i6) dispfun (f);
                                  h(x)
(%t6)                     f(x) := ----
                                  g(x)

(%o6)                         done
(%i7) f (a * b);
                            a b - 99
(%o7)                       --------
                            a b + 99

Hat macroexpansion den Wert displace, wird eine Makro-Funktion nur einmal aufgerufen. Der aufrufende Ausdruck wird modifiziert.

(%i1) f (x) := h (x) / g (x);
                                  h(x)
(%o1)                     f(x) := ----
                                  g(x)
(%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                       return (x + 99));
(%o2) g(x) ::= block(print("x + 99 is equal to", x), 
                                                  return(x + 99))
(%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                       return (x - 99));
(%o3) h(x) ::= block(print("x - 99 is equal to", x), 
                                                  return(x - 99))
(%i4) macroexpansion: displace;
(%o4)                       displace
(%i5) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x 
                            a b - 99
(%o5)                       --------
                            a b + 99
(%i6) dispfun (f);
                                 x - 99
(%t6)                    f(x) := ------
                                 x + 99

(%o6)                         done
(%i7) f (a * b);
                            a b - 99
(%o7)                       --------
                            a b + 99
Systemvariable: macros

Standardwert: []

Die Systemvariable macros ist eine Informationsliste, die die vom Nutzer mit dem Operator ::= definierten Makros enthält. Wird das Makro mit einer der Funktionen kill, remove oder remfunction gelöscht, wird der Eintrag aus der Informationsliste entfernt. Siehe auch die Systemvariable infolists.

Funktion: splice (a)

Die Funktion splice kann nur im Zusammenhang mit der Funktion buildq verwendet werden. Das Argument a bezeichnet eine Liste, die an Stelle von splice(a) in einen Ausdruck eingefügt wird. a kann nicht selbst eine Liste oder ein Ausdruck sein, der zu einer Liste auswertet.

Beispiele:

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

Nächste: , Vorige: , Nach oben: Funktionsdefinitionen   [Inhalt][Index]