|
4.28 reference and shared (experimental)
The black box data types reference and shared in SINGULAR
allow for concurrently accessing SINGULAR object data.
Copying such object will only add an additional handle which allows you
to define multiple identifiers for the same object instance.
Both experimental features are hidden by default, please activate them by
typing system("reference"); or system("shared"); , respectively,
at the SINGULAR prompt.
You must initialize a reference using a named identifier
or a subexpression of the latter. The resulting object can be stored to gain
read and write access from sophisticated data structures.
| system("reference"); system("shared");
int i = 17;
reference ref = i;
ref;
==> 17
==>
ref = 19;
ref;
==> 19
==>
i; // original handle changed!
==> 19
kill ref;
i; // 'i' stays alive
==> 19
reference uninitialized;
uninitialized; // not initialized
==> <unassigned reference or shared memory>
// error: not a named identifier:
uninitialized = 17;
==> ? Can only take reference from identifier
==> ? error occurred in or before ./examples/reference_and_shared__experim\
ental_.sing line 16: `uninitialized = 17;`
// but subexpressions of named identifiers will do
list ll = list(3,4,5);
reference ref = ll[2];
ref;
==> 4
==>
ref = 12;
ref;
==> 12
==>
ll;
==> [1]:
==> 3
==> [2]:
==> 12
==> [3]:
==> 5
|
In contrast, the type shared can be used to
avoid the initial identifier definition. Each copy has equal rights
for manipulating the data.
| system("reference"); system("shared");
shared ll= list(2,3);
ll[1];
==> 2
==>
ll[1]= 17;
ll;
==> [1]:
==> 17
==> [2]:
==> 3
==>
|
In most cases the value look-up is done automatically, but sometimes
you have to disambiguate the input.
| system("reference"); system("shared");
int i = 0;
reference ref = i;
shared sh = 12;
ref + sh; // automated 'dereferencing'
==> 12
ref + 4;
==> 4
4 + sh;
==> 16
list ll = list(ref, ref, ref, ref, ref, ref, ref);
string(ll);
==> 0,0,0,0,0,0,0
ref = 1;
string(ll); // all one now
==> 1,1,1,1,1,1,1
ll[3] = 0;
string(ll); // only third element changed
==> 1,1,0,1,1,1,1
reference(ll[1]) = 9;
string(ll); // all others changed
==> 9,9,0,9,9,9,9
def(ll[1]) = 11; // alternative (generic) syntax
string(ll);
==> 11,11,0,11,11,11,11
|
The previous example had shown that reference and shared
objects can store highly structured without duplicating data
all over again.
As an additional feature, you can use reference objects for
implementing procedures having side-effects.
| system("reference"); system("shared");
list changeme;
changeme;
==> empty list
proc setfirst(reference ll, def arg) { ll[1] = arg; }
setfirst(changeme, 17);
changeme;
==> [1]:
==> 17
|
If you do not need write-access to proc parameters, your code
will usually perform better using the alias statement in the
parameter list, see proc.
|