-\input texinfo
-@c -*-texinfo-*-
-@c %**start of header
-@setfilename data-rep.info
-@settitle Data Representation in Guile
-@c %**end of header
-
-@include version.texi
-
-@dircategory The Algorithmic Language Scheme
-@direntry
-* data-rep: (data-rep). Data Representation in Guile --- how to use
+@c essay \input texinfo
+@c essay @c -*-texinfo-*-
+@c essay @c %**start of header
+@c essay @setfilename data-rep.info
+@c essay @settitle Data Representation in Guile
+@c essay @c %**end of header
+
+@c essay @include version.texi
+
+@c essay @dircategory The Algorithmic Language Scheme
+@c essay @direntry
+@c essay * data-rep: (data-rep). Data Representation in Guile --- how to use
Guile objects in your C code.
-@end direntry
-
-@setchapternewpage off
-
-@ifinfo
-Data Representation in Guile
-
-Copyright (C) 1998, 1999 Free Software Foundation
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-@ignore
-Permission is granted to process this file through TeX and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
-@end ignore
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the entire
-resulting derived work is distributed under the terms of a permission
-notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that this permission notice may be stated in a translation approved
-by the Free Software Foundation.
-@end ifinfo
-
-@titlepage
-@sp 10
-@comment The title is printed in a large font.
-@title Data Representation in Guile
-@subtitle $Id: data-rep.texi,v 1.8 1999-12-07 22:43:01 ghouston Exp $
-@subtitle For use with Guile @value{VERSION}
-@author Jim Blandy
-@author Free Software Foundation
-@author @email{jimb@@red-bean.com}
-@c The following two commands start the copyright page.
-@page
-@vskip 0pt plus 1filll
-@vskip 0pt plus 1filll
-Copyright @copyright{} 1998 Free Software Foundation
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the entire
-resulting derived work is distributed under the terms of a permission
-notice identical to this one.
+@c essay @end direntry
+
+@c essay @setchapternewpage off
+
+@c essay @ifinfo
+@c essay Data Representation in Guile
+
+@c essay Copyright (C) 1998, 1999, 2000 Free Software Foundation
+
+@c essay Permission is granted to make and distribute verbatim copies of
+@c essay this manual provided the copyright notice and this permission notice
+@c essay are preserved on all copies.
+
+@c essay @ignore
+@c essay Permission is granted to process this file through TeX and print the
+@c essay results, provided the printed document carries copying permission
+@c essay notice identical to this one except for the removal of this paragraph
+@c essay (this paragraph not being relevant to the printed manual).
+@c essay @end ignore
+
+@c essay Permission is granted to copy and distribute modified versions of this
+@c essay manual under the conditions for verbatim copying, provided that the entire
+@c essay resulting derived work is distributed under the terms of a permission
+@c essay notice identical to this one.
+
+@c essay Permission is granted to copy and distribute translations of this manual
+@c essay into another language, under the above conditions for modified versions,
+@c essay except that this permission notice may be stated in a translation approved
+@c essay by the Free Software Foundation.
+@c essay @end ifinfo
+
+@c essay @titlepage
+@c essay @sp 10
+@c essay @comment The title is printed in a large font.
+@c essay @title Data Representation in Guile
+@c essay @subtitle $Id: data-rep.texi,v 1.17 2001-03-09 08:21:59 ossau Exp $
+@c essay @subtitle For use with Guile @value{VERSION}
+@c essay @author Jim Blandy
+@c essay @author Free Software Foundation
+@c essay @author @email{jimb@@red-bean.com}
+@c essay @c The following two commands start the copyright page.
+@c essay @page
+@c essay @vskip 0pt plus 1filll
+@c essay @vskip 0pt plus 1filll
+@c essay Copyright @copyright{} 1998 Free Software Foundation
+
+@c essay Permission is granted to make and distribute verbatim copies of
+@c essay this manual provided the copyright notice and this permission notice
+@c essay are preserved on all copies.
+
+@c essay Permission is granted to copy and distribute modified versions of this
+@c essay manual under the conditions for verbatim copying, provided that the entire
+@c essay resulting derived work is distributed under the terms of a permission
+@c essay notice identical to this one.
+
+@c essay Permission is granted to copy and distribute translations of this manual
+@c essay into another language, under the above conditions for modified versions,
+@c essay except that this permission notice may be stated in a translation approved
+@c essay by Free Software Foundation.
+@c essay @end titlepage
+
+@c essay @c @smallbook
+@c essay @c @finalout
+@c essay @headings double
+
+
+@c essay @node Top, Data Representation in Scheme, (dir), (dir)
+@c essay @top Data Representation in Guile
+
+@c essay @ifinfo
+@c essay This essay is meant to provide the background necessary to read and
+@c essay write C code that manipulates Scheme values in a way that conforms to
+@c essay libguile's interface. If you would like to write or maintain a
+@c essay Guile-based application in C or C++, this is the first information you
+@c essay need.
+
+@c essay In order to make sense of Guile's @code{SCM_} functions, or read
+@c essay libguile's source code, it's essential to have a good grasp of how Guile
+@c essay actually represents Scheme values. Otherwise, a lot of the code, and
+@c essay the conventions it follows, won't make very much sense.
+
+@c essay We assume you know both C and Scheme, but we do not assume you are
+@c essay familiar with Guile's C interface.
+@c essay @end ifinfo
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that this permission notice may be stated in a translation approved
-by Free Software Foundation.
-@end titlepage
-@c @smallbook
-@c @finalout
-@headings double
+@page
+@node Data Representation
+@chapter Data Representation in Guile
+@strong{by Jim Blandy}
-@node Top, Data Representation in Scheme, (dir), (dir)
-@top Data Representation in Guile
+[Due to the rather non-orthogonal and performance-oriented nature of the
+SCM interface, you need to understand SCM internals *before* you can use
+the SCM API. That's why this chapter comes first.]
-@ifinfo
-This essay is meant to provide the background necessary to read and
-write C code that manipulates Scheme values in a way that conforms to
-libguile's interface. If you would like to write or maintain a
-Guile-based application, this is the first information you need.
+[NOTE: this is Jim Blandy's essay almost entirely unmodified. It has to
+be adapted to fit this manual smoothly.]
In order to make sense of Guile's SCM_ functions, or read libguile's
source code, it's essential to have a good grasp of how Guile actually
represents Scheme values. Otherwise, a lot of the code, and the
-conventions it follows, won't make very much sense.
+conventions it follows, won't make very much sense. This essay is meant
+to provide the background necessary to read and write C code that
+manipulates Scheme values in a way that is compatible with libguile.
We assume you know both C and Scheme, but we do not assume you are
-familiar with Guile's C interface.
-@end ifinfo
+familiar with Guile's implementation.
@menu
* Data Representation in Scheme:: Why things aren't just totally
application-specific datatypes.
@end menu
-@node Data Representation in Scheme, How Guile does it, Top, Top
+@node Data Representation in Scheme
@section Data Representation in Scheme
Scheme is a latently-typed language; this means that the system cannot,
* Guile Is Hairier::
@end menu
-@node A Simple Representation, Faster Integers, Data Representation in Scheme, Data Representation in Scheme
+@node A Simple Representation
@subsection A Simple Representation
The simplest way to meet the above requirements in C would be to
@end itemize
-@node Faster Integers, Cheaper Pairs, A Simple Representation, Data Representation in Scheme
+@node Faster Integers
@subsection Faster Integers
Unfortunately, the above representation has a serious disadvantage. In
@code{01} in their least significant bits, and integers had @code{00}?)
-@node Cheaper Pairs, Guile Is Hairier, Faster Integers, Data Representation in Scheme
+@node Cheaper Pairs
@subsection Cheaper Pairs
However, there is yet another issue to confront. Most Scheme heaps
unmodified pointer.
-@node Guile Is Hairier, , Cheaper Pairs, Data Representation in Scheme
+@node Guile Is Hairier
@subsection Guile Is Hairier
We originally started with a very simple typing system --- each object
more complex than what we've presented above.
-@node How Guile does it, Defining New Types (Smobs), Data Representation in Scheme, Top
+@node How Guile does it
@section How Guile does it
Here we present the specifics of how Guile represents its data. We
@menu
* General Rules::
-* Garbage Collection::
+* Conservative GC::
* Immediates vs. Non-immediates::
* Immediate Datatypes::
* Non-immediate Datatypes::
* Signalling Type Errors::
@end menu
-@node General Rules, Garbage Collection, How Guile does it, How Guile does it
+@node General Rules
@subsection General Rules
Any code which operates on Guile datatypes must @code{#include} the
@emph{not} a pair object (a @code{CONS}).
-@node Garbage Collection, Immediates vs. Non-immediates, General Rules, How Guile does it
-@subsection Garbage Collection
+@node Conservative GC
+@subsection Conservative Garbage Collection
Aside from the latent typing, the major source of constraints on a
Scheme implementation's data representation is the garbage collector.
variable addresses, is effectively much less reliable, due to programmer
error.
-To accomodate this technique, data must be represented so that the
+To accommodate this technique, data must be represented so that the
collector can accurately determine whether a given stack word is a
pointer or not. Guile does this as follows:
@itemize @bullet
and then use the cell's type to find more pointers to trace.
-@node Immediates vs. Non-immediates, Immediate Datatypes, Garbage Collection, How Guile does it
+@node Immediates vs. Non-immediates
@subsection Immediates vs. Non-immediates
Guile classifies Scheme objects into two kinds: those that fit entirely
@end deftypefn
-@node Immediate Datatypes, Non-immediate Datatypes, Immediates vs. Non-immediates, How Guile does it
+@node Immediate Datatypes
@subsection Immediate Datatypes
The following datatypes are immediate values; that is, they fit entirely
@menu
-* Integers::
-* Characters::
-* Booleans::
+* Integer Data::
+* Character Data::
+* Boolean Data::
* Unique Values::
@end menu
-@node Integers, Characters, Immediate Datatypes, Immediate Datatypes
+@node Integer Data
@subsubsection Integers
Here are functions for operating on small integers, that fit within an
@end deftypefn
-@node Characters, Booleans, Integers, Immediate Datatypes
+@node Character Data
@subsubsection Characters
Here are functions for operating on characters.
-@deftypefn Macro int SCM_ICHRP (SCM @var{x})
+@deftypefn Macro int SCM_CHARP (SCM @var{x})
Return non-zero iff @var{x} is a character value.
@end deftypefn
-@deftypefn Macro {unsigned int} SCM_ICHR (SCM @var{x})
+@deftypefn Macro {unsigned int} SCM_CHAR (SCM @var{x})
Return the value of @code{x} as a C character. If @var{x} is not a
Scheme character, the result is undefined.
@end deftypefn
-@deftypefn Macro SCM SCM_MAKICHR (SCM @var{c})
+@deftypefn Macro SCM SCM_MAKE_CHAR (int @var{c})
Given a C character @var{c}, return its representation as a Scheme
character value.
@end deftypefn
-@node Booleans, Unique Values, Characters, Immediate Datatypes
+@node Boolean Data
@subsubsection Booleans
Here are functions and macros for operating on booleans.
@end deftypefn
-@node Unique Values, , Booleans, Immediate Datatypes
+@node Unique Values
@subsubsection Unique Values
The immediate values that are neither small integers, characters, nor
@end deftypefn
-@node Non-immediate Datatypes, Signalling Type Errors, Immediate Datatypes, How Guile does it
+@node Non-immediate Datatypes
@subsection Non-immediate Datatypes
A non-immediate datatype is one which lives in the heap, either because
@menu
* Non-immediate Type Predicates:: Special rules for using the type
predicates described here.
-* Pairs::
-* Vectors::
+* Pair Data::
+* Vector Data::
* Procedures::
* Closures::
* Subrs::
-* Ports::
+* Port Data::
@end menu
-@node Non-immediate Type Predicates, Pairs, Non-immediate Datatypes, Non-immediate Datatypes
+@node Non-immediate Type Predicates
@subsubsection Non-immediate Type Predicates
-As mentioned in @ref{Garbage Collection}, all non-immediate objects
+As mentioned in @ref{Conservative GC}, all non-immediate objects
start with a @dfn{cell}, or a pair of words. Furthermore, all type
information that distinguishes one kind of non-immediate from another is
stored in the cell. The type information in the @code{SCM} value
@end example
-@node Pairs, Vectors, Non-immediate Type Predicates, Non-immediate Datatypes
+@node Pair Data
@subsubsection Pairs
Pairs are the essential building block of list structure in Scheme. A
@end deftypefn
-@node Vectors, Procedures, Pairs, Non-immediate Datatypes
+@node Vector Data
@subsubsection Vectors, Strings, and Symbols
Vectors, strings, and symbols have some properties in common. They all
characters, but you don't want to know about those. What cruft!
-@node Procedures, Closures, Vectors, Non-immediate Datatypes
+@node Procedures
@subsubsection Procedures
Guile provides two kinds of procedures: @dfn{closures}, which are the
@end deftypefun
-@node Closures, Subrs, Procedures, Non-immediate Datatypes
+@node Closures
@subsubsection Closures
[FIXME: this needs to be further subbed, but texinfo has no subsubsub]
@end deftypefn
-@node Subrs, Ports, Closures, Non-immediate Datatypes
+@node Subrs
@subsubsection Subrs
[FIXME: this needs to be further subbed, but texinfo has no subsubsub]
@end deftypefun
-@node Ports, , Subrs, Non-immediate Datatypes
+@node Port Data
@subsubsection Ports
Haven't written this yet, 'cos I don't understand ports yet.
-@node Signalling Type Errors, , Non-immediate Datatypes, How Guile does it
+@node Signalling Type Errors
@subsection Signalling Type Errors
Every function visible at the Scheme level should aggressively check the
invoking the subr, so we don't run into these problems.
@end deftypefn
-@deftypefn Macro int SCM_OUTOFRANGE
-Signal an error complaining that @var{obj} is ``out of range'' for
-@var{subr}.
-@end deftypefn
-
-@node Defining New Types (Smobs), , How Guile does it, Top
+@node Defining New Types (Smobs)
@section Defining New Types (Smobs)
@dfn{Smobs} are Guile's mechanism for adding new non-immediate types to
* A Complete Example::
@end menu
-@node Describing a New Type, Creating Instances, Defining New Types (Smobs), Defining New Types (Smobs)
+@node Describing a New Type
@subsection Describing a New Type
To define a new type, the programmer must write four functions to
the value, as for @code{display} or @code{write}. The function should
write a printed representation of @var{exp} on @var{port}, in accordance
with the parameters in @var{pstate}. (For more information on print
-states, see @ref{Ports}.) The default print function prints @code{#<NAME ADDRESS>}
+states, see @ref{Port Data}.) The default print function prints @code{#<NAME ADDRESS>}
where @code{NAME} is the first argument passed to @code{scm_make_smob_type} or
@code{scm_make_smob_type_mfpe}.
@end table
-To actually register the new smob type, you must call either @code{scm_make_smob_type}
-or @code{scm_make_smob_type_mfpe}:
+To actually register the new smob type, call @code{scm_make_smob_type}:
@deftypefun long scm_make_smob_type (const char *name, scm_sizet size)
-This function adds a new smob type, named @var{name}, with instance size @var{size} to the system.
-The return value is a tag that is used in creating instances of the type. If @var{size}
-is 0, then no memory will be allocated when instances of the smob are created, and
-nothing will be freed by the default free function.
+This function implements the standard way of adding a new smob type,
+named @var{name}, with instance size @var{size}, to the system. The
+return value is a tag that is used in creating instances of the type.
+If @var{size} is 0, then no memory will be allocated when instances of
+the smob are created, and nothing will be freed by the default free
+function. Default values are provided for mark, free, print, and,
+equalp, as described above. If you want to customize any of these
+functions, the call to @code{scm_make_smob_type} should be immediately
+followed by calls to one or several of @code{scm_set_smob_mark},
+@code{scm_set_smob_free}, @code{scm_set_smob_print}, and/or
+@code{scm_set_smob_equalp}.
@end deftypefun
Each of the below @code{scm_set_smob_XXX} functions registers a smob
-special function for a given type. You can instead use
-@code{scm_make_smob_type_mfpe} to register the special smob functions
-when you create the smob type, if you prefer.
+special function for a given type. Each function is intended to be used
+only zero or one time per type, and the call should be placed
+immediately following the call to @code{scm_make_smob_type}.
@deftypefun void scm_set_smob_mark (long tc, SCM (*mark) (SCM))
This function sets the smob marking procedure for the smob type specified by
the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}.
@end deftypefun
-Instead of using @code{scm_make_smob_type} and calling each of the individual
-@code{scm_set_smob_XXXX} functions to register each special function
-independently, you can use @code{scm_make_smob_type_mfpe} to register all
-of the special functions at once as you create the smob type:
+Instead of using @code{scm_make_smob_type} and calling each of the
+individual @code{scm_set_smob_XXX} functions to register each special
+function independently, you can use @code{scm_make_smob_type_mfpe} to
+register all of the special functions at once as you create the smob
+type@footnote{Warning: There is an ongoing discussion among the developers which
+may result in deprecating @code{scm_make_smob_type_mfpe} in next release
+of Guile.}:
@deftypefun long scm_make_smob_type_mfpe(const char *name, scm_sizet size, SCM (*mark) (SCM), scm_sizet (*free) (SCM), int (*print) (SCM, SCM, scm_print_state*), SCM (*equalp) (SCM, SCM))
This function invokes @code{scm_make_smob_type} on its first two arguments
@end example
-@node Creating Instances, Typechecking, Describing a New Type, Defining New Types (Smobs)
+@node Creating Instances
@subsection Creating Instances
Like other non-immediate types, smobs start with a cell whose @sc{car}
@end example
-@node Typechecking, Garbage Collecting Smobs, Creating Instances, Defining New Types (Smobs)
+@node Typechecking
@subsection Typechecking
Functions that operate on smobs should aggressively check the types of
int area;
struct image *image;
- SCM_ASSERT ((SCM_NIMP (image_smob)
- && SCM_CAR (image_smob) == image_tag),
+ SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob),
image_smob, SCM_ARG1, "clear-image");
- image = (struct image *) SCM_CDR (image_smob);
+ image = (struct image *) SCM_SMOB_DATA (image_smob);
area = image->width * image->height;
memset (image->pixels, 0, area);
@c GJB:FIXME:: should talk about guile-snarf somewhere!
-@node Garbage Collecting Smobs, A Common Mistake In Allocating Smobs, Typechecking, Defining New Types (Smobs)
+@node Garbage Collecting Smobs
@subsection Garbage Collecting Smobs
Once a smob has been released to the tender mercies of the Scheme
the @code{mark} and @code{free} functions of the @code{scm_smobfuns}
structure to manage this.
-As described before (@pxref{Garbage Collection}), every object in the
+As described before (@pxref{Conservative GC}), every object in the
Scheme system has a @dfn{mark bit}, which the garbage collector uses to
tell live objects from dead ones. When collection starts, every
object's mark bit is clear. The collector traces pointers through the
mark_image (SCM image_smob)
@{
/* Mark the image's name and update function. */
- struct image *image = (struct image *) SCM_CDR (image_smob);
+ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
scm_gc_mark (image->name);
scm_gc_mark (image->update_func);
mark_image (SCM image_smob)
@{
/* Mark the image's name and update function. */
- struct image *image = (struct image *) SCM_CDR (image_smob);
+ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
scm_gc_mark (image->name);
return image->update_func;
scm_sizet
free_image (SCM image_smob)
@{
- struct image *image = (struct image *) SCM_CDR (image_smob);
+ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
scm_sizet size = image->width * image->height + sizeof (*image);
free (image->pixels);
@end deftypefun
-@node A Complete Example, , Garbage Collecting Simple Smobs, Defining New Types (Smobs)
+@node A Complete Example
@subsection A Complete Example
Here is the complete text of the implementation of the image datatype,
image->name = name;
image->update_func = SCM_BOOL_F;
- SCM_NEWCELL (image_smob);
- SCM_SETCDR (image_smob, image);
- SCM_SETCAR (image_smob, image_tag);
+ SCM_NEWSMOB (image_smob, image_tag, image);
return image_smob;
@}
int area;
struct image *image;
- SCM_ASSERT ((SCM_NIMP (image_smob)
- && SCM_CAR (image_smob) == image_tag),
+ SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob),
image_smob, SCM_ARG1, "clear-image");
- image = (struct image *) SCM_CDR (image_smob);
+ image = (struct image *) SCM_SMOB_DATA (image_smob);
area = image->width * image->height;
memset (image->pixels, 0, area);
static SCM
mark_image (SCM image_smob)
@{
- struct image *image = (struct image *) SCM_CDR (image_smob);
+ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
scm_gc_mark (image->name);
return image->update_func;
static scm_sizet
free_image (SCM image_smob)
@{
- struct image *image = (struct image *) SCM_CDR (image_smob);
+ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
scm_sizet size = image->width * image->height + sizeof (struct image);
free (image->pixels);
static int
print_image (SCM image_smob, SCM port, scm_print_state *pstate)
@{
- struct image *image = (struct image *) SCM_CDR (image_smob);
+ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob);
scm_puts ("#<image ", port);
scm_display (image->name, port);
guile>
@end example
-@bye
+@c essay @bye