* scheme-data.texi (Arithmetic): Documented the arithmetic
[bpt/guile.git] / doc / data-rep.texi
index cc0bb0a..9b7b879 100644 (file)
-\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
@@ -105,7 +130,7 @@ familiar with Guile's C interface.
                                         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,
@@ -142,7 +167,7 @@ does it}.
 * 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
@@ -186,7 +211,7 @@ semantics.  If @var{x} is an @code{SCM} value:
 @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
@@ -281,7 +306,7 @@ but this essay isn't about bit-twiddling.  (Hint: what if pointers had
 @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
@@ -379,7 +404,7 @@ are referencing, making a modified pointer as fast to use as an
 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
@@ -395,7 +420,7 @@ significant loss of efficiency, but the simplified system would still be
 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
@@ -407,14 +432,14 @@ everything one need know to use Guile's data.
 
 @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
@@ -445,8 +470,8 @@ boolean value have names starting with @code{SCM_N}.  For example,
 @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.
@@ -492,7 +517,7 @@ problem.  The alternative, an explicitly maintained list of local
 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
@@ -529,7 +554,7 @@ many pieces of code, it is enough for the collector to find the cell,
 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
@@ -570,7 +595,7 @@ from this weakness.
 @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
@@ -587,13 +612,13 @@ before applying them.
 
 
 @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
@@ -626,27 +651,27 @@ This function does not check for overflow.
 @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.
@@ -669,7 +694,7 @@ Scheme boolean, the result is undefined.
 @end deftypefn
 
 
-@node Unique Values,  , Booleans, Immediate Datatypes
+@node Unique Values
 @subsubsection Unique Values
 
 The immediate values that are neither small integers, characters, nor
@@ -714,7 +739,7 @@ symbol's value to see if it has a binding as a global variable.
 @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
@@ -737,18 +762,18 @@ corrupted.
 @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
@@ -766,7 +791,7 @@ SCM_NIMP (@var{x}) && SCM_CONSP (@var{x})
 @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
@@ -851,7 +876,7 @@ Return the @sc{car} of the @sc{car} of @var{cell}, the @sc{car} of the
 @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
@@ -898,7 +923,7 @@ There are also a few magic values stuffed into memory before a symbol's
 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
@@ -915,7 +940,7 @@ any sort.  Otherwise, return @code{SCM_BOOL_F}.
 @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]
@@ -964,7 +989,7 @@ connected with the interpreter's implementation.
 @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]
@@ -1015,13 +1040,13 @@ object instead of a subr object.
 @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
@@ -1076,13 +1101,8 @@ naming the function.  Usually, Guile catches these errors before ever
 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
@@ -1112,7 +1132,7 @@ datatypes described here.)
 * 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
@@ -1145,7 +1165,7 @@ Guile will apply this function to each instance of the new type to print
 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}.
 
@@ -1159,20 +1179,26 @@ never @code{equal?} unless they are @code{eq?}.
 
 @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
@@ -1194,10 +1220,13 @@ This function sets the smob equality-testing predicate for the smob type specifi
 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
@@ -1226,7 +1255,7 @@ init_image_type ()
 @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}
@@ -1339,7 +1368,7 @@ make_image (SCM name, SCM s_width, SCM s_height)
 @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
@@ -1361,11 +1390,10 @@ clear_image (SCM 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);
 
@@ -1393,7 +1421,7 @@ Collecting Smobs}.
 
 @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
@@ -1401,7 +1429,7 @@ system, it must be prepared to survive garbage collection.  Guile calls
 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
@@ -1444,7 +1472,7 @@ SCM
 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);
@@ -1470,7 +1498,7 @@ SCM
 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;
@@ -1497,7 +1525,7 @@ type:
 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);
@@ -1634,7 +1662,7 @@ other than the smob's header cell.
 @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,
@@ -1690,9 +1718,7 @@ make_image (SCM name, SCM s_width, SCM s_height)
   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;
 @}
@@ -1703,11 +1729,10 @@ clear_image (SCM 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);
 
@@ -1721,7 +1746,7 @@ clear_image (SCM image_smob)
 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;
@@ -1730,7 +1755,7 @@ mark_image (SCM image_smob)
 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);
@@ -1742,7 +1767,7 @@ free_image (SCM image_smob)
 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);
@@ -1790,4 +1815,4 @@ Type "(backtrace)" to get more information.
 guile> 
 @end example
 
-@bye
+@c essay @bye