## `alias, unalias` -- defines or un-defines an abbreviation or a macro

#### Introduction

`alias(x = object)` defines `x` as an abbreviation for `object`.

`alias(f(y1, y2, ...) = object)` defines `f` to be a macro. For arbitrary objects `a1, a2, ...`, `f(a1, a2, ...)` is equivalent to `object` with `a1` substituted for `y1`, `a2` substituted for `y2`, etc.

`alias()` displays a list of all currently defined aliases and macros.

`unalias(x)` deletes the abbreviation or the macro `x`.

`unalias()` deletes all abbreviations and macros.

#### Call(s)

`alias(x1 = object1, x2 = object2, ...)`
`alias()`
`unalias(z1, z2, ...)`
`unalias()`

#### Parameters

`x1, x2, ...` | - | identifiers or symbolic expressions of the form `f(y1, y2, ...)`, with identifiers `f, y1, y2, ...`
`object1, object2, ...` | - | any MuPAD objects
`z1, z2, ...` | - | identifiers

#### Returns

Both `alias` and `unalias` return the void object of type `DOM_NULL`.

When called with no arguments, `alias` displays all currently defined aliases as a sequence of equations; see below for a description.

#### Side Effects

`alias` with at least one argument and `unalias` change the parser configuration in the way described in the ``Details'' section.

#### Related Functions

`:=`, `finput`, `fprint`, `fread`, `input`, `Pref::alias`, `print`, `proc`, `read`, `subs`, `text2expr`, `write`

#### Details

- `alias(x = object)` defines an abbreviation. It changes the configuration of the parser such that the identifier `x` is replaced by `object` whenever it occurs in the input, and such that `object` is in turn replaced by `x` in the output.

- `alias(f(y1, y2, ...) = object)` defines a macro. It changes the configuration of the parser such that a function call of the form `f(a1, a2, ...)`, where `a1,a2,...` is a sequence of arbitrary objects of the same length as `y1,y2,...`, is replaced by `object` with `a1` substituted for `y1`, `a2` substituted for `y2`, etc.

  No substitution takes place if the number of parameters `y1,y2,...` differs from the number of arguments `a1,a2,...`. No substitution takes place in the output.

  It is valid to define a macro with no arguments via `alias(f()=object)`.

- Multiple alias definitions may be given in a single call; abbreviations and macros may be mixed.

- `alias()` displays all currently defined aliases as a sequence of equations. For an abbreviation defined via `alias(x = object)`, the equation `x = object` is printed. For a macro defined via `alias(f(y1, y2, ...) = object)`, the equation `f = [object, [y1, y2, ...]]` is printed. If no aliases are defined, the message ``No alias defined'' is printed. See Example 11.

- `unalias(x)` deletes the abbreviation or macro `x`. To delete a macro defined by `alias(f(y1, y2, ...) = object)`, use `unalias(f)`. If no alias for `x` or `f`, respectively, is defined currently, the call is ignored.

  Multiple alias definitions may be deleted by a single call of `unalias`. The call `unalias()` deletes all currently defined aliases.

- Neither `alias` nor `unalias` evaluate its arguments. Hence it has no effect if the aliased identifier has a value, and `alias` creates an alias for the right hand side of the alias definition and not for its evaluation. Cf. example 2.

- `alias` does not flatten its arguments. Thus an expression sequence is a valid right hand side of an alias definition. See example 5.

- An alias definition causes a substitution similar to the effect of `subs`, not just a textual replacement. Cf. example 3.

- Each identifier may be aliased to only one object. Each object may be abbreviated in only one way; otherwise `alias` aborts with an error.
- An alias is in effect from the time when the call to `alias` has been evaluated. It affects exactly those inputs that are parsed after that moment. Cf. example 9. In particular, an alias definition inside a procedure does not affect the rest of the procedure.

