Next: , Previous: , Up: Top   [Contents][Index]

7 Operators


Next: , Previous: , Up: Operators   [Contents][Index]

7.1 Introduction to operators

It is possible to define new operators with specified precedence, to undefine existing operators, or to redefine the precedence of existing operators. An operator may be unary prefix or unary postfix, binary infix, n-ary infix, matchfix, or nofix. "Matchfix" means a pair of symbols which enclose their argument or arguments, and "nofix" means an operator which takes no arguments. As examples of the different types of operators, there are the following.

unary prefix

negation - a

unary postfix

factorial a!

binary infix

exponentiation a^b

n-ary infix

addition a + b

matchfix

list construction [a, b]

(There are no built-in nofix operators; for an example of such an operator, see nofix.)

The mechanism to define a new operator is straightforward. It is only necessary to declare a function as an operator; the operator function might or might not be defined.

An example of user-defined operators is the following. Note that the explicit function call "dd" (a) is equivalent to dd a, likewise "<-" (a, b) is equivalent to a <- b. Note also that the functions "dd" and "<-" are undefined in this example.

(%i1) prefix ("dd");
(%o1)                          dd
(%i2) dd a;
(%o2)                         dd a
(%i3) "dd" (a);
(%o3)                         dd a
(%i4) infix ("<-");
(%o4)                          <-
(%i5) a <- dd b;
(%o5)                      a <- dd b
(%i6) "<-" (a, "dd" (b));
(%o6)                      a <- dd b

The Maxima functions which define new operators are summarized in this table, stating the default left and right binding powers (lbp and rbp, respectively). (Binding power determines operator precedence. However, since left and right binding powers can differ, binding power is somewhat more complicated than precedence.) Some of the operation definition functions take additional arguments; see the function descriptions for details.

prefix

rbp=180

postfix

lbp=180

infix

lbp=180, rbp=180

nary

lbp=180, rbp=180

matchfix

(binding power not applicable)

nofix

(binding power not applicable)

For comparison, here are some built-in operators and their left and right binding powers.

Operator   lbp     rbp

  :        180     20 
  ::       180     20 
  :=       180     20 
  ::=      180     20 
  !        160
  !!       160
  ^        140     139 
  .        130     129 
  *        120
  /        120     120 
  +        100     100 
  -        100     134 
  =        80      80 
  #        80      80 
  >        80      80 
  >=       80      80 
  <        80      80 
  <=       80      80 
  not              70 
  and      65
  or       60
  ,        10
  $        -1
  ;        -1

remove and kill remove operator properties from an atom. remove ("a", op) removes only the operator properties of a. kill ("a") removes all properties of a, including the operator properties. Note that the name of the operator must be enclosed in quotation marks.

(%i1) infix ("##");
(%o1)                          ##
(%i2) "##" (a, b) := a^b;
                                     b
(%o2)                     a ## b := a
(%i3) 5 ## 3;
(%o3)                          125
(%i4) remove ("##", op);
(%o4)                         done
(%i5) 5 ## 3;
Incorrect syntax: # is not a prefix operator
5 ##
  ^
(%i5) "##" (5, 3);
(%o5)                          125
(%i6) infix ("##");
(%o6)                          ##
(%i7) 5 ## 3;
(%o7)                          125
(%i8) kill ("##");
(%o8)                         done
(%i9) 5 ## 3;
Incorrect syntax: # is not a prefix operator
5 ##
  ^
(%i9) "##" (5, 3);
(%o9)                       ##(5, 3)

Categories:  Operators Syntax


Next: , Previous: , Up: Operators   [Contents][Index]

7.2 Arithmetic operators

Operator: +
Operator: -
Operator: *
Operator: /
Operator: ^

The symbols + * / and ^ represent addition, multiplication, division, and exponentiation, respectively. The names of these operators are "+" "*" "/" and "^", which may appear where the name of a function or operator is required.

The symbols + and - represent unary addition and negation, respectively, and the names of these operators are "+" and "-", respectively.

Subtraction a - b is represented within Maxima as addition, a + (- b). Expressions such as a + (- b) are displayed as subtraction. Maxima recognizes "-" only as the name of the unary negation operator, and not as the name of the binary subtraction operator.

Division a / b is represented within Maxima as multiplication, a * b^(- 1). Expressions such as a * b^(- 1) are displayed as division. Maxima recognizes "/" as the name of the division operator.

Addition and multiplication are n-ary, commutative operators. Division and exponentiation are binary, noncommutative operators.

Maxima sorts the operands of commutative operators to construct a canonical representation. For internal storage, the ordering is determined by orderlessp. For display, the ordering for addition is determined by ordergreatp, and for multiplication, it is the same as the internal ordering.

