## `print` -- print objects to the screen

#### Introduction

`print(`object`)` displays `object` on the screen.

#### Call(s)

`print( <Unquoted,> <NoNL,> <KeepOrder,> object1, object2, ...)`

#### Parameters

`object1, object2, ...` | - | any MuPAD objects

#### Options

`Unquoted` | - | Display character strings without quotation marks and with expanded control characters `'`\n`'`, `'`\t`'`, and `'`\\`'`.
`NoNL` | - | Like `Unquoted`, but no newline is put at the end. `PRETTYPRINT` is implicitly set to `FALSE`.
`KeepOrder` | - | Display operands of sums (of type `"_plus"`) always in the internal order.

#### Returns

`print` returns the void object `null()` of type `DOM_NULL`.

### Overloadable:

`object1`, `object2`, ``, `...`

#### Side Effects

`print` is sensitive to the environment variables `DIGITS`, `PRETTYPRINT`, and `TEXTWIDTH`, and to the output preferences `Pref::floatFormat`, `Pref::keepOrder`, `Pref::matrixSeparator`, `Pref::timesDot`, and `Pref::trailingZeroes`.

#### Related Functions

`DIGITS`, `DOM_FUNC_ENV`, `expose`, `expr2text`, `finput`, `fprint`, `fread`, `funcenv`, `input`, `Pref::floatFormat`, `Pref::keepOrder`, `Pref::matrixSeparator`, `Pref::timesDot`, `Pref::trailingZeroes`, `PRETTYPRINT`, `protocol`, `read`, `TEXTWIDTH`, `userinfo`, `write`

#### Details

- At interactive level, the result of a MuPAD command entered at the command prompt is usually displayed on the screen automatically. `print` serves to generate additional output from within loops or procedures.
- Apart from some exceptions mentioned below, the output generated by `print` is identical to the usual output of MuPAD results at interactive level.
- `print` evaluates its arguments sequentially from left to right (cf. example 2) and displays the results on the screen. The individual outputs are separated by commas. A new line is started at the end of the output if this is not suppressed by the option NoNL.
- The output width for `print` is limited by the environment variable `TEXTWIDTH`. Cf. example 3.
- The style of the output is determined by the value of the environment variable `PRETTYPRINT`. Cf. example 4. `print` will always produce ASCII output, even under Windows when typesetting is enabled for the result outputs.
- `print` descends recursively into the operands of an object. For each subobject `s`, `print` first determines its domain type `T`. If the domain `T` has a `"`print" slot, then `print` issues the call `T::print(s)` to the slot routine. In contrast to the overloading mechanism for most other MuPAD functions, `print` processes the result of this call recursively, and the result of the recursive process is printed at the position of `s` (cf. example 5).

  The result returned by the `"`print" method must not contain the domain element `s` itself as a subobject, since this leads to infinite recursion (cf. example 6). The same remark also applies to the output procedures of function environments (see below).

  If `T` is a built-in kernel domain without a `"`print" slot, then the output of `s` is handled by `print` itself.

  If `T` is a library domain without a `"`print" slot and the internal operands of `s` are `op1, op2, ...`, then `s` is printed as `new(T, op1, op2, ...)`. (See example 5.)

- Even the output of elements of a kernel domain can be changed by defining a `"`print" method. Cf. example 7.
- `"`print" methods may return strings or expressions. Strings are always printed unquoted. Expressions are printed in normal mode. If they contain strings, they will be printed with quotation marks. Cf. example 8.
- The output of an `expression` is determined by the 0th operand of the expression. If the 0th operand is a `function environment`, then its second operand handles the output of the expression (cf. examples 9 and 10). Otherwise, the expression is printed in functional notation.
- In contrast to the usual output of MuPAD objects at interactive level, `print` does not perform resubstitution of aliases (see `Pref::alias` for details). Moreover, the routines defined via `Pref::output` and `Pref::postOutput` are not called by `print`. Cf. example 15.
- The output of `floating point numbers` depends on the environment variable `DIGITS` and the settings of `Pref::floatFormat` (exponential or floating point representation) and `Pref::trailingZeroes` (printing of trailing zeroes). Cf. example 19.
- `print` is a function of the system kernel.

#### Option: Unquoted

- With this option, character strings are displayed without quotation marks. Moreover, the control characters `'`\n`'`, `'`\t`'`, and `'`\\`'` in strings are expanded into a new line, a tabulator skip, and a single backslash `'`\`'`, respectively. Cf. example 11.
- The control character `'`\t`'` is expanded with tab-size 8. The following character is placed in the next column `i` with `i mod 8 = 0`.