- By default, back-substitution of aliases in the output happens only for abbreviations and not for macros. After a command of the form `alias(x = object)`, both the unevaluated object `object` and its evaluation are replaced by the unevaluated identifier `x` in the output. Cf. example 2.

  The user can control the behavior of the back-substitution in the output with the function `Pref::alias`; see the corresponding help page for details.

- Substitutions in the output only happen for the results of computations at interactive level. The behavior of the functions `fprint`, `print`, or `write` is not affected.

- Alias substitutions are performed in parallel, both in the input and in the output. Thus it is not possible to define nested aliases. See Example 10.

- If an identifier is used as an abbreviation, it is not possible to enter this identifier in its literal meaning any longer.

  In particular, it is necessary to use `unalias` before another abbreviation or macro for the same identifier can be defined. Cf. example 4.

- If a macro `f(y1,y2,...,yn)` with n arguments has been defined, it is not possible to enter a call to `f` with n arguments in its literal meaning any longer. However, entering a call to `f` with a different number of arguments is still possible. Cf. example 5.

  It is not necessary to use `unalias` before redefining an abbreviation or a macro with a different number of arguments for the identifier `f`. Any subsequent alias definition for this identifier, whether it is an abbreviation or a macro, overwrites the previous definition. See Example 4.

- An alias definition affects all kinds of input: interactive input on the command line, input via the function `input`, input from a file using `finput`, `fread`, or `read` (for the latter two only if option `Plain` is not set), and input from a string using `text2expr`. Cf. example 8.

- An alias definition has no effect on the identifier used as an alias. In particular, that identifier retains its value and its properties. The alias and the aliased object are still distinguished by the evaluator. Cf. example 6.
- Assigning a value to one of the identifiers on the left hand side of an alias definition, or deleting its value has no effect on the alias substitution, neither in the input nor in the output. See Example 7.

#### Example 1

We define `d` as a shortcut for `diff`:

    >> delete f, g, x, y: alias(d = diff):
       d(sin(x), x) = diff(sin(x), x);
       d(f(x, y), x) = diff(f(x, y), x)

                                  cos(x) = cos(x)

                           d(f(x, y), x) = d(f(x, y), x)

We define a macro `Dx(f)` for `diff(f(x), x)`. Note that `hold` does not prevent alias substitution:

    >> alias(Dx(f) = diff(f(x), x)):
       Dx(sin); Dx(f + g); hold(Dx(f + g))

                                      cos(x)

                              d(f(x), x) + d(g(x), x)

                                 d((f + g)(x), x)

After the call `unalias(d, Dx)`, no alias substitutions happen any longer:

    >> unalias(d, Dx):
       d(sin(x), x), diff(sin(x), x), d(f(x, y), x), diff(f(x, y), x);
       Dx(sin), Dx(f + g)

               d(sin(x), x), cos(x), d(f(x, y), x), diff(f(x, y), x)

                                Dx(sin), Dx(f + g)

#### Example 2

Suppose we want to avoid typing `longhardtotypeident` and therefore define an abbreviation `a` for it:

    >> longhardtotypeident := 10; alias(a = longhardtotypeident):

                                        10

Since `alias` does not evaluate its arguments, `a` is now an abbreviation for `longhardtotypeident` and not for the number `10`:

    >> type(a), type(hold(a))

                                DOM_INT, DOM_IDENT

    >> a + 1, hold(a) + 1, eval(hold(a) + 1)

                                   11, a + 1, 11

    >> longhardtotypeident := 2:
       a + 1, hold(a) + 1, eval(hold(a) + 1)

                                    3, a + 1, 3

However, by default alias back-substitution in the output happens for both the identifier and its current value:

    >> 2, 10, longhardtotypeident, hold(longhardtotypeident)

                                    a, 10, a, a

The command `Pref::alias(FALSE)` switches alias resubstitution off:

    >> p := Pref::alias(FALSE):
       a, hold(a), 2, longhardtotypeident, hold(longhardtotypeident);
       Pref::alias(p): unalias(a):

                 2, longhardtotypeident, 2, 2, longhardtotypeident

#### Example 3

