Please open ChoralSociety.lava in LavaPE.
Please open ModelView.lava in LavaPE.
Please open QueueOfPoint.lava in LavaPE.
Please open Visitor.lava in LavaPE.
Please open FinalVirtualType.lava in LavaPE.
Please open FactoryForceOverride.lava in LavaPE.
Interfaces and packages with type parameters ("virtual types"), covariant specialization.
ChoralSociety:
The ChoralSociety sample provides a package S ("Society") with two virtual types society and member. In S the value of society is the type Society, the value of member is Member. A second package CS ("ChoralSociety") is derived from S by specializing society to become ChoralSociety (in turn derived fro Society) and member to become Singer (derived from Member). As a consequence, the MemberList becomes a list of Singers in CS automatically, and the chairman is also a Singer in CS rather than just a Member.
ModelView:
The ModelView sample (based on the well-known subject/observer pattern) reconstructs the corresponding sample from [16]. It provides a package ModelViewFW ("model/view framework") with two type parameters "model" and "view". "ModelViewFW" contains two mutually recursive types "Model" and "View". "Model" contains a member vList which is a homogeneous "ViewList" all of whose elements have the same virtual type setElem=~<view>. (The tilde "~" marks variable state objects in Lava.)
Package "DrawFW" shows how the (rudimentary) framework "ModelViewFW" could be specialized by overriding its virtual types (= type parameters) "model" and "view".
See our ModelManyViews sample for another variant of Model/View that provides an inhomogeneous "ViewList" containing different types of views (on the basis of "substitutable types").
QueueOfPoint:
The QueueOfPoint sample corresponds to a similar sample in [16], too. Compared to [16], it shows again the advantage of making virtual types non-substitutable by default: We need not view the virtual type "elemType" as a special, type-valued member variable of "Queue" objects but we can introduce virtual types in a more static way as type parameters of classes and packages.
Visitor:
The Visitor sample illustrates a special case of the well-known "Visitor" pattern of [8] and also a special case of indirect tree recursion.
FinalVirtualType and FactoryForceOverride:
There are situations where you want to assign an object of a concrete Lava class to a variable whose type is virtual, particularly if you create the object from scratch using the new expression of Lava. In the new expression you have to select one of the initializers of the respective Lava class generally. But only concrete Lava classes have initializers, virtual type parameters don't. Therfore you are not allowed to specify a virtual type as the type of the new object in the new expression, but only a concrete Lava class.
The assignment "concrete to virtual type" can be made compatible in two ways in Lava
ModelView:ew:
Note in particular the "covariant
specialization" of the only input parameter of function registerView
of class Model.
Note how this is exploited in the exec of the main program ModelViewDemo to pass a view object of the derived type DrawFW::View to this function.
Note that DrawFW::View is not compatible in the traditional sense (of c-derivation) to ModelViewFW::View, since it contains member variables (myModel) and function parameters (m of initializer ini) that are of a more derived type in pattern DrawFW than in ModelViewFW (as a consequence of covariant specialization of the VT <MODEL>).
QueueOfPoint:
Note the difference between the classes X_inner and X_outer: X_inner belongs to pattern Queue (a
class having a VT elemType), whereas X_outer is declared outside
class Queue.
Both have a member function f with almost identical implementations.
Look at these:
The difference between the implementations of the two versions of f is that one of them belongs to pattern Queue, and one doesn't. The former has to use the virtual type <Queue::elemType> of Queue to declare the local variable p, the latter cannot use this but must use the concrete class Point to declare p. The reasons are:
The first rule corresponds to rule 9 in our Lava genericity section. Its motivation is explained in our IsSelfVirtual sample.
The reason for the validity of the second rule is simple: The value of a VT (= type parameter) is determined by the respective pattern context. So if you are outside a pattern P and outside of any pattern that is derived from P, the values of P's VTs at the actual place of reference are just undefined.
Visitor:
The Visitor pattern defines an abstract virtual type R for the
result of the visitor's tree evaluation function evaluate. The way how
the visitor walks through the tree is described by this evaluate method
and doesn't depend on R, while the treatment of the individual tree
nodes depends on R and is implemented by the overridden methods
evalLeaf and evalNode of StringVisitor and
IntVisitor. The initiator VisitorDemo shows how a sample tree is
constructed and how this same tree is evaluated twice: once by the
StringVisitor and once by the IntVisitor
Please note the comments in the VisitorDemo initiator.
FinalVirtualType:
Look into the property sheet of virtual type ELEMTYPE and into the
implementation of the initializer StringSet::ini, and also into the main program
FinalVT.
FactoryForceOverride:
Look into the property sheets and the implementations of the factory
functions Framework::Application::CreateDoc and
MyFramework::Application::CreateDoc, and also into the main program
FactoryOverrideDemo.
See also our CallbackSample