Flipping the coin on Iterator or deriving the subject-observer design pattern in php

Continuing from parts one and two of these series of posts I'll stick to iterators for the time being. I'll make a quick overview of the php Iterator and IteratorAggregate interfaces. Then will derive a pair of Observable(Subject) and Observer interfaces as their mathematical duals by flipping the methods (arrows) around and see what comes about. In fact, this technique was used by the C# team to derive the Rx framework.

Flipping iterators


class IteratorAggregate extends  Traversable   {
    abstract public Traversable getIterator ( void )
}

class Iterator extends Traversable   {
    /* Methods */
    abstract public mixed current ( void )
    abstract public scalar key ( void )
    abstract public void next ( void )
    abstract public void rewind ( void )
    abstract public boolean valid ( void )
}

These definitions a lifted directly from the php documentation. An IteratorAggregator
produces a Travesable by applying getIterator(), in most code written in php it will be some derivative of Iterator, so I will be using Iterator here instead. Let's play a little mind game - let's reverse the direction of the getIterator and see what we get.


class IteratorAggregateDual extends XYZ {
     void getIteratorDual( IteratorDual );
}

What possible meaning can we assign to the above constuct? The
getIteratorDual( IteratorDual ) method can only
perform some side effect like assignment or IO, as it returns void. Since we are creating a dual to a getter method it is only reasonable to expect to have a setter, i.e. assignment, so we could rename the method to setSomething(...).

But what should be the meaning of the class? What is the dual of Traversable? The dual of an IteratorAggregate? A traversable, is something which can be traversed, or enumerated in some order. The values are pulled from it for further processing by using some interface. In the case of Iterator, the key,value tuple of each element of a collection wrapped in an iterator can be obtained by using the scalar key( void ) and mixed current methods. It sounds reasonable to presume that the dual to a traversable will push values for further processing. Sounds quite like the Subject/Observer pattern. Since the dual to the IteratorAggregate has only one method, which set something which will be pushed to, let's call it Subject.


interface Subject {
     void subscribe( Observer );
}

I write it as an interface, as at the moment I am only interested in the abstract protocol of working with this construction, rather that some specific implementation. I want to be able to combine these with other possible protocols cleanly - ergo interfaces.

Having decided to call The dual of Iterator and Observer, let's mechanically flip the methods (swap return values and arguments)


interface Observer   {
    void onChange( mixed ); //dual to current()
    void onKey( scalar );   //dual to key()
    void onNext( void );    //dual to next()
    void onStart( void );  //dual to rewind()
    void onDone( boolean );   //dual to valid()
}

OnChange is called whenever the subject changes state. onKey is rather odd, it is called at the same time as onChange, but only with the key. onNext() signals state change. Similarly onStart is called at initialisation of the state of the subject. onDone( boolean ) is called every step, but the argument will be True only at the end of life of the subject.

Ok, the above code is both a bit too much and too little at the same time. For example, there is no way for an observer to unsubscribe from observing a subject. onKey, onNext, onChange should in most cases be folded into one and the same method - state change is obvious if onChange() is called making onNext() redundant. onKey() can be easily folded into onChange as well. onDone(false) is rendundant as well - it makes sense to call onDone() only at the end of life of the object.

Since the Iterator can trow exceptions, for example during errors reading a file, but that is not reflected in the interface of the class, the dual to this capability is onError(). It tells the subject to call onError(), whenever something goes wrong.

Hereby I present the low fat Observer:


interface Observer   {
    void onChange( mixed ); //dual to current()
    void onStart( void );  //dual to rewind()
    void onDone( );   //dual to valid()
    void onError( Exception );
}

Reactive interactive programming

Imagine that we have an iterator, which is being driven by a foreach loop. What if the iterator is a subject itself, similar to the one defined above and we have the capability to pre-register observers with it? We get a merge of both worlds - interactive loop pulling values from the Iterator, which in turn calls subscribers on occurrence of the different events. This gives us a flexibility to augment or even change the result of the iteration. Even better, what to do in a loop becomes a configuration problem. The question-marks in foreach(...){???}
become configurable, rather than hard coded. Looks awfully like what can be achieved with cut-points in aspect oriented programming. Combined with other techniques it can lead to more declarative and flexible code than typically used.

I haven't touched on how to remove observers and combining observers with composable iterators expressed as steppers. I'm leaving that for later posts.

I must mention that I shamelessly use the ideas of Eric Meijer as seen on TV
and elsewhere for everything I've done in this write-up, and as an inspiration for most of the previous parts. The man has strange loop powers and weird and wonderful shirts. I highly recommend reading his papers and definitely watching his videos. There is much to be learned and a few worthy headaches to be had.

Powered by Drupal, an open source content management system