Arithmetic computations are carried out on literal numbers (integers, rationals, ordinary floats, and bigfloats). Except for exponentiation, all arithmetic operations on numbers are simplified to numbers. Exponentiation is simplified to a number if either operand is an ordinary float or bigfloat or if the result is an exact integer or rational; otherwise an exponentiation may be simplified to sqrt or another exponentiation or left unchanged.

Floating-point contagion applies to arithmetic computations: if any operand is a bigfloat, the result is a bigfloat; otherwise, if any operand is an ordinary float, the result is an ordinary float; otherwise, the operands are rationals or integers and the result is a rational or integer.

Arithmetic computations are a simplification, not an evaluation. Thus arithmetic is carried out in quoted (but simplified) expressions.

Arithmetic operations are applied element-by-element to lists when the global flag listarith is true, and always applied element-by-element to matrices. When one operand is a list or matrix and another is an operand of some other type, the other operand is combined with each of the elements of the list or matrix.

Examples:

Addition and multiplication are n-ary, commutative operators. Maxima sorts the operands to construct a canonical representation. The names of these operators are "+" and "*".

(%i1) c + g + d + a + b + e + f;
(%o1)               g + f + e + d + c + b + a
(%i2) [op (%), args (%)];
(%o2)              [+, [g, f, e, d, c, b, a]]
(%i3) c * g * d * a * b * e * f;
(%o3)                     a b c d e f g
(%i4) [op (%), args (%)];
(%o4)              [*, [a, b, c, d, e, f, g]]
(%i5) apply ("+", [a, 8, x, 2, 9, x, x, a]);
(%o5)                    3 x + 2 a + 19
(%i6) apply ("*", [a, 8, x, 2, 9, x, x, a]);
                                 2  3
(%o6)                       144 a  x

Division and exponentiation are binary, noncommutative operators. The names of these operators are "/" and "^".

(%i1) [a / b, a ^ b];
                              a   b
(%o1)                        [-, a ]
                              b
(%i2) [map (op, %), map (args, %)];
(%o2)              [[/, ^], [[a, b], [a, b]]]
(%i3) [apply ("/", [a, b]), apply ("^", [a, b])];
                              a   b
(%o3)                        [-, a ]
                              b

Subtraction and division are represented internally in terms of addition and multiplication, respectively.

(%i1) [inpart (a - b, 0), inpart (a - b, 1), inpart (a - b, 2)];
(%o1)                      [+, a, - b]
(%i2) [inpart (a / b, 0), inpart (a / b, 1), inpart (a / b, 2)];
                                   1
(%o2)                       [*, a, -]
                                   b

Computations are carried out on literal numbers. Floating-point contagion applies.

(%i1) 17 + b - (1/2)*29 + 11^(2/4);
                                       5
(%o1)                   b + sqrt(11) + -
                                       2
(%i2) [17 + 29, 17 + 29.0, 17 + 29b0];
(%o2)                   [46, 46.0, 4.6b1]

Arithmetic computations are a simplification, not an evaluation.

(%i1) simp : false;
(%o1)                         false
(%i2) '(17 + 29*11/7 - 5^3);
                              29 11    3
(%o2)                    17 + ----- - 5
                                7
(%i3) simp : true;
(%o3)                         true
(%i4) '(17 + 29*11/7 - 5^3);
                                437
(%o4)                         - ---
                                 7

Arithmetic is carried out element-by-element for lists (depending on listarith) and matrices.

(%i1) matrix ([a, x], [h, u]) - matrix ([1, 2], [3, 4]);
                        [ a - 1  x - 2 ]
(%o1)                   [              ]
                        [ h - 3  u - 4 ]
(%i2) 5 * matrix ([a, x], [h, u]);
                          [ 5 a  5 x ]
(%o2)                     [          ]
                          [ 5 h  5 u ]
(%i3) listarith : false;
(%o3)                         false
(%i4) [a, c, m, t] / [1, 7, 2, 9];
                          [a, c, m, t]
(%o4)                     ------------
                          [1, 7, 2, 9]
(%i5) [a, c, m, t] ^ x;
                                      x
(%o5)                     [a, c, m, t]
(%i6) listarith : true;
(%o6)                         true
(%i7) [a, c, m, t] / [1, 7, 2, 9];
                              c  m  t
(%o7)                     [a, -, -, -]
                              7  2  9
(%i8) [a, c, m, t] ^ x;
                          x   x   x   x
(%o8)                   [a , c , m , t ]

Categories:  Operators

Operator: **

Exponentiation operator. Maxima recognizes ** as the same operator as ^ in input, and it is displayed as ^ in 1-dimensional output, or by placing the exponent as a superscript in 2-dimensional output.

