12.3 Selector Functions

Note that we deliberately do not provide a way to extract the generator that is stored inside the representation. For if that generator is used then the stream will change its semantics, as the cache will not be filled appropriately.

Export of DataStream

#: % -> MachineInteger

Usage

T == String;
l: List T := ["Hello", " ", "World", "!"];
s: DataStream T := stream generator l;
a := #s;
w := s.2;

b := #s;
d := data s;
u: String := "";
for i in 0..prev b repeat u := u + d.i;

v: String := "";
for i in 0..9 for x in s repeat v := v + x;
c := #s;

Description

Number of computed elements.

#s returns the number of computed elements, i. e., the number of elements that are stored in the data(s) array.

In the above example code the variables will get the following values.

a = 0
w = "World"
b = 3
d = ["Hello", " ", "World"]
u = "Hello World"
v = "Hello World!!!!!!!"
c = 4

Remarks

Note that for a stream s that is known to be constant from some point on, #s might return a smaller value then i even if s.i has been accessed.

401aexports: DataStream 392a+   (386)  398a  403a
 #: % -> MachineInteger;

Uses MachineInteger 67.

For a test corresponding of the code in the usage part see testStream5.

401bimplementation: DataStream 392b+   (386)  398b  403b
 #(x: %): I == X.numberOfElements;

Uses I 47.

Export of DataStream

data: % -> PrimitiveArray T

Usage

T == Integer;
l: List T := [2,3,5,7,11,0];
s: DataStream T := stream generator l;
a := #s;
w := s.2;
b := #s;
d := data s;
u: String := "";
for i in 0..prev b repeat u := u + d.i;

Description

Returns the array of computed elements.

This function gives access to the internal data structure of DataStream. It is ensured that

p: PrimitiveArray T := [x for i in 1..#s for x in s];

and

q: PrimitiveArray T := data s;

give arrays with identical content.

Remarks

Since this function does not copy the internal array, writing to the array might change the stream s. It is unsafe to access data(s) after the stream s has been accessed beyond #s, i. e., the following code might result in a runtime error or even segmentation fault.

g: Generator Integer := generate for i in 5.. repeat yield i;
s: DataStream Integer := stream g;
x: Integer := s.2;
d := data s; -- gives [5,6,7];
y := s.100; -- allocate a new internal array and release the old one
z := d.0; -- segfault, because the memory for d has been released

403aexports: DataStream 392a+   (386)  401a  404a
data: % -> PrimitiveArray T;
403bimplementation: DataStream 392b+   (386)  401b  404b
data(x: %): PrimitiveArray T == X.cache;

Export of DataStream

constant?: % -> Boolean

Usage

T == Integer;
l: List T := [2,3,5,7,11,0];
s: DataStream T := stream generator l;
a := constant? s;
x := s.3;
b := constant? s;
y := s.5;
c := constant? s;
z := s.6;
d := constant? s;

t: DataStream T := stream 3;
e := constant? t;

Description

Returns true if the stream is known to be eventually constant.

Since streams are lazy objects, it is not know whether or not a stream is constant until the generator that is used to construct the stream runs out of elements. A special case, however, is the function stream which constructs a constant stream.

In the above example code, a, b, and c are false whereas d and e are true.

404aexports: DataStream 392a+   (386)  403a  407a
constant?: % -> Boolean;

For a test corresponding the the code in the usage part see testStream6.

404bimplementation: DataStream 392b+   (386)  403b  407b
constant?(x: %): Boolean == X.constant?;