As a structure, a vtable also has a vtable, which is also a structure. Structures, their vtables, the vtables of the vtables, and so on form a tree of structures. Making a new structure adds a leaf to the tree, and if that structure is a vtable, it may be used to create other leaves.
If you traverse up the tree of vtables, via calling
struct-vtable, eventually you reach a root which is the vtable of
[email protected](guile-user)> (current-module) $1 = #<directory (guile-user) 221b090> [email protected](guile-user)> (struct-vtable $1) $2 = #<record-type module> [email protected](guile-user)> (struct-vtable $2) $3 = #<<standard-vtable> 12c30a0> [email protected](guile-user)> (struct-vtable $3) $4 = #<<standard-vtable> 12c3fa0> [email protected](guile-user)> (struct-vtable $4) $5 = #<<standard-vtable> 12c3fa0> [email protected](guile-user)> <standard-vtable> $6 = #<<standard-vtable> 12c3fa0>
In this example, we can say that
$1 is an instance of
$2 is an instance of
$3 is an instance of
$4, strangely enough, is an instance of itself.
The value bound to
$4 in this console session also bound to
<standard-vtable> in the default environment.
A meta-vtable, useful for making new vtables.
All of these values are structures. All but
$1 are vtables. As
$2 is an instance of
$3 is a vtable, we can
$3 is a meta-vtable: a vtable that can create
With this definition, we can specify more precisely what a vtable is: a vtable is a structure made from a meta-vtable. Making a structure from a meta-vtable runs some special checks to ensure that the first field of the structure is a valid layout. Additionally, if these checks see that the layout of the child vtable contains all the required fields of a vtable, in the correct order, then the child vtable will also be a meta-table, inheriting a magical bit from the parent.
#t if obj is a vtable structure: an instance of a
<standard-vtable> is a root of the vtable tree. (Normally there
is only one root in a given Guile process, but due to some legacy
interfaces there may be more than one.)
The set of required fields of a vtable is the set of fields in the
<standard-vtable>, and is bound to
in the default environment. It is possible to create a meta-vtable that
with additional fields in its layout, which can be used to create
vtables with additional data:
[email protected](guile-user)> (struct-ref $3 vtable-index-layout) $6 = pwuhuhpwphuhuhpwpwpw [email protected](guile-user)> (struct-ref $4 vtable-index-layout) $7 = pwuhuhpwphuhuh [email protected](guile-user)> standard-vtable-fields $8 = "pwuhuhpwphuhuh" [email protected](guile-user)> (struct-ref $2 vtable-offset-user) $9 = module
In this continuation of our earlier example,
$2 is a vtable that
has extra fields, because its vtable,
$3, was made from a
meta-vtable with an extended layout.
vtable-offset-user is a
convenient definition that indicates the number of fields in
A string containing the ordered set of fields that a vtable must have.
The first index in a vtable that is available for a user.
Return a structure layout symbol, from a fields string.
fields is as described under
(see Vtables). An invalid fields string is an error.
With these definitions, one can define
make-vtable in this way:
(define* (make-vtable fields #:optional printer) (make-struct/no-tail <standard-vtable> (make-struct-layout fields) printer))