Aliases are substituted and not just replaced textually. In the following example, `3*succ(u)` is replaced by `3*(u+1)`, and not by `3*u+1`, which a search-and-replace function in a text editor would produce:

    >> alias(succ(x) = x + 1): 3*succ(u);
       unalias(succ):

                                      3 u + 3

#### Example 4

We define `a` to be an abbreviation for `b`. Then the next alias definition is really an alias definition for `b`:

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

                                DOM_IDENT, DOM_INT

Use `unalias` first before defining another alias for the identifier `a`:

    >> unalias(a): alias(a = 2): type(a), type(b); unalias(a):

                                DOM_INT, DOM_IDENT

A macro definition, however, can be overwritten immediately if the newly defined macro has a different number of arguments:

    >> alias(a(x)=sin(x^2)): a(y); alias(a(x)=cos(x^2)):

                                           2
                                      sin(y )
          Error: Illegal operand [_power];
          during evaluation of 'alias'

    >> alias(a(x, y) = sin(x + y)): a(u, v); unalias(a)

                                    sin(u + v)

#### Example 5

A macro definition has no effect when called with the wrong number of arguments, and the sequence of arguments is not flattened:

    >> alias(plus(x, y) = x + y):
       plus(1), plus(3, 2), plus((3, 2));
       unalias(plus):

                              plus(1), 5, plus(3, 2)

Expression sequences may appear on the right hand side of an alias definition, but they have to be enclosed in parenthesis:

    >> alias(x = (1, 2)): f := 0, 1, 2, x;
       nops(f); unalias(x):

                                   0, 1, 2, 1, 2

                                         5

#### Example 6

An identifier used as an abbreviation may still exist in its literal meaning inside expressions that were entered before the alias definition:

    >> delete x: f := [x, 1]: alias(x = 1): f;
       map(f, type); unalias(x):

                                      [x, x]

                               [DOM_IDENT, DOM_INT]

#### Example 7

It does not matter whether the identifier used as an alias has a value:

    >> a := 5: alias(a = 7): 7, 5; print(a); unalias(a):

                                       a, 5

                                         7

#### Example 8

Alias definitions also apply to input from files or strings:

    >> alias(a = 3): type(text2expr("a")); unalias(a)

                                      DOM_INT

#### Example 9

An alias is valid for all input that is parsed after executing `alias`. A statement in a command line is not parsed before the previous commands in that command line have been executed. In the following example, the alias is already in effect for the second statement:

    >> alias(a = 3): type(a); unalias(a)

                                      DOM_INT

This can be changed by entering additional parentheses:

    >> (alias(a = 3): type(a)); unalias(a)

                                      DOM_INT

#### Example 10

We define `b` to be an alias for `c`, which in turn is defined to be an alias for `2`. It is recommended to avoid such chains of alias definitions beacuse of some probably unwanted effects.

    >> alias(b=c): alias(c=2):

Now each `b` in the input is replaced by `c`, but no additional substitution step is taken to replace this again by `2`:

    >> print(b)

                                         c

On the other hand, the number `2` is replaced by `c` in every output, but that `c` is not replaced by `b`:

    >> 2

                                         c

    >> unalias(c): unalias(b):

#### Example 11

When called without arguments, `alias` just displays all aliasses that are currently in effect:

    >> alias(a = 5, F(x) = sin(x^2)):
       alias(); unalias(F, a):

          a = 5,
          F = [sin(x^2), [x]]

#### Background

- The aliases are stored in the parser configuration table displayed by `_parser_config()`. Note that by default, alias back-substitution happens for the right hand sides of the equations in this table, but not for the indices. Use `print(_parser_config())` to display this table without alias back-substitution.

- Aliases are not in effect while a file is read using `read` or `fread` with option `Plain`. This is true in particular for all library files read with `loadproc`. Conversely, if an alias is defined in a file which is read with option `Plain`, the alias is only in effect until the file has been read completely.

#### Changes

- Alias back-substitution for abbreviations now happens in the output by default.

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