#### Option: NoNL

- This option has the same functionality as `Unquoted`. In addition, the new line at the end of the output is suppressed. Cf. example 13.
- Moreover, this option implicitly sets `PRETTYPRINT` to `FALSE`.

#### Option: KeepOrder

- This option determines the order of terms in sums. Normally, the system sorts the terms of a `sum` such that a positive term is in the first position of the output. If KeepOrder is given, no such re-ordering takes place and sums are printed in the internal order. Cf. example 14.
- This behavior can also be controlled via `Pref::keepOrder`. More precisely, the call `print(`KeepOrder, ...`)` generates the same output as the following command:

-     Pref::keepOrder(Always): print(...): Pref::keepOrder(%2):

#### Example 1

This example shows a simple call of `print` with strings as arguments. They are printed with quotation marks:

    >> print("Hello", "You"." !"):

                                 "Hello", "You !"

#### Example 2

Like most other functions, `print` evaluates its arguments. In the following call, `x` evaluates to `0` and `cos(0)` evaluates to `1`:

    >> a := 0: print(cos(a)^2):

                                         1

Use `hold` if you want to print the expression `cos(a)^2` literally:

    >> print(hold(cos(a)^2)):

                                            2
                                      cos(a)

    >> delete a:

#### Example 3

`print` is sensitive to the current value of `TEXTWIDTH`:

    >> print(expand((a + b)^4)):
       old := TEXTWIDTH: TEXTWIDTH := 30:
       print(expand((a + b)^4)):
       TEXTWIDTH := old:

                         4    4        3      3        2  2
                        a  + b  + 4 a b  + 4 a  b + 6 a  b

           4    4        3      3
          a  + b  + 4 a b  + 4 a  b +

                2  2
             6 a  b

    >> delete old:

#### Example 4

`print` is sensitive to the current value of `PRETTYPRINT`:

    >> print(a/b):
       old := PRETTYPRINT: PRETTYPRINT := FALSE:
       print(a/b):
       PRETTYPRINT := old:

                                         a
                                         -
                                         b
          a/b

    >> delete old:

#### Example 5

We demonstrate how to achieve formatted output for elements of a user-defined domain. Suppose that we want to write a new domain `Complex` for complex numbers. Each element of this domain has two operands: the real part `r` and the imaginary part `s`:

    >> Complex := newDomain("Complex"): z := new(Complex, 1, 3):
       z + 1;
       print(z + 1):

                             (new(Complex, 1, 3)) + 1

                             (new(Complex, 1, 3)) + 1

Now we want a nicer output for elements of this domain, namely in the form `r+s*I`, where `I` denotes the imaginary unit. We implement the slot routine `Complex::print` to handle this. This slot routine will be called by MuPAD with an element of the domain `Complex` as argument whenever such an element is to be printed on the screen:

    >> Complex::print := (z -> extop(z, 1) + extop(z, 2)*I):
       z + 1;
       print(z + 1):

                                   (1 + 3 I) + 1

                                   (1 + 3 I) + 1

    >> delete Complex, z:

#### Example 6

The result of a `"`print" method must not contain the argument as a subobject; otherwise this leads to infinite recursion. In the following example, the slot routine `T::print` would be called infinitly often. MuPAD tries to trap such infinite recursions and prints ``????`` instead:

    >> T := newDomain(T): T::print := id:
       new(T, 1);
       print(new(T, 1)):

                                      `????`

                                      `????`

    >> delete T:

#### Example 7

Even `"print"` methods for kernel domains are possible. This example shows how to redefine the output of `polynomials` by printing only the polynomial expression:

    >> poly(x + 1);
       print(poly(x + 1)):

                                 poly(x + 1, [x])

                                 poly(x + 1, [x])

    >> unprotect(DOM_POLY): DOM_POLY::print := p -> op(p, 1):
       poly(x + 1);
       print(poly(x + 1)):
       delete DOM_POLY::print:  protect(DOM_POLY):

                                       x + 1

                                       x + 1

#### Example 8

If a `"`print" method returns a string, it will be printed unquoted:

    >> Example := newDomain("Example"):  e := new(Example, 1):
       Example::print := x -> "elementOfExample":
       print(e):

                                 elementOfExample

If a `"`print"-method returns an expression, it will be printed in normal mode. If the expression contains strings, they will be printed in the usual way with quotation marks:

    >> Example::print := x -> ["elementOfExample", extop(x)]:
       print(e):

                              ["elementOfExample", 1]

    >> delete Example, e:

#### Example 9

