9 MyCopyableType

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.

Convention 3 By convention, functions that possibly affect their arguments are called destructive and their names end with ! (exclamation mark).

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.

Convention 4 A domain should only have a few destructive functions in order to provide efficient access to its data structure. An extension of a domain is not allowed to know the internal representation of the domain and, therefore, it cannot introduce other direct destructive operations. It is only possible to introduce destructive functions that are built on the already existing ones.

A domain that provides destructive functions must make sure that

  1. either the arguments of any destructive function are not modified at all
  2. or the domain additionally exports MyCopyableType and if any destructive function is called with copies of values, the original values are not affected.

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.

53* 13+   47  58b
-------------------------------------------------------------------
----
---- ALLPROSE
---- Copyright (C) Ralf Hemmecke (ralf@hemmecke.de)
---- http://www.hemmecke.de/aldor
----
-------------------------------------------------------------------

#assert DontNeedLibraryMyAlps
#include "myalps"
cat: MyCopyableType 54

Uses DontNeedLibraryMyAlps 37.

Type Constructor

MyCopyableType

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.

54cat: MyCopyableType 54  (53)
define MyCopyableType: Category == with {
        exports: MyCopyableType 55
    default {
        defaults: MyCopyableType 58a
    }
}

Defines:
MyCopyableType, never used.

Exports of MyCopyableType

copy: % -> % Returns a copy of its argument.

copy!: (%, %) -> % Returns a copy of its second argument.

Export of MyCopyableType

copy: % -> %

Usage

y := copy x

Parameters

x: %

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!: (%, %, %) -> %

which works destructively on its first two arguments. The function

bar: (%, %, %) -> %

defined by

bar(x: %, y: %, z: %): % == foo!(copy x, copy y, z)

is non-destructive.
55exports: MyCopyableType 55  (54)  57
copy: % -> %;

Export of MyCopyableType

copy!: (%, %) -> %

Usage

z := copy!(x, y)

Parameters

x: %

Element that provides storage.

y: %

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)

Note that some functions are not necessarily copying their arguments and can thus create memory aliases.

According to the remark in copy, the call

copy!(copy v, y)

does not modify v.
57exports: MyCopyableType 55+   (54)  55
copy!: (%, %) -> %;

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.

58adefaults: MyCopyableType 58a  (54)
copy!(x: %, y: %): % == copy y;
58b* 13+   53  82
-------------------------------------------------------------------
----
---- ALLPROSE
---- Copyright (C) Ralf Hemmecke (ralf@hemmecke.de)
---- http://www.hemmecke.de/aldor
----
-------------------------------------------------------------------

#include "myalps"
cat: MyAdditiveType 60
cat: MyArithmeticType 73