15.01.2015 Views

4th International Conference on Principles and Practices ... - MADOC

4th International Conference on Principles and Practices ... - MADOC

4th International Conference on Principles and Practices ... - MADOC

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

4. FIXED POINT DEFINITIONS<br />

A stream often depends <strong>on</strong> itself as e.g. the stream of<br />

integers or fib<strong>on</strong>acci numbers shown above. This self recursi<strong>on</strong><br />

is revealed in the lazily evaluated recursive calls of<br />

the methods integersFrom or fib<strong>on</strong>acci. This recursi<strong>on</strong><br />

property can also be made more visible <strong>and</strong> be used to define<br />

a stream as a fixed point of a map <strong>on</strong> the domain of<br />

streams [6].<br />

Such maps are defined with method map of the interface<br />

StreamMap (defined in the interface Stream)<br />

interface StreamMap {<br />

Stream map(Stream stream);<br />

}<br />

<strong>and</strong> new streams are c<strong>on</strong>structed with the static generic<br />

method fixedpoint<br />

static Stream fixedPoint(StreamMap map){..}<br />

which c<strong>on</strong>structs a stream which is a fixed point of the given<br />

map.<br />

In particular, we think of maps which do not perform<br />

operati<strong>on</strong>s <strong>on</strong> their argument but rather simply include it<br />

in a new stream which is returned as result. In particular,<br />

the head element of the defined stream must not depend <strong>on</strong><br />

the argument. This way bootstrapping of the c<strong>on</strong>structi<strong>on</strong><br />

of the stream is possible.<br />

As an example we show the definiti<strong>on</strong> of the stream of<br />

<strong>on</strong>es with a fixed point. This stream is the fixed point of a<br />

map which prepends the element <strong>on</strong>e to its argument.<br />

Stream <strong>on</strong>es = fixedPoint(<br />

new StreamMap(){<br />

public Stream map(Stream s){<br />

return s.prepend(1);<br />

}<br />

}<br />

);<br />

We now discuss how the fixedPoint method is implemented<br />

for LinkedStreams <strong>and</strong> ArrayStreams. In both cases<br />

a new stream is c<strong>on</strong>structed <strong>and</strong> passed to the given map.<br />

The result is another stream of the same type. The fields<br />

of this stream are copied to the initially generated stream.<br />

This way the fixed point of the map is c<strong>on</strong>structed. The<br />

resulting code looks similar for both classes.<br />

public class LinkedStream implements Stream {<br />

private LinkedStream(){}<br />

public static Stream fixedPoint(<br />

StreamMap map){<br />

LinkedStream s1 = new LinkedStream();<br />

LinkedStream s2 = (LinkedStream)map.map(s1);<br />

s1.head = s2.head;<br />

s1.lazyTail = s2.lazyTail;<br />

return s2;<br />

} ...<br />

}<br />

public class ArrayStream implements Stream {<br />

private ArrayStream(){}<br />

public static Stream fixedPoint(<br />

StreamMap map){<br />

ArrayStream s1 = new ArrayStream();<br />

ArrayStream s2 = (ArrayStream)map.map(s1);<br />

s1.lazyCoeff = s2.lazyCoeff;<br />

return s2;<br />

} ...<br />

}<br />

Let us now define some streams as fixed points of stream<br />

maps. The first example is the periodic sequence [A, B, C,<br />

A, B, C, A, B, C, . . .]. This stream is simply the fixed point<br />

of a map which pretends the strings “A”, “B” <strong>and</strong> “C” to<br />

its argument. The statement<br />

System.out.println(<br />

fixedPoint(<br />

new StreamMap(){<br />

public Stream map(Stream s){<br />

return s.prepend("C").prepend("B").<br />

prepend("A");<br />

}<br />

}<br />

)<br />

);<br />

generates the output<br />

A B C A B C A B C A B C A B C ...<br />

Next we define the stream of integers as fixed point of a<br />

map which takes a stream, adds <strong>on</strong>e to each element <strong>and</strong><br />

prepends zero.<br />

integers = fixedPoint(<br />

new StreamMap(){<br />

public Stream map(Stream s){<br />

return s.map(<br />

new UnaryFunctor(){<br />

public Integer eval(Integer x){<br />

return x+1;<br />

}<br />

}<br />

).prepend(0);<br />

}<br />

}<br />

);<br />

This example <strong>on</strong>ly works if the prepend method does not<br />

evaluate the stream to which a new head element is prepended.<br />

Otherwise the call s.map is evaluated which results in<br />

a NullPointerExcepti<strong>on</strong> as the head element of the stream<br />

to be c<strong>on</strong>structed by this fixed point definiti<strong>on</strong> is not yet<br />

defined. As a c<strong>on</strong>sequence, this definiti<strong>on</strong> <strong>on</strong>ly works with<br />

the fixed point method of class ArrayStream.<br />

Fib<strong>on</strong>acci numbers can be expressed as the fixed point of<br />

the map<br />

f ibs → 0 : (+ f ibs (1 : f ibs))<br />

which leads to the following definiti<strong>on</strong>:<br />

class Add implements<br />

Stream.BinaryFunctor {<br />

public Integer eval(Integer x, Integer y){<br />

return x+y;<br />

}<br />

};<br />

Stream fib<strong>on</strong>acci = fixedPoint(<br />

new StreamMap() {<br />

public Stream map(Stream f){<br />

return f.zip(new Add(),<br />

f.prepend(1)).prepend(0);<br />

}<br />

}<br />

);<br />

Again, this definiti<strong>on</strong> <strong>on</strong>ly works with class ArrayStream.<br />

In this example the zip functi<strong>on</strong> accesses the head element<br />

185

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!