Suppose that you have defined a function `f` that may return itself symbolically, and you want such symbolic expressions of the form `f(x,...)` to be printed in a special way. To this end, embed your procedure `f` in a function environment and supply an output procedure as second argument to the corresponding `funcenv` call. Whenever an expression of the form `f(x,...)` is to be printed, the output procedure will be called with the arguments `x,...` of the expression:

    >> f := funcenv(f,
                proc(x) begin
                   if nops(x) = 2 then
                     "f does strange things with its arguments ".
                     expr2text(op(x, 1))." and ".expr2text(op(x,2))
                   else
                     FAIL
                   end
                end):

    >> delete a, b:
       f(a, b)/2;
       f(a, b, c)/2

                 f does strange things with its arguments a and b
                 ------------------------------------------------
                                        2

                                    f(a, b, c)
                                    ----------
                                        2

    >> delete f:

#### Example 10

For all prefedined `function environments`, the second operand is a built-in output function, of type `DOM_EXEC`. In particular, this is the case for operators such as `+`, `*`, `^` etc. In the following example, we change the output symbol for the power operator `^`, which is stored in the third operand of the built-in output function of the function environment `_power`, to a double asterisk:

    >> unprotect(_power):
       _power := subsop(_power, [2, 3] = "**"):
       a^b/2;
       print(a^b/2):
       _power := subsop(_power, [2, 3] = "^"):
       protect(_power):

                                       a**b
                                       ----
                                        2

                                       a**b
                                       ----
                                        2

#### Example 11

With the option Unquoted, quotation marks are omitted:

    >> print(Unquoted, "Hello", "You"." !"):

                                   Hello, You !

With Unquoted the special characters `'`\t`'` and `'`\n`'` are expanded:

    >> print(Unquoted, "As you can see\n".
                       "'\\n' is the newline character\n".
                       "\tand '\\t' a tabulator"):

                           As you can see
                           '\n' is the newline character
                                   and '\t' a tabulator

#### Example 12

It is useful to construct output strings using `expr2text` and the concatenation operator `.`:

    >> d := 5:  print(Unquoted, "d plus 3 = ".expr2text(d + 3)):

                                   d plus 3 = 8

    >> delete d:

#### Example 13

With the option NoNL, no new line is put at the end of the output and `PRETTYPRINT` is implicitly set to `FALSE`. Apart from that, the behavior is the same as with the option Unquoted:

    >> print(NoNL, "Hello"):  print(NoNL, ",  You"." !\n"):
       print(NoNL, "As you can see PRETTYPRINT is FALSE: "):
       print(NoNL, x^2-1):  print(NoNL, "\n"):

          Hello,  You !
          As you can see PRETTYPRINT is FALSE: x^2 - 1

#### Example 14

If the option KeepOrder is given, sums are printed in their internal order:

    >> print(b - a):  print(KeepOrder, b - a):

                                       b - a

                                      - a + b

#### Example 15

Alias resubstitution (see `Pref::alias`) takes place for normal result outputs in an interactive session, but not for outputs generated by `print`:

    >> delete a, b: alias(a = b):
       a; print(a):
       unalias(a):

                                         a

                                         b

In contrast to the usual result output, `print` does not react to `Pref::output`:

    >> old := Pref::output(generate::TeX):
       sin(a)^b; print(sin(a)^b):
       Pref::output(old):

                             "\\sin\\left(a\\right)^b"

                                            b
                                      sin(a)

The same is true for `Pref::postOutput`:

    >> old := Pref::postOutput("postOutput was called"):
       a*b; print(a*b):
       Pref::postOutput(old):

                                        a b
          postOutput was called

                                        a b

    >> delete old:

#### Example 16

The output of summands of a sum depends on the form of these summands. If the summand is a `_mult` expression, only the first and last operand of the product are taken into account for determining the sign of that term in the output. If one of them is a negative number then the "+"-symbol in the sum is replaced by a "-"-symbol:

    >> print(hold(a + b*c*(-2)),
             hold(a + b*(-2)*c),
             hold(a + (-2)*b*c)):

                        a - 2 b c, a + b (-2) c, a - 2 b c

This has to be taken into account when writing `"`print"-methods for polynomial domains.

#### Example 17

Usually, MuPAD does not print a multiplication symbol for products and just concatenates the factors with spaces in between. You can explicitly request that a multiplication symbol be printed via `Pref::timesDot`:

    >> a*b*c;
       print(a*b*c):

                                       a b c

                                       a b c

    >> old := Pref::timesDot(" * "):
       a*b*c;
       print(a*b*c):
       Pref::timesDot(old):

                                     a * b * c

                                     a * b * c

    >> delete old:

#### Example 18