The fortran function displays the exponentiation operator as **, whether it was input as ** or ^.

Examples:

(%i1) is (a**b = a^b);
(%o1)                         true
(%i2) x**y + x^z;
                              z    y
(%o2)                        x  + x
(%i3) string (x**y + x^z);
(%o3)                        x^z+x^y
(%i4) fortran (x**y + x^z);
      x**z+x**y
(%o4)                         done

Categories:  Operators

Operator: ^^

Noncommutative exponentiation operator. ^^ is the exponentiation operator corresponding to noncommutative multiplication ., just as the ordinary exponentiation operator ^ corresponds to commutative multiplication *.

Noncommutative exponentiation is displayed by ^^ in 1-dimensional output, and by placing the exponent as a superscript within angle brackets < > in 2-dimensional output.

Examples:

(%i1) a . a . b . b . b + a * a * a * b * b;
                        3  2    <2>    <3>
(%o1)                  a  b  + a    . b
(%i2) string (a . a . b . b . b + a * a * a * b * b);
(%o2)                  a^3*b^2+a^^2 . b^^3

Categories:  Operators

Operator: .

The dot operator, for matrix (non-commutative) multiplication. When "." is used in this way, spaces should be left on both sides of it, e.g. A . B This distinguishes it plainly from a decimal point in a floating point number.

See also Dot, dot0nscsimp, dot0simp, dot1simp, dotassoc, dotconstrules, dotdistrib, dotexptsimp, dotident, and dotscrules.

Categories:  Operators


Next: , Previous: , Up: Operators   [Contents][Index]

7.3 Relational operators

Operator: <
Operator: <=
Operator: >=
Operator: >

The symbols < <= >= and > represent less than, less than or equal, greater than or equal, and greater than, respectively. The names of these operators are "<" "<=" ">=" and ">", which may appear where the name of a function or operator is required.

These relational operators are all binary operators; constructs such as a < b < c are not recognized by Maxima.

Relational expressions are evaluated to Boolean values by the functions is and maybe, and the programming constructs if, while, and unless. Relational expressions are not otherwise evaluated or simplified to Boolean values, although the arguments of relational expressions are evaluated (when evaluation is not otherwise prevented by quotation).

When a relational expression cannot be evaluated to true or false, the behavior of is and if are governed by the global flag prederror. When prederror is true, is and if trigger an error. When prederror is false, is returns unknown, and if returns a partially-evaluated conditional expression.

maybe always behaves as if prederror were false, and while and unless always behave as if prederror were true.

Relational operators do not distribute over lists or other aggregates.

See also =, #, equal, and notequal.

Examples:

Relational expressions are evaluated to Boolean values by some functions and programming constructs.

(%i1) [x, y, z] : [123, 456, 789];
(%o1)                    [123, 456, 789]
(%i2) is (x < y);
(%o2)                         true
(%i3) maybe (y > z);
(%o3)                         false
(%i4) if x >= z then 1 else 0;
(%o4)                           0
(%i5) block ([S], S : 0, for i:1 while i <= 100 do S : S + i, 
             return (S));
(%o5)                         5050

Relational expressions are not otherwise evaluated or simplified to Boolean values, although the arguments of relational expressions are evaluated.

(%o1)                    [123, 456, 789]
(%i2) [x < y, y <= z, z >= y, y > z];
(%o2)    [123 < 456, 456 <= 789, 789 >= 456, 456 > 789]
(%i3) map (is, %);
(%o3)               [true, true, true, false]

Categories:  Operators


Next: , Previous: , Up: Operators   [Contents][Index]

7.4 Logical operators

Operator: and

The logical conjunction operator. and is an n-ary infix operator; its operands are Boolean expressions, and its result is a Boolean value.

and forces evaluation (like is) of one or more operands, and may force evaluation of all operands.

Operands are evaluated in the order in which they appear. and evaluates only as many of its operands as necessary to determine the result. If any operand is false, the result is false and no further operands are evaluated.

The global flag prederror governs the behavior of and when an evaluated operand cannot be determined to be true or false. and prints an error message when prederror is true. Otherwise, operands which do not evaluate to true or false are accepted, and the result is a Boolean expression.

and is not commutative: a and b might not be equal to b and a due to the treatment of indeterminate operands.

Categories:  Operators

Operator: not

The logical negation operator. not is a prefix operator; its operand is a Boolean expression, and its result is a Boolean value.

not forces evaluation (like is) of its operand.

The global flag prederror governs the behavior of not when its operand cannot be determined to be true or false. not prints an error message when prederror is true. Otherwise, operands which do not evaluate to true or false are accepted, and the result is a Boolean expression.

