www.delorie.com/gnu/docs/guile/guile_235.html   search  
 
Buy GNU books!


Guile Reference Manual

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

22.5.4 Vtables

Vtables are structures that are used to represent structure types. Each vtable contains a layout specification in field vtable-index-layout -- instances of the type are laid out according to that specification. Vtables contain additional fields which are used only internally to libguile. The variable vtable-offset-user is bound to a field number. Vtable fields at that position or greater are user definable.

Scheme Procedure: struct-vtable handle
C Function: scm_struct_vtable (handle)
Return the vtable structure that describes the type of struct.

Scheme Procedure: struct-vtable? x
C Function: scm_struct_vtable_p (x)
Return #t iff x is a vtable structure.

If you have a vtable structure, V, you can create an instance of the type it describes by using (make-struct V ...). But where does V itself come from? One possibility is that V is an instance of a user-defined vtable type, V', so that V is created by using (make-struct V' ...). Another possibility is that V is an instance of the type it itself describes. Vtable structures of the second sort are created by this procedure:

Scheme Procedure: make-vtable-vtable user_fields tail_array_size . init
C Function: scm_make_vtable_vtable (user_fields, tail_array_size, init)
Return a new, self-describing vtable structure.

user-fields is a string describing user defined fields of the vtable beginning at index vtable-offset-user (see make-struct-layout).

tail-size specifies the size of the tail-array (if any) of this vtable.

init1, ... are the optional initializers for the fields of the vtable.

Vtables have one initializable system field--the struct printer. This field comes before the user fields in the initializers passed to make-vtable-vtable and make-struct, and thus works as a third optional argument to make-vtable-vtable and a fourth to make-struct when creating vtables:

If the value is a procedure, it will be called instead of the standard printer whenever a struct described by this vtable is printed. The procedure will be called with arguments STRUCT and PORT.

The structure of a struct is described by a vtable, so the vtable is in essence the type of the struct. The vtable is itself a struct with a vtable. This could go on forever if it weren't for the vtable-vtables which are self-describing vtables, and thus terminate the chain.

There are several potential ways of using structs, but the standard one is to use three kinds of structs, together building up a type sub-system: one vtable-vtable working as the root and one or several "types", each with a set of "instances". (The vtable-vtable should be compared to the class <class> which is the class of itself.)

 
(define ball-root (make-vtable-vtable "pr" 0))

(define (make-ball-type ball-color)
  (make-struct ball-root 0
	       (make-struct-layout "pw")
               (lambda (ball port)
                 (format port "#"
                         (color ball)
                         (owner ball)))
               ball-color))
(define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user))
(define (owner ball) (struct-ref ball 0))

(define red (make-ball-type 'red))
(define green (make-ball-type 'green))

(define (make-ball type owner) (make-struct type 0 owner))

(define ball (make-ball green 'Nisse))
ball => #<a green ball owned by Nisse>

Scheme Procedure: struct-vtable-name vtable
C Function: scm_struct_vtable_name (vtable)
Return the name of the vtable vtable.

Scheme Procedure: set-struct-vtable-name! vtable name
C Function: scm_set_struct_vtable_name_x (vtable, name)
Set the name of the vtable vtable to name.

Scheme Procedure: struct-vtable-tag handle
C Function: scm_struct_vtable_tag (handle)
Return the vtable tag of the structure handle.


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

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003