slot
Method or entry of a domain or a function environment
MuPAD® notebooks will be removed in a future release. Use MATLAB® live scripts instead.
MATLAB live scripts support most MuPAD functionality, though there are some differences. For more information, see Convert MuPAD Notebooks to MATLAB Live Scripts.
d::n slot(d
,"n"
) d::n := v slot(d
,"n"
,v
) object::dom slot(object
, "dom")
d::n
returns the value of the slot named "n"
of
the object d
.
d::n := v
creates or changes the slot "n"
.
The value v
is assigned to the slot.
The function slot
is used for defining methods
and entries of data types (domains) or for defining attributes of function environments. Such methods, entries,
or attributes are called slots. They allow to
overload system functions by user defined domains and function environments.
See the “Background” section below for further information.
Any MuPAD® object has a special slot named "dom"
.
It holds the domain the object belongs to: slot(object, "dom")
is
equivalent to domtype(object)
. The value of this
special slot cannot be changed. Cf. Example 1.
Apart from the special slot "dom"
, only domains and function environments may have further slots.
The call slot(d, "n")
is equivalent to d::n
.
It returns the value of the slot.
The call slot(d, "n", v)
returns the object d
with
an added or changed slot "n"
bearing the value v
.
For a function environmentd
,
the call slot(d, "n", v)
returns d
with
the changed slot "n"
and changes the function environment d
as
a side-effect. This is the so-called “reference effect”
of function environments. Cf. Example 2.
For a domaind
, however,
the call slot(d, "n", v)
modifies d
as
a side-effect and returns the domain. This is the so-called “reference
effect” of domains. Cf. Example 3.
If a non-existing slot is accessed, FAIL
is returned as
the value of the slot. Cf. Example 4.
The ::
-operator is a shorthand notation to
access a slot.
The expression d::n
, when not appearing on
the left hand side of an assignment, is equivalent to slot(d,
"n")
.
The command d::n := v
assigns the value v
to
the slot "n"
of d
. This assignment
is almost equivalent to changing or creating a slot via slot(d,
"n", v)
. Note the following subtle semantical difference
between these assignments: in d::n := v
, the identifier d
is
evaluated with level 1, i.e., the slot "n"
is attached
to the value of d
. In slot(d,
"n", v)
, the identifier d
is fully
evaluated. See Example 6.
With delete d::n
or delete slot(d,"n")
,
the slot "n"
of the function environment or the
domain d
is deleted. Cf. Example 5. The special slot "dom"
cannot
be deleted.
The first argument of slot
is not flattened. This
allows to access the slots of expression sequences and null()
objects.
Cf. Example 7.
For domains, there is a special mechanism to create new values
for slots on demand. If a non existing slot is read, the method "make_slot"
of
the domain is called in order to create the slot. If such a method
does not exist, FAIL
is
returned. Cf. Example 8.
Every object has the slot "dom"
:
x::dom = domtype(x), slot(45, "dom") = domtype(45), sin::dom = domtype(sin)
Here we access the existing "float"
slot
of the function environment sin
implementing
the sine function. The float slot is again a function environment
and may be called like any MuPAD function. Note, however, the
different functionality: in contrast to sin
, the float slot always tries to compute
a floating-point approximation:
s := sin::float: s(1), sin(1)
With the following commands, s
becomes the
function environment sin
apart
from a changed "float"
slot. The slot
call
has no effect on the original sin
function because slot
returns
a copy of the function environment:
s := funcenv(sin): s::float := x -> float(x - x^3/3!): s(PI/3) = sin(PI/3), s::float(1) <> sin::float(1)
delete s:
If you are using the slot
function to change
slot entries in a domain, you must be aware that you are modifying
the domain:
old_one := Dom::Float::one
newDomFloat := slot(Dom::Float, "one", 1): newDomFloat::one, Dom::Float::one
We restore the original state:
slot(Dom::Float, "one", old_one): Dom::Float::one
delete old_one, newDomFloat:
The function environment sin
does not contain a "sign"
slot.
So accessing this slot yields FAIL
:
slot(sin, "sign"), sin::sign
We define a function environment for a function computing the
logarithm to the base 3
:
log3 := funcenv(x -> log(3, x)):
If the function info
is
to give some information about log3
, we have to
define the "info"
slot for this function:
log3::info := "log3 -- the logarithm to the base 3":
info(log3)
log3 -- the logarithm to the base 3
The delete
statement
is used for deleting a slot:
delete log3::info: info(log3)
log3(x) -- a library procedure [try ?log3 for help]
It is not possible to delete the special slot "dom"
:
delete log3::dom
Error: Invalid argument. [delete]
delete log3:
Here we demonstrate the subtle difference between the slot
function
and the use of the ::
-operator in assignments.
The following call adds a "xyz"
slot to the domain DOM_INT
of
integer numbers:
delete b: d := b: b := DOM_INT: slot(d, "xyz", 42):
The slot "xyz"
of DOM_INT
is changed, because d
is
fully evaluated with the result DOM_INT
. Hence,
the slot DOM_INT::xyz
is set to 42:
slot(d, "xyz"), slot(DOM_INT, "xyz")
Here is the result when using the ::
-operator: d
is
only evaluated with level 1, i.e., it is evaluated to the identifier b
.
However, there is no slot b::xyz
, and an error
occurs:
delete b: d := b: b := DOM_INT: d::xyz := 42
Error: Unknown slot 'd::xyz'. [slot]
delete b, d:
The first argument of slot
is not flattened. This
allows access to the slots of expression sequences and null()
objects:
slot((a, b), "dom") = (a,b)::dom, slot(null(), "dom") = (null())::dom
We give an example for the use of the function make_slot
.
The element undefined
of the domain stdlib::Undefined
represents
an undefined value. Any function f
should yield f(undefined)
= undefined
. Inside the implementation of stdlib::Undefined
,
we find:
undef := newDomain("stdlib::Undefined"): undefined := new(undef): undef::func_call := proc() begin undefined end_proc; undef::make_slot := undef::func_call:
The following mechanism takes place automatically for a function f
that
is overloadable by its first argument: in the call f(undefined)
,
it is checked whether the slot undef::f
exists.
If this is not the case, the make_slot
function
creates this slot “on the fly”, producing the value undefined
.
Thus, via overloading, f(undefined)
returns the
value undefined
.
The following example is rather advanced and technical. It demonstrates
overloading of the slot
function to implement slot
access and slot assignments for other objects than domains (DOM_DOMAIN
)
or function environments (DOM_FUNC_ENV
). The following example defines
the slots "numer"
and "denom"
for
rational numbers. The domain DOM_RAT
of such numbers does not have slots "numer"
and "denom"
:
domtype(3/4)
slot(3/4, "numer")
Error: Unknown slot '(3/4)::numer'. [slot]
We can change DOM_RAT
, however. For this, we have to unprotectDOM_RAT
temporarily:
unprotect(DOM_RAT): DOM_RAT::slot := proc(r : DOM_RAT, n : DOM_STRING, v=null(): DOM_INT) local i : DOM_INT; begin i := contains(["numer", "denom"], n); if i = 0 then error("Unknown slot \"".expr2text(r)."::".n."\"") end; if args(0) = 3 then subsop(r, i = v) else op(r, i) end end_proc:
Now, we can access the operands of rational numbers, which are the numerator and the denominator respectively, via our new slots:
slot(3/4, "numer"), (3/4)::numer, slot(3/4, "denom"), (3/4)::denom
a := 3/4: slot(a, "numer", 7)
a::numer := 11: a
We restore the original behavior:
delete DOM_RAT::slot, a: protect(DOM_RAT, Error):
|
A domain or a function environment |
|
The name of the slot: an identifier |
|
The new value of the slot: an arbitrary MuPAD object |
|
An arbitrary MuPAD object |
slot(d, "n")
returns the value of the slot; slot(d,
"n", v)
returns the object d
with the
added or changed slot; slot(object, "dom")
returns
the domain type of the object.
d
Overloading of system functions by domain elements is typically
implemented as follows. If a library function f
,
say, is to be overloadable by user defined data types, a code segment
as indicated by the following lines is appropriate. It tests whether
the domain x::dom
of the argument x
contains
a method f
. If this is the case, this domain method
is called:
f:= proc(x) begin // check if f is overloaded by x if x::dom::f <> FAIL then // use the method of the domain of x return(x::dom::f(args())) else // execute the code for the function f endif end_proc:
By overloading the function slot
, slot access
and slot assignment can be implemented for other objects than domains
or function environments. Cf. Example 9.
In principle, the name n
of a slot may be
an arbitrary MuPAD object. Note, however, that the ::
-operator
cannot access slots defined by slot(d, n, v)
if
the the name n
is not a string.
Strings may be used in conjunction with the ::
-operator:
the calls d::"n"
and d::n
are
equivalent.