Categories:  Operators

Operator: or

The logical disjunction operator. or is an n-ary infix operator; its operands are Boolean expressions, and its result is a Boolean value.

or forces evaluation (like is) of one or more operands, and may force evaluation of all operands.

Operands are evaluated in the order in which they appear. or evaluates only as many of its operands as necessary to determine the result. If any operand is true, the result is true and no further operands are evaluated.

The global flag prederror governs the behavior of or when an evaluated operand cannot be determined to be true or false. or prints an error message when prederror is true. Otherwise, operands which do not evaluate to true or false are accepted, and the result is a Boolean expression.

or is not commutative: a or b might not be equal to b or a due to the treatment of indeterminate operands.

Categories:  Operators


Next: , Previous: , Up: Operators   [Contents][Index]

7.5 Operators for Equations

Operator: #

Represents the negation of syntactic equality =.

Note that because of the rules for evaluation of predicate expressions (in particular because not expr causes evaluation of expr), not a = b is equivalent to is(a # b), instead of a # b.

Examples:

(%i1) a = b;
(%o1)                         a = b
(%i2) is (a = b);
(%o2)                         false
(%i3) a # b;
(%o3)                         a # b
(%i4) not a = b;
(%o4)                         true
(%i5) is (a # b);
(%o5)                         true
(%i6) is (not a = b);
(%o6)                         true

Categories:  Operators

Operator: =

The equation operator.

An expression a = b, by itself, represents an unevaluated equation, which might or might not hold. Unevaluated equations may appear as arguments to solve and algsys or some other functions.

The function is evaluates = to a Boolean value. is(a = b) evaluates a = b to true when a and b are identical. That is, a and b are atoms which are identical, or they are not atoms and their operators are identical and their arguments are identical. Otherwise, is(a = b) evaluates to false; it never evaluates to unknown. When is(a = b) is true, a and b are said to be syntactically equal, in contrast to equivalent expressions, for which is(equal(a, b)) is true. Expressions can be equivalent and not syntactically equal.

The negation of = is represented by #. As with =, an expression a # b, by itself, is not evaluated. is(a # b) evaluates a # b to true or false.

In addition to is, some other operators evaluate = and # to true or false, namely if, and, or, and not.

Note that because of the rules for evaluation of predicate expressions (in particular because not expr causes evaluation of expr), not a = b is equivalent to is(a # b), instead of a # b.

rhs and lhs return the right-hand and left-hand sides, respectively, of an equation or inequation.

See also equal and notequal.

Examples:

An expression a = b, by itself, represents an unevaluated equation, which might or might not hold.

(%i1) eq_1 : a * x - 5 * y = 17;
(%o1)                    a x - 5 y = 17
(%i2) eq_2 : b * x + 3 * y = 29;
(%o2)                    3 y + b x = 29
(%i3) solve ([eq_1, eq_2], [x, y]);
                        196         29 a - 17 b
(%o3)          [[x = ---------, y = -----------]]
                     5 b + 3 a       5 b + 3 a
(%i4) subst (%, [eq_1, eq_2]);
         196 a     5 (29 a - 17 b)
(%o4) [--------- - --------------- = 17, 
       5 b + 3 a      5 b + 3 a
                                  196 b     3 (29 a - 17 b)
                                --------- + --------------- = 29]
                                5 b + 3 a      5 b + 3 a
(%i5) ratsimp (%);
(%o5)                  [17 = 17, 29 = 29]

is(a = b) evaluates a = b to true when a and b are syntactically equal (that is, identical). Expressions can be equivalent and not syntactically equal.

(%i1) a : (x + 1) * (x - 1);
(%o1)                    (x - 1) (x + 1)
(%i2) b : x^2 - 1;
                              2
(%o2)                        x  - 1
(%i3) [is (a = b), is (a # b)];
(%o3)                     [false, true]
(%i4) [is (equal (a, b)), is (notequal (a, b))];
(%o4)                     [true, false]

Some operators evaluate = and # to true or false.

(%i1) if expand ((x + y)^2) = x^2 + 2 * x * y + y^2 then FOO else
      BAR;
(%o1)                          FOO
(%i2) eq_3 : 2 * x = 3 * x;
(%o2)                       2 x = 3 x
(%i3) eq_4 : exp (2) = %e^2;
                              2     2
(%o3)                       %e  = %e
(%i4) [eq_3 and eq_4, eq_3 or eq_4, not eq_3];
(%o4)                  [false, true, true]

Because not expr causes evaluation of expr, not a = b is equivalent to is(a # b).

(%i1) [2 * x # 3 * x, not (2 * x = 3 * x)];
(%o1)                   [2 x # 3 x, true]
(%i2) is (2 * x # 3 * x);
(%o2)                         true

Categories:  Operators


Next: , Previous: , Up: Operators   [Contents][Index]

7.6 Assignment operators

Operator: :

Assignment operator.

When the left-hand side is a simple variable (not subscripted), : evaluates its right-hand side and associates that value with the left-hand side.

When the left-hand side is a subscripted element of a list, matrix, declared Maxima array, or Lisp array, the right-hand side is assigned to that element. The subscript must name an existing element; such objects cannot be extended by naming nonexistent elements.

When the left-hand side is a subscripted element of a hashed array, the right-hand side is assigned to that element, if it already exists, or a new element is allocated, if it does not already exist.

When the left-hand side is a list of simple and/or subscripted variables, the right-hand side must evaluate to a list, and the elements of the right-hand side are assigned to the elements of the left-hand side, in parallel.

See also kill and remvalue, which undo the association between the left-hand side and its value.

Examples:

Assignment to a simple variable.

(%i1) a;
(%o1)                           a
(%i2) a : 123;
(%o2)                          123
(%i3) a;
(%o3)                          123

Assignment to an element of a list.

(%i1) b : [1, 2, 3];
(%o1)                       [1, 2, 3]
(%i2) b[3] : 456;
(%o2)                          456
(%i3) b;
(%o3)                      [1, 2, 456]

Assignment to a variable that neither is the name of a list nor of an array creates a hashed array.

(%i1) c[99] : 789;
(%o1)                          789
(%i2) c[99];
(%o2)                          789
(%i3) c;
(%o3)                           c
(%i4) arrayinfo (c);
(%o4)                   [hashed, 1, [99]]
(%i5) listarray (c);
(%o5)                         [789]

Multiple assignment.

(%i1) [a, b, c] : [45, 67, 89];
(%o1)                     [45, 67, 89]
(%i2) a;
(%o2)                          45
(%i3) b;
(%o3)                          67
(%i4) c;
(%o4)                          89

Multiple assignment is carried out in parallel. The values of a and b are exchanged in this example.

(%i1) [a, b] : [33, 55];
(%o1)                       [33, 55]
(%i2) [a, b] : [b, a];
(%o2)                       [55, 33]
(%i3) a;
(%o3)                          55
(%i4) b;
(%o4)                          33

Categories:  Evaluation Operators

Operator: ::

Assignment operator.

:: is the same as : (which see) except that :: evaluates its left-hand side as well as its right-hand side.

Examples:

(%i1) x : 'foo;
(%o1)                          foo
(%i2) x :: 123;
(%o2)                          123
(%i3) foo;
(%o3)                          123
(%i4) x : '[a, b, c];
(%o4)                       [a, b, c]
(%i5) x :: [11, 22, 33];
(%o5)                     [11, 22, 33]
(%i6) a;
(%o6)                          11
(%i7) b;
(%o7)                          22
(%i8) c;
(%o8)                          33

Categories:  Evaluation Operators

Operator: ::=

Macro function definition operator. ::= defines a function (called a "macro" for historical reasons) which quotes its arguments, and the expression which it returns (called the "macro expansion") is evaluated in the context from which the macro was called. A macro function is otherwise the same as an ordinary function.

macroexpand returns a macro expansion (without evaluating it). macroexpand (foo (x)) followed by ''% is equivalent to foo (x) when foo is a macro function.

::= puts the name of the new macro function onto the global list macros. kill, remove, and remfunction unbind macro function definitions and remove names from macros.

fundef or dispfun return a macro function definition or assign it to a label, respectively.

Macro functions commonly contain buildq and splice expressions to construct an expression, which is then evaluated.

Examples

A macro function quotes its arguments, so message (1) shows y - z, not the value of y - z. The macro expansion (the quoted expression '(print ("(2) x is equal to", x))) is evaluated in the context from which the macro was called, printing message (2).

(%i1) x: %pi$
(%i2) y: 1234$
(%i3) z: 1729 * w$
(%i4) printq1 (x) ::= block (print ("(1) x is equal to", x),
      '(print ("(2) x is equal to", x)))$
(%i5) printq1 (y - z);
(1) x is equal to y - z
(2) x is equal to %pi
(%o5)                                 %pi

An ordinary function evaluates its arguments, so message (1) shows the value of y - z. The return value is not evaluated, so message (2) is not printed until the explicit evaluation ''%.

(%i1) x: %pi$
(%i2) y: 1234$
(%i3) z: 1729 * w$
(%i4) printe1 (x) := block (print ("(1) x is equal to", x),
      '(print ("(2) x is equal to", x)))$
(%i5) printe1 (y - z);
(1) x is equal to 1234 - 1729 w
(%o5)                     print((2) x is equal to, x)
(%i6) ''%;
(2) x is equal to %pi
(%o6)                                 %pi

macroexpand returns a macro expansion. macroexpand (foo (x)) followed by ''% is equivalent to foo (x) when foo is a macro function.

(%i1) x: %pi$
(%i2) y: 1234$
(%i3) z: 1729 * w$
(%i4) g (x) ::= buildq ([x], print ("x is equal to", x))$
(%i5) macroexpand (g (y - z));
(%o5)                     print(x is equal to, y - z)
(%i6) ''%;
x is equal to 1234 - 1729 w
(%o6)                            1234 - 1729 w
(%i7) g (y - z);
x is equal to 1234 - 1729 w
(%o7)                            1234 - 1729 w

Operator: :=

The function definition operator.

f(x_1, ..., x_n) := expr defines a function named f with arguments x_1, …, x_n and function body expr. := never evaluates the function body (unless explicitly evaluated by quote-quote ''). The function body is evaluated every time the function is called.

f[x_1, ..., x_n] := expr defines a so-called memoizing function. Its function body is evaluated just once for each distinct value of its arguments, and that value is returned, without evaluating the function body, whenever the arguments have those values again. (A function of this kind is also known as a “array function”.)

f[x_1, ..., x_n](y_1, ..., y_m) := expr is a special case of a memoizing function. f[x_1, ..., x_n] is a memoizing function which returns a lambda expression with arguments y_1, ..., y_m. The function body is evaluated once for each distinct value of x_1, ..., x_n, and the body of the lambda expression is that value.

When the last or only function argument x_n is a list of one element, the function defined by := accepts a variable number of arguments. Actual arguments are assigned one-to-one to formal arguments x_1, …, x_(n - 1), and any further actual arguments, if present, are assigned to x_n as a list.

All function definitions appear in the same namespace; defining a function f within another function g does not automatically limit the scope of f to g. However, local(f) makes the definition of function f effective only within the block or other compound expression in which local appears.

If some formal argument x_k is a quoted symbol, the function defined by := does not evaluate the corresponding actual argument. Otherwise all actual arguments are evaluated.

See also define and ::=.

Examples:

:= never evaluates the function body (unless explicitly evaluated by quote-quote).

(%i1) expr : cos(y) - sin(x);
(%o1)                    cos(y) - sin(x)
(%i2) F1 (x, y) := expr;
(%o2)                   F1(x, y) := expr
(%i3) F1 (a, b);
(%o3)                    cos(y) - sin(x)
(%i4) F2 (x, y) := ''expr;
(%o4)              F2(x, y) := cos(y) - sin(x)
(%i5) F2 (a, b);
(%o5)                    cos(b) - sin(a)

f(x_1, ..., x_n) := ... defines an ordinary function.

(%i1) G1(x, y) := (print ("Evaluating G1 for x=", x, "and y=", y), x.y - y.x);
(%o1) G1(x, y) := (print("Evaluating G1 for x=", x, "and y=", 
                                               y), x . y - y . x)
(%i2) G1([1, a], [2, b]);
Evaluating G1 for x= [1, a] and y= [2, b] 
(%o2)                           0
(%i3) G1([1, a], [2, b]);
Evaluating G1 for x= [1, a] and y= [2, b] 
(%o3)                           0

f[x_1, ..., x_n] := ... defines a memoizing function.

(%i1) G2[a] := (print ("Evaluating G2 for a=", a), a^2);
                                                     2
(%o1)     G2  := (print("Evaluating G2 for a=", a), a )
            a
(%i2) G2[1234];
Evaluating G2 for a= 1234 
(%o2)                        1522756
(%i3) G2[1234];
(%o3)                        1522756
(%i4) G2[2345];
Evaluating G2 for a= 2345 
(%o4)                        5499025
(%i5) arrayinfo (G2);
(%o5)              [hashed, 1, [1234], [2345]]
(%i6) listarray (G2);
(%o6)                  [1522756, 5499025]

f[x_1, ..., x_n](y_1, ..., y_m) := expr is a special case of a memoizing function.

(%i1) G3[n](x) := (print ("Evaluating G3 for n=", n), diff (sin(x)^2, x, n));
(%o1) G3 (x) := (print("Evaluating G3 for n=", n), 
        n
                                                     2
                                             diff(sin (x), x, n))
(%i2) G3[2];
Evaluating G3 for n= 2 
                                2           2
(%o2)          lambda([x], 2 cos (x) - 2 sin (x))
(%i3) G3[2];
                                2           2
(%o3)          lambda([x], 2 cos (x) - 2 sin (x))
(%i4) G3[2](1);
                           2           2
(%o4)                 2 cos (1) - 2 sin (1)
(%i5) arrayinfo (G3);
(%o5)                   [hashed, 1, [2]]
(%i6) listarray (G3);
                                2           2
(%o6)         [lambda([x], 2 cos (x) - 2 sin (x))]

When the last or only function argument x_n is a list of one element, the function defined by := accepts a variable number of arguments.

(%i1) H ([L]) := apply ("+", L);
(%o1)                H([L]) := apply("+", L)
(%i2) H (a, b, c);
(%o2)                       c + b + a

local makes a local function definition.

(%i1) foo (x) := 1 - x;
(%o1)                    foo(x) := 1 - x
(%i2) foo (100);
(%o2)                         - 99
(%i3) block (local (foo), foo (x) := 2 * x, foo (100));
(%o3)                          200
(%i4) foo (100);
(%o4)                         - 99


Previous: , Up: Operators   [Contents][Index]

7.7 User defined operators

Function: infix
    infix (op)
    infix (op, lbp, rbp)
    infix (op, lbp, rbp, lpos, rpos, pos)

Declares op to be an infix operator. An infix operator is a function of two arguments, with the name of the function written between the arguments. For example, the subtraction operator - is an infix operator.

infix (op) declares op to be an infix operator with default binding powers (left and right both equal to 180) and parts of speech (left and right both equal to any).

infix (op, lbp, rbp) declares op to be an infix operator with stated left and right binding powers and default parts of speech (left and right both equal to any).

infix (op, lbp, rbp, lpos, rpos, pos) declares op to be an infix operator with stated left and right binding powers and parts of speech lpos, rpos, and pos for the left operand, the right operand, and the operator result, respectively.

"Part of speech", in reference to operator declarations, means expression type. Three types are recognized: expr, clause, and any, indicating an algebraic expression, a Boolean expression, or any kind of expression, respectively. Maxima can detect some syntax errors by comparing the declared part of speech to an actual expression.

The precedence of op with respect to other operators derives from the left and right binding powers of the operators in question. If the left and right binding powers of op are both greater the left and right binding powers of some other operator, then op takes precedence over the other operator. If the binding powers are not both greater or less, some more complicated relation holds.

The associativity of op depends on its binding powers. Greater left binding power (lbp) implies an instance of op is evaluated before other operators to its left in an expression, while greater right binding power (rbp) implies an instance of op is evaluated before other operators to its right in an expression. Thus greater lbp makes op right-associative, while greater rbp makes op left-associative. If lbp is equal to rbp, op is left-associative.

See also Introduction to operators.

Examples:

If the left and right binding powers of op are both greater the left and right binding powers of some other operator, then op takes precedence over the other operator.

(%i1) :lisp (get '$+ 'lbp)
100
(%i1) :lisp (get '$+ 'rbp)
100
(%i1) infix ("##", 101, 101);
(%o1)                          ##
(%i2) "##"(a, b) := sconcat("(", a, ",", b, ")");
(%o2)       (a ## b) := sconcat("(", a, ",", b, ")")
(%i3) 1 + a ## b + 2;
(%o3)                       (a,b) + 3
(%i4) infix ("##", 99, 99);
(%o4)                          ##
(%i5) 1 + a ## b + 2;
(%o5)                       (a+1,b+2)

Greater lbp makes op right-associative, while greater rbp makes op left-associative.

(%i1) infix ("##", 100, 99);
(%o1)                          ##
(%i2) "##"(a, b) := sconcat("(", a, ",", b, ")")$
(%i3) foo ## bar ## baz;
(%o3)                    (foo,(bar,baz))
(%i4) infix ("##", 100, 101);
(%o4)                          ##
(%i5) foo ## bar ## baz;
(%o5)                    ((foo,bar),baz)

Maxima can detect some syntax errors by comparing the declared part of speech to an actual expression.

(%i1) infix ("##", 100, 99, expr, expr, expr);
(%o1)                          ##
(%i2) if x ## y then 1 else 0;
Incorrect syntax: Found algebraic expression where logical
expression expected
if x ## y then 
             ^
(%i2) infix ("##", 100, 99, expr, expr, clause);
(%o2)                          ##
(%i3) if x ## y then 1 else 0;
(%o3)                if x ## y then 1 else 0

Function: matchfix
    matchfix (ldelimiter, rdelimiter)
    matchfix (ldelimiter, rdelimiter, arg_pos, pos)

Declares a matchfix operator with left and right delimiters ldelimiter and rdelimiter. The delimiters are specified as strings.

A "matchfix" operator is a function of any number of arguments, such that the arguments occur between matching left and right delimiters. The delimiters may be any strings, so long as the parser can distinguish the delimiters from the operands and other expressions and operators. In practice this rules out unparseable delimiters such as %, ,, $ and ;, and may require isolating the delimiters with white space. The right delimiter can be the same or different from the left delimiter.

A left delimiter can be associated with only one right delimiter; two different matchfix operators cannot have the same left delimiter.

An existing operator may be redeclared as a matchfix operator without changing its other properties. In particular, built-in operators such as addition + can be declared matchfix, but operator functions cannot be defined for built-in operators.

The command matchfix (ldelimiter, rdelimiter, arg_pos, pos) declares the argument part-of-speech arg_pos and result part-of-speech pos, and the delimiters ldelimiter and rdelimiter.

"Part of speech", in reference to operator declarations, means expression type. Three types are recognized: expr, clause, and any, indicating an algebraic expression, a Boolean expression, or any kind of expression, respectively. Maxima can detect some syntax errors by comparing the declared part of speech to an actual expression.

The function to carry out a matchfix operation is an ordinary user-defined function. The operator function is defined in the usual way with the function definition operator := or define. The arguments may be written between the delimiters, or with the left delimiter as a quoted string and the arguments following in parentheses. dispfun (ldelimiter) displays the function definition.

The only built-in matchfix operator is the list constructor [ ]. Parentheses ( ) and double-quotes " " act like matchfix operators, but are not treated as such by the Maxima parser.

matchfix evaluates its arguments. matchfix returns its first argument, ldelimiter.

Examples:

Delimiters may be almost any strings.

(%i1) matchfix ("@@", "~");
(%o1)                          @@
(%i2) @@ a, b, c ~;
(%o2)                      @@a, b, c~
(%i3) matchfix (">>", "<<");
(%o3)                          >>
(%i4) >> a, b, c <<;
(%o4)                      >>a, b, c<<
(%i5) matchfix ("foo", "oof");
(%o5)                          foo
(%i6) foo a, b, c oof;
(%o6)                     fooa, b, coof
(%i7) >> w + foo x, y oof + z << / @@ p, q ~;
                     >>z + foox, yoof + w<<
(%o7)                ----------------------
                            @@p, q~

Matchfix operators are ordinary user-defined functions.

(%i1) matchfix ("!-", "-!");
(%o1)                         "!-"
(%i2) !- x, y -! := x/y - y/x;
                                    x   y
(%o2)                   !-x, y-! := - - -
                                    y   x
(%i3) define (!-x, y-!, x/y - y/x);
                                    x   y
(%o3)                   !-x, y-! := - - -
                                    y   x
(%i4) define ("!-" (x, y), x/y - y/x);
                                    x   y
(%o4)                   !-x, y-! := - - -
                                    y   x
(%i5) dispfun ("!-");
                                    x   y
(%t5)                   !-x, y-! := - - -
                                    y   x

(%o5)                         done
(%i6) !-3, 5-!;
                                16
(%o6)                         - --
                                15
(%i7) "!-" (3, 5);
                                16
(%o7)                         - --
                                15

Categories:  Syntax Operators

Function: nary
    nary (op)
    nary (op, bp, arg_pos, pos)

An nary operator is used to denote a function of any number of arguments, each of which is separated by an occurrence of the operator, e.g. A+B or A+B+C. The nary("x") function is a syntax extension function to declare x to be an nary operator. Functions may be declared to be nary. If declare(j,nary); is done, this tells the simplifier to simplify, e.g. j(j(a,b),j(c,d)) to j(a, b, c, d).

See also Introduction to operators.

Categories:  Operators Syntax

Function: nofix
    nofix (op)
    nofix (op, pos)

nofix operators are used to denote functions of no arguments. The mere presence of such an operator in a command will cause the corresponding function to be evaluated. For example, when one types "exit;" to exit from a Maxima break, "exit" is behaving similar to a nofix operator. The function nofix("x") is a syntax extension function which declares x to be a nofix operator.

See also Introduction to operators.

Categories:  Operators Syntax

Function: postfix
    postfix (op)
    postfix (op, lbp, lpos, pos)

postfix operators like the prefix variety denote functions of a single argument, but in this case the argument immediately precedes an occurrence of the operator in the input string, e.g. 3!. The postfix("x") function is a syntax extension function to declare x to be a postfix operator.

See also Introduction to operators.

Categories:  Operators Syntax

Function: prefix
    prefix (op)
    prefix (op, rbp, rpos, pos)

A prefix operator is one which signifies a function of one argument, which argument immediately follows an occurrence of the operator. prefix("x") is a syntax extension function to declare x to be a prefix operator.

See also Introduction to operators.

Categories:  Operators Syntax


Previous: , Up: Operators   [Contents][Index]