Just recording a bit of my learning the internals of Roassal, since it helps me flesh out my understanding.
At first glance looking at [ROShape>>addLast:] this seemed to recursively call itself with no exit-condition, but then I noticed its ivar 'next' is initialized to ROChildrenShape this provides the exit condition inherited from RONullShape. Adding a shape replaces this ROChildrenShape in 'next', but the new shape itself has a ROChildrenShape in its 'next' .
I haven't got as far looking at ROChildrenShape yet, but briefly thought it might be a container holding other shapes, but then actually I think it is the ROElements ivar 'elements' that is the container of subview nodes - and that ROChildrenShape just stores how to draw the subview nodes.
I guess it is the lack of the [drawOn:For:] method that distinguishes between abstract and concrete ROShape classes. By the way, what is the design decision of leaving [ROShape>>drawOn:For] blank rather than using [self subclassResponsibility] ?
So, just to confirm my understanding, perhaps the following or similar would be useful as a comment on ROShape>>addLast: "Instance variable 'next' must be a RONullShape to provide the exit condition of this recursive call. This is ensured by instance initialization"
cheers -ben