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

  Categories:Operators ·Declarations and inferences ·Syntax ·

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 ·