## `new` -- create a domain element

#### Introduction

`new(`T, object1, object2, ...`)` creates a new element of the domain `T` with the internal representation `object1, object2, ...`.

#### Call(s)

`new(T, object1, object2, ...)`

#### Parameters

`T` | - | a MuPAD domain
`object1, object2, ...` | - | arbitrary MuPAD objects

#### Returns

an element of the domain `T`.

#### Related Functions

`DOM_DOMAIN`, `domain`, `extop`, `extnops`, `extsubsop`, `newDomain`, `op`

#### Details

- `new` is a low-level function for creating elements of library domains.

  The internal representation of a domain element comprises a reference to the corresponding domain and an arbitrary number of MuPAD objects, the internal operands of the domain element.

- `new(`T, object1, object2, ...`)` creates a new element of the domain `T`, whose internal representation is the sequence of operands `object1, object2, ...`, and returns this element.

  `new(`T`)` creates a new element of the domain `T`, whose internal representation is an empty sequence of operands.

- `new` is intended only for programmers implementing their own domains in MuPAD. You should never use `new` directly to generate elements of a predefined domain `T`; use the corresponding constructor `T(...)` instead, for the following reasons. The internal representation of the predefined MuPAD domains may be subject to changes more often than the interface provided by the constructor. Moreover, in contrast to `new`, the constructors usually perform argument checking. Thus using `new` directly may lead to invalid internal representations of MuPAD objects.

- New domains can be created via `newDomain`.

- You can access the operands of the internal representation of a domain element via `extop`, which, in contrast to `op`, cannot be overloaded for the domain. The function `op` is sometimes overloaded for a domain in order to hide the internal, technical representation of an object and to provide a more user friendly and intuitive interface.

- Similarly, the function `extnops` returns the number of operands of a domain element in the internal representation, and `extsubsop` modifies an operand in the internal representation. These functions, in contrast to the related functions `nops` and `subsop`, cannot be overloaded for a domain.

- You can write a constructor for your own domain `T` by providing a `"new"` method. This method is invoked whenever the user calls `T(arg1, arg2, ...)`. This is recommended since it provides a more elegant and intuitive user interface than `new`. The `"new"` method usually performs some argument checking and converts the arguments `arg1, arg2, ...` into the internal representation of the domain, using `new` (see example 1).

- `new` is a function of the system kernel.

#### Example 1

We create a new domain `Time` for representing clock times. The internal representation of an object of this domain has two operands: the hour and the minutes. Then we create a new domain element for the time 12:45:

    >> Time := newDomain("Time"):
       a := new(Time, 12, 45)

                                 new(Time, 12, 45)

The domain type of `a` is `Time`, the number of operands is `2`, and the operands are `12` and `45`:

    >> domtype(a), extnops(a)

                                      Time, 2

    >> extop(a)

                                      12, 45

We now implement a `"new"` method for our new domain `Time`, permitting several input formats. It expects either two integers, the hour and the minutes, or only one integer that represents the minutes, or a rational number or a floating point number, implying that the integral part is the hour and the fractional part represents a fraction of an hour corresponding to the minutes, or no arguments, representing midnight. Additionally, the procedure checks that the arguments are of the correct type:

    >> Time::new := proc(HR = 0, MN = 0)
         local m;
       begin
         if args(0) = 2 and domtype(HR) = DOM_INT
            and domtype(MN) = DOM_INT then
           m := HR*60 + MN
         elif args(0) = 1 and domtype(HR) = DOM_INT then
           m := HR
         elif args(0) = 1 and domtype(HR) = DOM_RAT then
           m := trunc(float(HR))*60 + frac(float(HR))*60
         elif args(0) = 1 and domtype(HR) = DOM_FLOAT then
           m := trunc(HR)*60 + frac(HR)*60
         elif args(0) = 0 then
           m := 0
         else
           error("wrong number or type of arguments")
         end_if;
         new(Time, trunc(m/60), trunc(m) mod 60)
       end_proc:

Now we can use this method to create new objects of the domain `Time`, either by calling `Time::new` directly, or, preferably, by using the equivalent but shorter call `Time(...)`:

    >> Time::new(12, 45), Time(12, 45), Time(12 + 3/4)

              new(Time, 12, 45), new(Time, 12, 45), new(Time, 12, 45)

    >> Time(), Time(8.25), Time(1/2)

                new(Time, 0, 0), new(Time, 8, 15), new(Time, 0, 30)

In order to have a nicer output for objects of the domain `Time`, we also define a `"print"` method (see the help page for `print`):

    >> Time::print := proc(TM)
       begin
         expr2text(extop(TM, 1)) . ":" .
         stringlib::format(expr2text(extop(TM, 2)), 2, Right, "0")
       end_proc:

    >> Time::new(12, 45), Time(12, 45), Time(12 + 3/4)

                                12:45, 12:45, 12:45

    >> Time(), Time(8.25), Time(1/2)

                                 0:00, 8:15, 0:30

#### Changes

- no changes

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