mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 12:20:26 +02:00
update structure documentation
* doc/ref/api-compound.texi (Records): Add a link to SRFI-9 records. (Structures): Add a link to Records. Describe tail arrays as deprecated, and add a rationale and some details.
This commit is contained in:
parent
a38da400d7
commit
146b8f85e1
1 changed files with 83 additions and 39 deletions
|
@ -2257,6 +2257,10 @@ Return a new list whose contents match those of @var{vlist}.
|
||||||
A @dfn{record type} is a first class object representing a user-defined
|
A @dfn{record type} is a first class object representing a user-defined
|
||||||
data type. A @dfn{record} is an instance of a record type.
|
data type. A @dfn{record} is an instance of a record type.
|
||||||
|
|
||||||
|
Note that in many ways, this interface is too low-level for every-day
|
||||||
|
use. Most uses of records are better served by SRFI-9 records.
|
||||||
|
@xref{SRFI-9}.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} record? obj
|
@deffn {Scheme Procedure} record? obj
|
||||||
Return @code{#t} if @var{obj} is a record of any type and @code{#f}
|
Return @code{#t} if @var{obj} is a record of any type and @code{#f}
|
||||||
otherwise.
|
otherwise.
|
||||||
|
@ -2355,21 +2359,22 @@ created the type represented by @var{rtd}.
|
||||||
@tpindex Structures
|
@tpindex Structures
|
||||||
|
|
||||||
A @dfn{structure} is a first class data type which holds Scheme values
|
A @dfn{structure} is a first class data type which holds Scheme values
|
||||||
or C words in fields numbered 0 upwards. A @dfn{vtable} represents a
|
or C words in fields numbered 0 upwards. A @dfn{vtable} is a structure
|
||||||
structure type, giving field types and permissions, and an optional
|
that represents a structure type, giving field types and permissions,
|
||||||
print function for @code{write} etc.
|
and an optional print function for @code{write} etc.
|
||||||
|
|
||||||
Structures are lower level than records (@pxref{Records}) but have
|
Structures are lower level than records (@pxref{Records}). Usually,
|
||||||
some extra features. The vtable system allows sets of types be
|
when you need to represent structured data, you just want to use
|
||||||
constructed, with class data. The uninterpreted words can
|
records. But sometimes you need to implement new kinds of structured
|
||||||
inter-operate with C code, allowing arbitrary pointers or other values
|
data abstractions, and for that purpose structures are useful. Indeed,
|
||||||
to be stored along side usual Scheme @code{SCM} values.
|
records in Guile are implemented with structures.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Vtables::
|
* Vtables::
|
||||||
* Structure Basics::
|
* Structure Basics::
|
||||||
* Vtable Contents::
|
* Vtable Contents::
|
||||||
* Vtable Vtables::
|
* Vtable Vtables::
|
||||||
|
* Tail Arrays::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Vtables
|
@node Vtables
|
||||||
|
@ -2418,24 +2423,15 @@ The second letter for each field is a permission code,
|
||||||
@code{o} -- opaque, the field can be neither read nor written at the
|
@code{o} -- opaque, the field can be neither read nor written at the
|
||||||
Scheme level. This can be used for fields which should only be used
|
Scheme level. This can be used for fields which should only be used
|
||||||
from C code.
|
from C code.
|
||||||
@item
|
|
||||||
@code{W},@code{R},@code{O} -- a tail array, with permissions for the
|
|
||||||
array fields as per @code{w},@code{r},@code{o}.
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
A tail array is further fields at the end of a structure. The last
|
Here are some examples. @xref{Tail Arrays}, for information on the
|
||||||
field in the layout string might be for instance @samp{pW} to have a
|
legacy tail array facility.
|
||||||
tail of writable Scheme-valued fields. The @samp{pW} field itself
|
|
||||||
holds the tail size, and the tail fields come after it.
|
|
||||||
|
|
||||||
Here are some examples.
|
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(make-vtable "pw") ;; one writable field
|
(make-vtable "pw") ;; one writable field
|
||||||
(make-vtable "prpw") ;; one read-only and one writable
|
(make-vtable "prpw") ;; one read-only and one writable
|
||||||
(make-vtable "pwuwuw") ;; one scheme and two uninterpreted
|
(make-vtable "pwuwuw") ;; one scheme and two uninterpreted
|
||||||
|
|
||||||
(make-vtable "prpW") ;; one fixed then a tail array
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The optional @var{print} argument is a function called by
|
The optional @var{print} argument is a function called by
|
||||||
|
@ -2465,23 +2461,25 @@ structure.
|
||||||
|
|
||||||
This section describes the basic procedures for working with
|
This section describes the basic procedures for working with
|
||||||
structures. @code{make-struct} creates a structure, and
|
structures. @code{make-struct} creates a structure, and
|
||||||
@code{struct-ref} and @code{struct-set!} access write fields.
|
@code{struct-ref} and @code{struct-set!} access its fields.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} make-struct vtable tail-size init @dots{}
|
@deffn {Scheme Procedure} make-struct vtable tail-size init @dots{}
|
||||||
@deffnx {C Function} scm_make_struct (vtable, tail_size, init_list)
|
@deffnx {Scheme Procedure} make-struct/no-tail vtable init @dots{}
|
||||||
Create a new structure, with layout per the given @var{vtable}
|
Create a new structure, with layout per the given @var{vtable}
|
||||||
(@pxref{Vtables}).
|
(@pxref{Vtables}).
|
||||||
|
|
||||||
@var{tail-size} is the size of the tail array if @var{vtable}
|
|
||||||
specifies a tail array. @var{tail-size} should be 0 when @var{vtable}
|
|
||||||
doesn't specify a tail array.
|
|
||||||
|
|
||||||
The optional @var{init}@dots{} arguments are initial values for the
|
The optional @var{init}@dots{} arguments are initial values for the
|
||||||
fields of the structure (and the tail array). This is the only way to
|
fields of the structure. This is the only way to
|
||||||
put values in read-only fields. If there are fewer @var{init}
|
put values in read-only fields. If there are fewer @var{init}
|
||||||
arguments than fields then the defaults are @code{#f} for a Scheme
|
arguments than fields then the defaults are @code{#f} for a Scheme
|
||||||
field (type @code{p}) or 0 for an uninterpreted field (type @code{u}).
|
field (type @code{p}) or 0 for an uninterpreted field (type @code{u}).
|
||||||
|
|
||||||
|
Structures also have the ability to allocate a variable number of
|
||||||
|
additional cells at the end, at their tails. However, this legacy
|
||||||
|
@dfn{tail array} facilty is confusing and inefficient, and so we do not
|
||||||
|
recommend it. @xref{Tail Arrays}, for more on the legacy tail array
|
||||||
|
interface.
|
||||||
|
|
||||||
Type @code{s} self-reference fields, permission @code{o} opaque
|
Type @code{s} self-reference fields, permission @code{o} opaque
|
||||||
fields, and the count field of a tail array are all ignored for the
|
fields, and the count field of a tail array are all ignored for the
|
||||||
@var{init} arguments, ie.@: an argument is not consumed by such a
|
@var{init} arguments, ie.@: an argument is not consumed by such a
|
||||||
|
@ -2498,18 +2496,17 @@ For example,
|
||||||
(struct-ref s 0) @result{} 123
|
(struct-ref s 0) @result{} 123
|
||||||
(struct-ref s 1) @result{} "abc"
|
(struct-ref s 1) @result{} "abc"
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@example
|
|
||||||
(define v (make-vtable "prpW"))
|
|
||||||
(define s (make-struct v 6 "fixed field" 'x 'y))
|
|
||||||
(struct-ref s 0) @result{} "fixed field"
|
|
||||||
(struct-ref s 1) @result{} 2 ;; tail size
|
|
||||||
(struct-ref s 2) @result{} x ;; tail array ...
|
|
||||||
(struct-ref s 3) @result{} y
|
|
||||||
(struct-ref s 4) @result{} #f
|
|
||||||
@end example
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deftypefn {C Function} SCM scm_make_struct (SCM vtable, SCM tail_size, SCM init_list)
|
||||||
|
@deftypefnx {C Function} SCM scm_c_make_struct (SCM vtable, SCM tail_size, SCM init, ...)
|
||||||
|
@deftypefnx {C Function} SCM scm_c_make_structv (SCM vtable, SCM tail_size, size_t n_inits, scm_t_bits init[])
|
||||||
|
There are a few ways to make structures from C. @code{scm_make_struct}
|
||||||
|
takes a list, @code{scm_c_make_struct} takes variable arguments
|
||||||
|
terminated with SCM_UNDEFINED, and @code{scm_c_make_structv} takes a
|
||||||
|
packed array.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} struct? obj
|
@deffn {Scheme Procedure} struct? obj
|
||||||
@deffnx {C Function} scm_struct_p (obj)
|
@deffnx {C Function} scm_struct_p (obj)
|
||||||
Return @code{#t} if @var{obj} is a structure, or @code{#f} if not.
|
Return @code{#t} if @var{obj} is a structure, or @code{#f} if not.
|
||||||
|
@ -2535,10 +2532,10 @@ be written because it's @code{r} read-only or @code{o} opaque.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} struct-vtable struct
|
@deffn {Scheme Procedure} struct-vtable struct
|
||||||
@deffnx {C Function} scm_struct_vtable (struct)
|
@deffnx {C Function} scm_struct_vtable (struct)
|
||||||
Return the vtable used by @var{struct}.
|
Return the vtable that describes @var{struct}.
|
||||||
|
|
||||||
This can be used to examine the layout of an unknown structure, see
|
The vtable is effectively the type of the structure. See @ref{Vtable
|
||||||
@ref{Vtable Contents}.
|
Contents}, for more on vtables.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -2735,6 +2732,53 @@ which can be changed.
|
||||||
ball @result{} #<a green ball owned by Nisse>
|
ball @result{} #<a green ball owned by Nisse>
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
|
@node Tail Arrays
|
||||||
|
@subsubsection Tail Arrays
|
||||||
|
|
||||||
|
Guile's structures have a facility whereby each instance of a vtable can
|
||||||
|
contain a variable-length tail array of values. The length of the tail
|
||||||
|
array is stored in the structure. This facility was originally intended
|
||||||
|
to allow C code to expose raw C structures with word-sized tail arrays
|
||||||
|
to Scheme.
|
||||||
|
|
||||||
|
However, the tail array facility is confusing and doesn't work very
|
||||||
|
well. It is very rarely used, but it insinuates itself into all
|
||||||
|
invocations of @code{make-struct}. For this reason the clumsily-named
|
||||||
|
@code{make-struct/no-tail} procedure can actually be more elegant in
|
||||||
|
actual use, because it doesn't have a random @code{0} argument stuck in
|
||||||
|
the middle.
|
||||||
|
|
||||||
|
Tail arrays also inhibit optimization by allowing instances to affect
|
||||||
|
their shapes. In the absence of tail arrays, all instances of a given
|
||||||
|
vtable have the same number and kinds of fields. This uniformity can be
|
||||||
|
exploited by the runtime and the optimizer. The presence of tail arrays
|
||||||
|
make some of these optimizations more difficult.
|
||||||
|
|
||||||
|
Finally, the tail array facility is ad-hoc and does not compose with the
|
||||||
|
rest of Guile. If a Guile user wants an array with user-specified
|
||||||
|
length, it's best to use a vector. It is more clear in the code, and
|
||||||
|
the standard optimization techniques will do a good job with it.
|
||||||
|
|
||||||
|
That said, we should mention some details about the interface. A vtable
|
||||||
|
that has tail array has upper-case permission descriptors: @code{W},
|
||||||
|
@code{R} or @code{O}, correspoding to tail arrays of writable,
|
||||||
|
read-only, or opaque elements. A tail array permission descriptor may
|
||||||
|
only appear in the last element of a vtable layout.
|
||||||
|
|
||||||
|
For exampple, @samp{pW} indicates a tail of writable Scheme-valued
|
||||||
|
fields. The @samp{pW} field itself holds the tail size, and the tail
|
||||||
|
fields come after it.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define v (make-vtable "prpW")) ;; one fixed then a tail array
|
||||||
|
(define s (make-struct v 6 "fixed field" 'x 'y))
|
||||||
|
(struct-ref s 0) @result{} "fixed field"
|
||||||
|
(struct-ref s 1) @result{} 2 ;; tail size
|
||||||
|
(struct-ref s 2) @result{} x ;; tail array ...
|
||||||
|
(struct-ref s 3) @result{} y
|
||||||
|
(struct-ref s 4) @result{} #f
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
@node Dictionary Types
|
@node Dictionary Types
|
||||||
@subsection Dictionary Types
|
@subsection Dictionary Types
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue