Next: , Up: Defining New Types (Smobs)   [Contents][Index]

5.5.1 Describing a New Type

To define a new type, the programmer must write two functions to manage instances of the type:


Guile will apply this function to each instance of the new type to print the value, as for display or write. The default print function prints #<NAME ADDRESS> where NAME is the first argument passed to scm_make_smob_type.


If Scheme code asks the equal? function to compare two instances of the same smob type, Guile calls this function. It should return SCM_BOOL_T if a and b should be considered equal?, or SCM_BOOL_F otherwise. If equalp is NULL, equal? will assume that two instances of this type are never equal? unless they are eq?.

When the only resource associated with a smob is memory managed by the garbage collector—i.e., memory allocated with the scm_gc_malloc functions—this is sufficient. However, when a smob is associated with other kinds of resources, it may be necessary to define one of the following functions, or both:


Guile will apply this function to each instance of the new type it encounters during garbage collection. This function is responsible for telling the collector about any other SCM values that the object has stored, and that are in memory regions not already scanned by the garbage collector. See Garbage Collecting Smobs, for more details.


Guile will apply this function to each instance of the new type that is to be deallocated. The function should release all resources held by the object. This is analogous to the Java finalization method—it is invoked at an unspecified time (when garbage collection occurs) after the object is dead. See Garbage Collecting Smobs, for more details.

This function operates while the heap is in an inconsistent state and must therefore be careful. See Smobs, for details about what this function is allowed to do.

To actually register the new smob type, call scm_make_smob_type. It returns a value of type scm_t_bits which identifies the new smob type.

The four special functions described above are registered by calling one of scm_set_smob_mark, scm_set_smob_free, scm_set_smob_print, or scm_set_smob_equalp, as appropriate. Each function is intended to be used at most once per type, and the call should be placed immediately following the call to scm_make_smob_type.

There can only be at most 256 different smob types in the system. Instead of registering a huge number of smob types (for example, one for each relevant C struct in your application), it is sometimes better to register just one and implement a second layer of type dispatching on top of it. This second layer might use the 16 extra bits to extend its type, for example.

Here is how one might declare and register a new type representing eight-bit gray-scale images:

#include <libguile.h>

struct image {
  int width, height;
  char *pixels;

  /* The name of this image */
  SCM name;

  /* A function to call when this image is
     modified, e.g., to update the screen,
     or SCM_BOOL_F if no action necessary */
  SCM update_func;

static scm_t_bits image_tag;

init_image_type (void)
  image_tag = scm_make_smob_type ("image", sizeof (struct image));
  scm_set_smob_mark (image_tag, mark_image);
  scm_set_smob_free (image_tag, free_image);
  scm_set_smob_print (image_tag, print_image);

Next: , Up: Defining New Types (Smobs)   [Contents][Index]