manpagez: man pages & more
info bigloo
Home | html | info | man
[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.4 Widening and shrinking

Bigloo introduces a new kind of inheritance: widening. This allows an object to be temporarily widened (that is transformed into an object of another class, a wide-class) and then shrink-ed (that is reshaped to its original class). This mechanism is very useful for implementing short-term data storage. For instance, Bigloo compilation passes are implemented using the widening/shrinking mechanism. On entry to a pass, objects are widened with the specific pass fields and, on exit from a pass, objects are shrunk in order to forget the information related to this pass.

Only instances of final classes can be widened and objects can only be widened in order to become instances of wide classes. Widening is performed by the widen! syntax:

bigloo syntax: widen!::wide-class obj (id value) …

The object obj is widened to be instance of the wide class wide-class. Fields values are either picked up from the parameter list of the widen! form or from the default values in the declaration of the wide class.

Objects are shrunk using the shrink! syntax:

bigloo syntax: shrink! obj

Here is a first example:

(module example
   (static (final-class point 
              (x (default 0))
              (y (default 0)))
           (wide-class named-point::point name)))

(define *point* (instantiate::point))

Two classes have been declared and an instance *point* of point has been allocated. For now, *point* is an instance of point but not an instance of named-point and this can be checked by:

(print (isa? *point* named))           → #t
(print (isa? *point* named-point))     → #f

Now, we widen *point*...

(let ((n-point (widen!::named-point *point* 
                  (name "orig"))))

And we check that now, n-point is an instance of named-point. Since named-point is a subclass of point, n-point still is an instance of point.

(print (isa? n-point named-point))  → #t
(print (isa? n-point named))        → #t

Widening affects the objects themselves. It does not operate any copy operation. Hence, *point* and n-point are eq?.

(print (eq? n-point *point*))   → #t

To end this example, we shrink n-point and check its class.

(shrink! n-point)
(print (isa? *point* named-point))) → #f

Here is a more complex example:

We illustrate widening and shrinking using our “wedding simulator”. First let us define three classes, person (for man and woman), married-woman and married-man:

(module wedding
   (static (final-class person 
               name::string
               fname::string
               (sex::symbol read-only))
           (wide-class married-man::person
               mate::person)
           (wide-class married-woman::person
               maiden-name::string
               mate::person)))

As we can see people are allowed to change their name but not their sex.

The identity of a person can be printed as

(define-method (object-display p::person . op)
   (with-access::person p (name fname sex)
      (print "firstname : " fname)
      (print "name      : " name)
      (print "sex       : " sex)
      p))

A married woman’s identity is printed by (we suppose an equivalent method definition for married-man)

(define-method (object-display p::married-woman . op)
   (with-access::married-woman p (name fname sex mate)
      (call-next-method)
      (print "married to: " mate) 
      p))

We create a person with the birth function:

(define (birth name::string fname::string sex)
   [assert (sex) (memq sex '(male female))]
   (instantiate::person 
      (name name)
      (fname fname)
      (sex sex)))

We celebrate a wedding using the get-married! function:

(define (get-married! woman::person man::person)
   (if (not (and (eq? (-> woman sex) 'female)
                 (eq? (-> man sex) 'male)))
       (error "get-married" 
              "Illegal wedding" 
              (cons woman man))
       (let* ((mname (-> woman name))
              (wife  (widen!::married-woman woman
                      (maiden-name mname)
                      (mate man))))
          (person-name-set! wife (-> man name))
          (widen!::married-man man
             (mate woman)))))

We can check if two people are married by

(define (couple? woman::person man::person)
   (and (isa? woman married-woman)
        (isa? man married-man)
        (eq? (with-access::married-woman woman (mate) mate) man)
        (eq? (with-access::married-man man (mate) mate) woman)))

Now let us study the life a Junior Jones and Pamela Smith. Once upon a time...

(define *junior* (birth "Jones" "Junior" 'male))
(define *pamela* (birth "Smith" "Pamela" 'female))

Later on, they met each other and ... they got married:

(define *old-boy-junior* *junior*)
(define *old-girl-pamela* *pamela*)
(get-married! *pamela* *junior*)

This union can be checked:

(couple? *pamela* *junior*)               
   ⇒ #t

We can look at the new identity of *pamela*

(print *pamela*)
   -| name      : Jones
      firstname : Pamela
      sex       : FEMALE
      married to: Junior Jones

But *pamela* and *junior* still are the same persons:

(print (eq? *old-boy-junior* *junior*))   ⇒ #t
(print (eq? *old-girl-pamela* *pamela*))  ⇒ #t

Unfortunately all days are not happy days. After having been married *pamela* and *junior* have divorced:

(define (divorce! woman::person man::person)
   (if (not (couple? woman man))
       (error "divorce!"
              "Illegal divorce"
              (cons woman man))
       (with-access::married-woman woman (maiden-name)
          (begin
             (shrink! woman)
             (set! (-> woman name) maiden-name))
          (shrink! man))))

(divorce! *pamela* *junior*)

We can look at the new identity of *pamela*

(print *pamela*)
   -| name      : Smith
      firstname : Pamela
      sex       : FEMALE

And *pamela* and *junior* still are the same persons:

(print (eq? *old-boy-junior* *junior*))   ⇒ #t
(print (eq? *old-girl-pamela* *pamela*))  ⇒ #t

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated on March 31, 2014 using texi2html 5.0.

© manpagez.com 2000-2024
Individual documents may contain additional copyright information.