## `funcenv` -- create a function environment

#### Introduction

`funcenv` creates a function environment. A function environment behaves like an ordinary function with the additional possibility to define function attributes. These are used to overload standard system functions such as `diff`, `float` etc.

#### Call(s)

`funcenv(f1 <, f2> <, slotTable>)`

#### Parameters

`f1` | - | an arbitrary MuPAD object. Typically, a procedure. It handles the evaluation of a function call to the function environment.
`f2` | - | a procedure handling the screen output of symbolic function calls
`slotTable` | - | a table of function attributes (slots)

#### Returns

a function environment of type `DOM_FUNC_ENV`.

#### Further Documentation

Chapter ``Function Environments'' of the Tutorial.

#### Related Functions

`slot`

#### Details

- `funcenv` serves for generating a function environment of domain type `DOM_FUNC_ENV`.

  From a user's point of view, function environments are similar to procedures and can be called like any MuPAD function.

  However, in contrast to simple procedures, a function environment allows a tight integration into the MuPAD system. In particular, standard system functions such as `diff`, `expand`, `float` etc. can be told how to act on symbolic function calls to a function environment.

  For this, a function environment stores special function attributes (slots) in an internal table. Whenever an overloadable system function such as `diff`, `expand`, `float` encounters an object of type `DOM_FUNC_ENV`, its searches the function environment for a corresponding slot. If found, it calls the corresponding slot and returns the value produced by the slot.

  Slots can be incorporated into the function environment by creating a table `slotTable` and passing this to `funcenv`, when the function environment is created. Alternatively, the function `slot` can be used to add further slots to an existing function environment.

  See example 1 below for further information.

- The first argument `f1` of `funcenv` determines the evaluation of function calls. With `f:= funcenv(f1)`, the call `f(x)` returns the result `f1(x)`. Note that calls of the form `f:= funcenv(f)` are possible (and, in fact, typical). This call embeds the procedure `f` into a function environment of the same name. The original procedure `f` is stored internally in the function environment `f`. After this call, further function attributes can be attached to `f` via the `slot` function.
- The second argument `f2` of `funcenv` determines the screen output of symbolic function calls. Consider `f:= funcenv(f1, f2)`. If the call `f(x)` returns a symbolic function call `f(x)` with 0-th operand `f`, then `f2` is called: the return value of `f2(f(x))` is used as the screen output of `f(x)`.

  Beware: `f2(f(x))` should not produce a result containing a further symbolic call of `f`, because this will lead to an infinite recursion, causing an error message.

- The third argument `slotTable` of `funcenv` is a table containing function attributes (slots). The table has to use strings as indices to address system functions. E.g.,

                 slotTable := table("diff" = mydiff, "float" = myfloat):
                 f := funcenv(f1, f2, slotTable):

  attaches the slot functions `mydiff` and `myfloat` to `f`. They are called by the system functions `diff` and `float`, respectively, whenever they encounter a symbolic expression `f(x)` with 0-th operand `f`. The internal slot table can be changed or filled with additional function attributes via the function `slot`.
- The documentation of `float`, `print`, and `slot` provides further examples involving function environments.
- `funcenv` is a function of the system kernel.

#### Example 1

We want to introduce a function `f` that represents a solution of the differential equation f'(x) = x + sin(x)*f(x). First, we define a function `f`, which returns any call `f(x)` symbolically:

    >> f := proc(x) begin procname(args()) end_proc: f(x), f(3 + y)

                                  f(x), f(y + 3)

Because of the differential equation f'(x) = x + sin(x)*f(x), derivatives of `f` can be rewritten in terms of `f`. How can we tell the MuPAD system to differentiate symbolic functions calls such as `f(x)` accordingly? For this, we first have to embed the procedure `f` into a function environment:

    >> f := funcenv(f):

The function environment behaves like the original procedure:

    >> f(x), f(3 + y)

                                  f(x), f(y + 3)

System functions such as `diff` still treat symbolic calls of `f` as calls to unknown functions:

    >> diff(f(x + 3), x)

                                    D(f)(x + 3)

However, as a function environment, `f` can receive attributes that overload the system functions. The following `slot` call attaches a dummy `"diff"` attribute to `f`:

    >> f := slot(f, "diff", mydiff): diff(2*f(x^2) + x, x)

                                          2
                              2 mydiff(f(x ), x) + 1

We attach a more meaningful `"diff"` attribute to `f` that is based on f'(x) = x + sin(x)*f(x). Note, that arbitrary calls `diff(f(y), x1, x2, ..)` have to be handled by this slot:

    >> fdiff := proc(fcall) local y; begin
           y:= op(fcall, 1);
           (y + sin(y)*f(y))*diff(y, args(2..args(0)))
       end_proc:
       f := slot(f, "diff", fdiff):

Now, as far as differentiation is concerned, the function `f` is fully integrated into MuPAD:

    >> diff(f(x), x), diff(f(x), x, x)

            x + f(x) sin(x), f(x) cos(x) + sin(x) (x + f(x) sin(x)) + 1

    >> diff(sin(x)*f(x^2), x)

                            2                 2      2       2
                  cos(x) f(x ) + 2 x sin(x) (x  + f(x ) sin(x ))

Since Taylor expansion around finite points only needs to evaluate derivatives, also Taylor expansions of `f` can be computed:

    >> taylor(f(x^2), x = 0, 9)

                       4 / f(0)       \    8 / f(0)       \      9
               f(0) + x  | ---- + 1/2 | + x  | ---- + 1/8 | + O(x )
                         \  2         /      \  12        /

    >> delete f, fdiff:

#### Background

- Mathematical functions such as `exp`, `ln` etc. or `abs`, `Re`, `Im` etc. are implemented as function environments.

#### Changes

- used to be called `func_env`

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