Node:Vtables, Previous:Structure Basics, Up:Structures
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.
struct-vtable handle | Scheme Procedure |
scm_struct_vtable (handle) | C Function |
Return the vtable structure that describes the type of struct. |
struct-vtable? x | Scheme Procedure |
scm_struct_vtable_p (x) | C Function |
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:
make-vtable-vtable user_fields tail_array_size . init | Scheme Procedure |
scm_make_vtable_vtable (user_fields, tail_array_size, init) | C Function |
Return a new, self-describing vtable structure.
user-fields is a string describing user defined fields of the
vtable beginning at index 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 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 "#<a ~A ball owned by ~A>" (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> |
struct-vtable-name vtable | Scheme Procedure |
scm_struct_vtable_name (vtable) | C Function |
Return the name of the vtable vtable. |
set-struct-vtable-name! vtable name | Scheme Procedure |
scm_set_struct_vtable_name_x (vtable, name) | C Function |
Set the name of the vtable vtable to name. |
struct-vtable-tag handle | Scheme Procedure |
scm_struct_vtable_tag (handle) | C Function |
Return the vtable tag of the structure handle. |