Tutorial: Virtual Patterns


 

To get started, think of virtual patterns as virtual methods. Then continue to discover what else they can do.

Virtual patterns used as virtual methods

When using virtual patterns just like virtual methods in other statically typed object-oriented languages, there are no new surprises, remembering that specialization does not discard anything, not even behavior. Here's an example:

Example 5

This is just the previous example, adjusted to a more reasonable shape by using virtual "methods:"


(* FILE ex5.gb *)
-- betaenv:descriptor --
(# 
   putline: (# enter stdio do '\n'->stdio #);
   person: 
     (# init:< (# enter name #);
        name: @string;
        print:< (# do 'Name: '+name->putline; INNER #)
     #);
   student: person
     (# init::< (# enter id #);
        id: @string;
        print::< (# do 'ID: '+id->putline; INNER #)
     #);
   freshman: student
     (# init::< (# enter nickname #);
        nickname: @string;
        print::< (# do 'Also-known-as: '+nickname->putline; INNER #)
     #);
   Smith: @freshman
do 
   ('Smith','533987/26B','Bunny')->Smith.init;
   Smith.print
#)

Note that the first (most general) occurrence of a virtual pattern declaration is marked with ":<". Here, it is the declarations of init and print in person.

Intermediate declarations, virtual further-bindings, are marked with "::<", and there is also the possibility to declare that a virtual is final, using the "::" mark (not shown).

Virtual patterns used for genericity

Since a pattern is a general descriptor of substance, virtual patterns can do more than "virtual methods." If we use the instantiated substance, i.e. the objects obtained from a given virtual pattern, as "objects", then the virtual pattern works as a type parameter on the enclosing pattern.

Example 6

This example shows a data-structure whose contained elements are qualified by a virtual pattern, element. When creating such a container from a specialization which further-binds element, the contained elements must be "at least" that kind of objects. ("At least" here means "instances of a specialization of that pattern," where "specialization of" is a reflexive relation, i.e. anything is a specialization of itself).


(* FILE ex6.gb *)
-- betaenv:descriptor --
(# 
   puttext: (# enter stdio do INNER #);
   putline: puttext(# do '\n'->stdio #);
   container: 
     (# element:< object;
        capacity:< integer;
        storage: [capacity] ^element;
        top: @integer;
        insert: (# enter storage[top+1->top][] #);
        scan:
          (# current: ^element;
          do (for i:top repeat storage[i][]->current[]; INNER for)
          #)
     #);
   myStrings: @container
     (# element::string; 
        capacity::(# do 10->value #);
        add: (# s: ^element enter &s do s[]->insert #);
        print: scan(# do current->puttext; ' '->puttext #)
     #);
do 
   'once'->myStrings.Add; 'upon'->myStrings.Add; 'a'->myStrings.Add; 
   'time'->myStrings.Add; '...'->myStrings.Add;
   myStrings.Print;
   putline
#)

Note that gbeta actually prints two warnings about a potential run-time type errors for this program. Actually, it is statically type-safe, and the type-checker will be able to detect this in a future version of gbeta. Se the section about bugs and inconveniences for more details.

Virtual patterns may be viewed as constant, automatically initialized pattern references: a pattern which depends on the actual enclosing current object, even though it is the same for all instances of the same pattern. The next section presents the even more dynamic pattern references.

 


Signed by: eernst@cs.auc.dk. Last Modified: 3-Jul-01