Copyright (C) 2000-2012 |
GNU Info (guile.info)VtablesVtables ------- 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. - primitive: struct-vtable handle Return the vtable structure that describes the type of STRUCT. - primitive: struct-vtable? x Return #t iff obj 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: - primitive: 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 "#<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> - primitive: struct-vtable-name vtable - primitive: set-struct-vtable-name! vtable name - primitive: struct-vtable-tag handle automatically generated by info2www version 1.2.2.9 |