In Aldor one usually does not care about memory management. Certain functions, however, are destructive, i. e., they affect one or several of their arguments. A common example is the function set! as it is used, for example, in Array in order to modify a particular element of the array without producing a new array structure.
In order to prevent any modification of a value one would have to pass a copy of that value to the function. The category MyCopyableType is meant to provide such a copy function.
A domain that provides destructive functions must make sure that
The second case specifies that the depth of the copying operation corresponds to the destructiveness of the operations the domain provides. Informally speaking: the composition of any destructive function with the copy function is non-destructive.
Suppose a domain provides a function
foo!: (%, %, MachineInteger) -> %
|
which works destructively on its first argument. Following the above convention, either foo! does not affect its arguments at all or the domain exports MyCopyableType and the call
z := foo!(copy x, y, i)
|
does not modify x, nor does any destructive modification of z affect x in any way.
Usage
MyDomain: MyCopyableType == add {
Rep == Record(z: MachineInteger, c: Character);
copy(x: %): % == per [x.z, x.c];
}
Description
The category of types whose elements can be copied.
Exports of MyCopyableType
Export of MyCopyableType
copy: % -> %
Usage
y := copy x
Parameters
Element to be copied.
Description
Returns a copy of its argument.
Remarks
An implementation of copy in some domain D must make sure that any destructive function of D composed with the copy function for each modifiable argument is, in fact, a non-destructive function, i. e., the depth of the copying process depends on the depth of destructive operations that the type D provides.
For example, let D provide a function
foo!: (%, %, %) -> %
bar: (%, %, %) -> %
bar(x: %, y: %, z: %): % == foo!(copy x, copy y, z)
Export of MyCopyableType
copy!: (%, %) -> %
Usage
z := copy!(x, y)
Parameters
Element that provides storage.
Element to be copied.
Description
Returns a copy of its second argument.
Remarks
While copying y the storage used by x is allowed to be destroyed or reused, so x is lost after this call. The call copy!(x, y) may cause x to be destroyed. Make sure before making in-place operations on a parameter x that x is not sharing memory with other elements, for example, by calling
x := copy(x)
According to the remark in copy, the call
does not modify v.A domain that implements the category MyCopyableType need not explicitly implement destructive copying since the category already provides the following default implementation. Most probably a specific domain wants to override this default.