Home Online Manual
Top
Back: python_run
Forward: reference declarations
FastBack: pyobject
FastForward:
Up: Data types
Top: Singular Manual
Contents: Table of Contents
Index: Index
About: About this document

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.

4.28.1 reference declarations  
4.28.2 reference expressions  
4.28.3 shared declarations  
4.28.4 shared expressions  
4.28.5 reference and shared operations  
4.28.6 reference and shared related functions