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|
If you have a vtable structure,
V, you can create an instance of
the type it describes by using
(make-struct V ...). But where
V itself come from? One possibility is that
V is an
instance of a user-defined vtable type,
V', so that
created by using
(make-struct V' ...). Another possibility is
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
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.|