The column separator in the output of matrices or two-dimensional arrays can be changed via `Pref::matrixSeparator`:

    >> a := array(1..2, 1..2, [[11, 12], [22, 23]]):
       a; print(a):

                                   +-        -+
                                   |  11, 12  |
                                   |          |
                                   |  22, 23  |
                                   +-        -+

                                   +-        -+
                                   |  11, 12  |
                                   |          |
                                   |  22, 23  |
                                   +-        -+

    >> old := Pref::matrixSeparator("  "):
       a; print(a):
       Pref::matrixSeparator(old): delete a:

                                   +-        -+
                                   |  11  12  |
                                   |          |
                                   |  22  23  |
                                   +-        -+

                                   +-        -+
                                   |  11  12  |
                                   |          |
                                   |  22  23  |
                                   +-        -+

If the output width of a matrix would exceed `TEXTWIDTH`, then it is printed in a textual form:

    >> print(array(1..4, 1..4, (2, 2) = 2)):
       print(array(1..10, 1..10, (5, 5) = 55)):

                     +-                                    -+
                     |  ?[1, 1], ?[1, 2], ?[1, 3], ?[1, 4]  |
                     |                                      |
                     |  ?[2, 1],    2,    ?[2, 3], ?[2, 4]  |
                     |                                      |
                     |  ?[3, 1], ?[3, 2], ?[3, 3], ?[3, 4]  |
                     |                                      |
                     |  ?[4, 1], ?[4, 2], ?[4, 3], ?[4, 4]  |
                     +-                                    -+

                                array(1..10, 1..10,
                                  (5, 5) = 55
                                )

    >> delete old, a:

#### Example 19

Floating point numbers are usually printed in fixed-point notation. You can change this to floating-point form with mantissa and exponent via `Pref::floatFormat`:

    >> print(0.000001, 1000.0): old := Pref::floatFormat("e"):
       print(0.000001, 1000.0): Pref::floatFormat(old):

                                 0.000001, 1000.0

                                  10.0e-7, 1.0e3

In the default output of floating point numbers, trailing zeroes are cut off. This behavior can be changed via `Pref::trailingZeroes`:

    >> print(0.000001, 1000.0): old := Pref::trailingZeroes(TRUE):
       print(0.000001, 1000.0): Pref::trailingZeroes(old):

                                 0.000001, 1000.0

                          0.000001000000000, 1000.000000

The number of digits of floating point numbers in output depends on the environment variable `DIGITS`:

    >> print(float(PI)):
       DIGITS := 20:  print(float(PI)):
       DIGITS := 30:  print(float(PI)):

                                    3.141592654

                               3.1415926535897932385

                          3.14159265358979323846264338328

    >> delete old, DIGITS:

#### Example 20

The output order of `sets` differs from the internal order of sets, which is returned by `op`:

    >> s := {a, b, c}:
       s;
       print(s):
       op(s)

                                     {a, b, c}

                                     {a, b, c}

                                      c, b, a

The index operator `[]` can be used to access the elements of a set with respect to the output order:

    >> s[1], s[2], s[3]

                                      a, b, c

    >> delete s:

#### Example 21

The output of a domain is determined by its `"Name"` slot if it exists, and otherwise by its key:

    >> T := newDomain("T"):
       T;
       print(T):

                                         T

                                         T

    >> T::Name := "domain T":
       T;
       print(T):

                                     domain T

                                     domain T

    >> delete T:

#### Example 22

It is sometimes desirable to combine strings with ``pretty'' expressions in an output. This is not possible via `expr2text`. On the other hand, an output with commas as separators is usually regarded as ugly. The following dummy expression sequence may be used to achieve the desired result. It uses MuPAD's internal function for standard operator output `builtin(1100,...)`, with priority `2`--the priority of `_exprseq`--and with an empty operator symbol "":

    >> myexprseq := funcenv(myexprseq,
                            builtin(1100, 2, "", "myexprseq")):
       print(Unquoted,
             myexprseq("String and pretty expression ", a^b, ".")):

                                                       b
                         String and pretty expression a .

    >> delete myexprseq:

#### Background

- The output order of `sets` differs from the internal order of sets, which can be obtained via `op`. For this reordering in the output, the kernel calls the method `DOM_SET::sort`, which takes the set as argument and returns a sorted list. The elements of the set are then printed in the order given by this list.

#### Changes

- KeepOrder now also works when `PRETTYPRINT` is `FALSE`.
- The output is differently formatted when `PRETTYPRINT` is `FALSE`.
- The elements of a set are sorted before output.
- `Domains` and `procedures` are now printed in a short form; use `expose` to see the full implementation.

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000