From 370bababdadc9bc93ef4fef1125dcdeaa1842a87 Mon Sep 17 00:00:00 2001 From: Neil Jerram Date: Sat, 28 Apr 2001 23:38:52 +0000 Subject: [PATCH] * Consolidate authorship information in AUTHORS file. * Simplify THANKS file and add in recent contributors. * Add top level menu entry for Manual Conventions node. * Consolidate notes at beginning of guile.texi. --- doc/AUTHORS | 85 +- doc/ChangeLog | 13 + doc/Makefile.am | 6 +- doc/THANKS | 39 +- doc/goops.texi | 2794 -------------------------------------------- doc/guile-tut.texi | 1336 --------------------- doc/guile.texi | 117 +- 7 files changed, 130 insertions(+), 4260 deletions(-) rewrite doc/AUTHORS (99%) rewrite doc/THANKS (70%) rewrite doc/goops.texi (100%) rewrite doc/guile-tut.texi (100%) diff --git a/doc/AUTHORS b/doc/AUTHORS dissimilarity index 99% index b5fb6a66d..13fc1dede 100644 --- a/doc/AUTHORS +++ b/doc/AUTHORS @@ -1,12 +1,73 @@ -The Guile reference and tutorial manuals were written and edited -largely by Mark Galassi and Jim Blandy. Significant portions were -contributed by Gary Houston and Tim Pierce. - -Tom Lord contributed a great deal of material with early Guile -snapshots; although most of this text has been rewritten, all of it -was important, and much of the structure remains. - -Aubrey Jaffer wrote the SCM Scheme implementation and manual upon -which the Guile program and manual are based. Some portions of the -SCM and SLIB manuals have been included here verbatim. - +@c This file is in -*-texinfo-*- mode because it gets @included by +@c the top level Texinfo source files for each manual in this +@c distribution. We do this so as to avoid having to maintain +@c authorship information in more than one place. + +@ifset guile + +@c The Guile reference and tutorial manuals were written and edited +@c largely by Mark Galassi and Jim Blandy. + +@c Significant portions were contributed by Gary Houston (contributions +@c to posix system calls and networking, expect, I/O internals and +@c extensions, slib installation, error handling) and Tim Pierce +@c (sections on script interpreter triggers, alists, function tracing). + +@c Tom Lord contributed a great deal of material with early Guile +@c snapshots; although most of this text has been rewritten, all of it +@c was important, and much of the structure remains. + +@c Aubrey Jaffer wrote the SCM Scheme implementation and manual upon +@c which the Guile program and manual are based. Some portions of the +@c SCM and SLIB manuals have been included here verbatim. + +@c Since Guile 1.4, Neil Jerram has been maintaining and improving the +@c reference manual. Among other contributions, he wrote the Basic +@c Ideas chapter, developed the tools for keeping the manual in sync +@c with snarfed libguile docstrings, and reorganized the structure so as +@c to accommodate docstrings for all Guile's primitives. + +@author Mark Galassi +@author Cygnus Solution and Los Alamos National Laboratory +@author @email{rosalia@@cygnus.com} +@author +@author Jim Blandy +@author Free Software Foundation and MIT AI Lab +@author @email{jimb@@red-bean.com} +@author +@author Gary Houston +@author @email{ghouston@@arglist.com} +@author +@author Tim Pierce +@author @email{twp@@skepsis.com} +@author +@author Neil Jerram +@author @email{neil@@ossau.uklinux.net} + +@end ifset + +@ifset guile-tut + +@author Mark Galassi +@author Cygnus Solutions and Los Alamos National Laboratory +@author @email{rosalia@@nis.lanl.gov} + +@end ifset + +@ifset goops + +@c The GOOPS tutorial was written by Christian Lynbech and Mikael +@c Djurfeldt, who also wrote GOOPS itself. The GOOPS reference manual +@c and MOP documentation were written by Neil Jerram and reviewed by +@c Mikael Djurfeldt. + +@author Christian Lynbech +@author @email{chl@@tbit.dk} +@author +@author Mikael Djurfeldt +@author @email{djurfeldt@@nada.kth.se} +@author +@author Neil Jerram +@author @email{neil@@ossau.uklinux.net} + +@end ifset diff --git a/doc/ChangeLog b/doc/ChangeLog index a6aa319c7..b94443f5c 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,16 @@ +2001-04-29 Neil Jerram + + * guile.texi (Top): Add menu entry for Manual Conventions node. + +2001-04-28 Neil Jerram + + * THANKS: Move authorship bit into AUTHORS, simplify structure, + add Dirk Herrmann. + + * AUTHORS, guile.texi, guile-tut.texi, goops.texi, Makefile.am: + Consolidate authorship information in AUTHORS file, and @include + AUTHORS from the top level source file for each manual. + 2001-04-28 Thien-Thi Nguyen * preface.texi (Manual Conventions): New chapter. diff --git a/doc/Makefile.am b/doc/Makefile.am index a22dff8bf..9975477f7 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -35,9 +35,11 @@ guile_TEXINFOS = preface.texi intro.texi scheme-intro.texi \ scheme-reading.texi scheme-indices.texi slib.texi posix.texi \ expect.texi scsh.texi tcltk.texi scripts.texi gh.texi scm.texi \ appendices.texi indices.texi script-getopt.texi data-rep.texi \ - extend.texi srfi-13-14.texi + extend.texi srfi-13-14.texi AUTHORS -goops_TEXINFOS = goops-tutorial.texi hierarchy.eps hierarchy.txt +guile_tut_TEXINFOS = guile-tut.texi AUTHORS + +goops_TEXINFOS = goops-tutorial.texi hierarchy.eps hierarchy.txt AUTHORS # Optionally support building an HTML version of the reference manual. diff --git a/doc/THANKS b/doc/THANKS dissimilarity index 70% index 82a5d37ab..7db6082eb 100644 --- a/doc/THANKS +++ b/doc/THANKS @@ -1,21 +1,18 @@ -The Guile reference manual: -- Mark Galassi, for general stewardship -- Tim Pierce, for writing sections on script interpreter triggers, alists, - function tracing, and splitting the manual into its own module. -- Gary Houston, contributions to posix system calls and networking, - expect, I/O internals and extensions, slib installation, error handling. - -Proofreading, bug reports and bug fixes from: - Marcus Daniels - Lee Thomas - Joel Weber - Keith Wright - Chris Bitmead - Dale P. Smith - Masao Uebayashi - -New entries from: - Per Bothner - -Build patches from: - Steve Tell +Many thanks to the following people for contributing to the Guile +manuals! + +Proofreading, bug reports and patches from: + Chris Bitmead + Marcus Daniels + Dirk Herrmann + Dale P. Smith + Steve Tell + Lee Thomas + Masao Uebayashi + Joel Weber + Keith Wright + +New entries from: + Per Bothner + Martin Grabmueller +Thien Thi Nguyen diff --git a/doc/goops.texi b/doc/goops.texi dissimilarity index 100% index 981a7a77d..e69de29bb 100644 --- a/doc/goops.texi +++ b/doc/goops.texi @@ -1,2794 +0,0 @@ -\input texinfo -@c -*-texinfo-*- -@c %**start of header -@setfilename goops.info -@settitle Goops Manual -@setchapternewpage odd -@paragraphindent 0 -@c %**end of header - -@set VERSION 0.3 - -@dircategory The Algorithmic Language Scheme -@direntry -* GOOPS: (goops). The GOOPS reference manual. -@end direntry - -@macro goops -GOOPS -@end macro - -@macro guile -Guile -@end macro - -@ifinfo -This file documents GOOPS, an object oriented extension for Guile. - -Copyright (C) 1999, 2000, 2001 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. - -@end ifinfo - -@c This title page illustrates only one of the -@c two methods of forming a title page. - -@titlepage -@title Goops Manual -@subtitle For use with GOOPS @value{VERSION} -@author Christian Lynbech -@author @email{chl@@tbit.dk} -@author -@author Mikael Djurfeldt -@author @email{djurfeldt@@nada.kth.se} -@author -@author Neil Jerram -@author @email{neil@@ossau.uklinux.net} - -@c The following two commands -@c start the copyright page. -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 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. - -@end titlepage - -@node Top, Introduction, (dir), (dir) - -@menu -[When the manual is completed, this will be a flat index in the style of - the Emacs manual. More nodes will turn up under parts I-III.] - -Part I: Preliminaries - -* Introduction:: -* Getting Started:: - -Part II: Reference Manual - -* Reference Manual:: - -Part III: GOOPS Meta Object Protocol - -* MOP Specification:: - -The GOOPS tutorial - -* Tutorial:: - -* Index:: -* Concept Index:: -* Function and Variable Index:: -@end menu - -@iftex -@chapter Preliminaries -@end iftex - -@node Introduction, Getting Started, Top, Top -@section Introduction - -@goops{} is the object oriented extension to @guile{}. Its -implementation is derived from @w{STk-3.99.3} by Erick Gallesio and -version 1.3 of Gregor Kiczales @cite{Tiny-Clos}. It is very close in -spirit to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is -adapted for the Scheme language. While GOOPS is not compatible with any -of these systems, GOOPS contains a compatibility module which allows for -execution of STKlos programs. - -Briefly stated, the @goops{} extension gives the user a full object -oriented system with multiple inheritance and generic functions with -multi-method dispatch. Furthermore, the implementation relies on a true -meta object protocol, in the spirit of the one defined for CLOS -(@cite{Gregor Kiczales: A Metaobject Protocol}). - -@node Getting Started, Reference Manual, Introduction, Top -@section Getting Started - -@menu -* Running GOOPS:: - -Examples of some basic GOOPS functionality. - -* Methods:: -* User-defined types:: -* Asking for the type of an object:: - -See further in the GOOPS tutorial available in this distribution in -info (goops.info) and texinfo format. -@end menu - -@node Running GOOPS, Methods, Getting Started, Getting Started -@subsection Running GOOPS - -@enumerate -@item -Type - -@smalllisp -guile-oops -@end smalllisp - -You should now be at the Guile prompt ("guile> "). - -@item -Type - -@smalllisp -(use-modules (oop goops)) -@end smalllisp - -to load GOOPS. (If your system supports dynamic loading, you -should be able to do this not only from `guile-oops' but from an -arbitrary Guile interpreter.) -@end enumerate - -We're now ready to try some basic GOOPS functionality. - -@node Methods, User-defined types, Running GOOPS, Getting Started -@subsection Methods - -@smalllisp -@group -(define-method (+ (x ) (y )) - (string-append x y)) - -(+ 1 2) --> 3 -(+ "abc" "de") --> "abcde" -@end group -@end smalllisp - -@node User-defined types, Asking for the type of an object, Methods, Getting Started -@subsection User-defined types - -@smalllisp -(define-class <2D-vector> () - (x #:init-value 0 #:accessor x-component #:init-keyword #:x) - (y #:init-value 0 #:accessor y-component #:init-keyword #:y)) - -@group -(use-modules (ice-9 format)) - -(define-method (write (obj <2D-vector>) port) - (display (format #f "<~S, ~S>" (x-component obj) (y-component obj)) - port)) - -(define v (make <2D-vector> #:x 3 #:y 4)) - -v --> <3, 4> -@end group - -@group -(define-method (+ (x <2D-vector>) (y <2D-vector>)) - (make <2D-vector> - #:x (+ (x-component x) (x-component y)) - #:y (+ (y-component x) (y-component y)))) - -(+ v v) --> <6, 8> -@end group -@end smalllisp - -@node Asking for the type of an object, , User-defined types, Getting Started -@subsection Types - -@example -(class-of v) --> #< <2D-vector> 40241ac0> -<2D-vector> --> #< <2D-vector> 40241ac0> -(class-of 1) --> #< 401b2a98> - --> #< 401b2a98> - -(is-a? v <2D-vector>) --> #t -@end example - -@node Reference Manual, MOP Specification, Getting Started, Top -@chapter Reference Manual - -This chapter is the GOOPS reference manual. It aims to describe all the -syntax, procedures, options and associated concepts that a typical -application author would need to understand in order to use GOOPS -effectively in their application. It also describes what is meant by -the GOOPS ``metaobject protocol'' (aka ``MOP''), and indicates how -authors can use the metaobject protocol to customize the behaviour of -GOOPS itself. - -For a detailed specification of the GOOPS metaobject protocol, see -@ref{MOP Specification}. - -@menu -* Introductory Remarks:: -* Defining New Classes:: -* Creating Instances:: -* Accessing Slots:: -* Creating Generic Functions:: -* Adding Methods to Generic Functions:: -* Invoking Generic Functions:: -* Redefining a Class:: -* Changing the Class of an Instance:: -* Introspection:: -* Miscellaneous Functions:: -@end menu - -@node Introductory Remarks -@section Introductory Remarks - -GOOPS is an object-oriented programming system based on a ``metaobject -protocol'' derived from the ones used in CLOS (the Common Lisp Object -System), tiny-clos (a small Scheme implementation of a subset of CLOS -functionality) and STKlos. - -GOOPS can be used by application authors at a basic level without any -need to understand what the metaobject protocol (aka ``MOP'') is and how -it works. On the other hand, the MOP underlies even the customizations -that application authors are likely to make use of very quickly --- such -as defining an @code{initialize} method to customize the initialization -of instances of an application-defined class --- and an understanding of -the MOP makes it much easier to explain such customizations in a precise -way. And in the long run, understanding the MOP is the key both to -understanding GOOPS at a deeper level and to taking full advantage of -GOOPS' power, by customizing the behaviour of GOOPS itself. - -Each of the following sections of the reference manual is arranged -such that the most basic usage is introduced first, and then subsequent -subsections discuss the related internal functions and metaobject -protocols, finishing with a description of how to customize that area of -functionality. - -These introductory remarks continue with a few words about metaobjects -and the MOP. Readers who do not want to be bothered yet with the MOP -and customization could safely skip this subsection on a first reading, -and should correspondingly skip subsequent subsections that are -concerned with internals and customization. - -In general, this reference manual assumes familiarity with standard -object oriented concepts and terminology. However, some of the terms -used in GOOPS is less well known, so the Terminology subsection -provides definitions for these terms. - -@menu -* Metaobjects and the Metaobject Protocol:: -* Terminology:: -@end menu - -@node Metaobjects and the Metaobject Protocol -@subsection Metaobjects and the Metaobject Protocol - -The conceptual building blocks of GOOPS are classes, slot definitions, -instances, generic functions and methods. A class is a grouping of -inheritance relations and slot definitions. An instance is an object -with slots that are allocated following the rules implied by its class's -superclasses and slot definitions. A generic function is a collection -of methods and rules for determining which of those methods to apply -when the generic function is invoked. A method is a procedure and a set -of specializers that specify the type of arguments to which the -procedure is applicable. - -Of these entities, GOOPS represents classes, generic functions and -methods as ``metaobjects''. In other words, the values in a GOOPS -program that describe classes, generic functions and methods, are -themselves instances (or ``objects'') of special GOOPS classes that -encapsulate the behaviour, respectively, of classes, generic functions, -and methods. - -(The other two entities are slot definitions and instances. Slot -definitions are not strictly instances, but every slot definition is -associated with a GOOPS class that specifies the behaviour of the slot -as regards accessibility and protection from garbage collection. -Instances are of course objects in the usual sense, and there is no -benefit from thinking of them as metaobjects.) - -The ``metaobject protocol'' (aka ``MOP'') is the specification of the -generic functions which determine the behaviour of these metaobjects and -the circumstances in which these generic functions are invoked. - -For a concrete example of what this means, consider how GOOPS calculates -the set of slots for a class that is being defined using -@code{define-class}. The desired set of slots is the union of the new -class's direct slots and the slots of all its superclasses. But -@code{define-class} itself does not perform this calculation. Instead, -there is a method of the @code{initialize} generic function that is -specialized for instances of type @code{}, and it is this method -that performs the slot calculation. - -@code{initialize} is a generic function which GOOPS calls whenever a new -instance is created, immediately after allocating memory for a new -instance, in order to initialize the new instance's slots. The sequence -of steps is as follows. - -@itemize @bullet -@item -@code{define-class} uses @code{make} to make a new instance of the -@code{}, passing as initialization arguments the superclasses, -slot definitions and class options that were specified in the -@code{define-class} form. - -@item -@code{make} allocates memory for the new instance, and then invokes the -@code{initialize} generic function to initialize the new instance's -slots. - -@item -The @code{initialize} generic function applies the method that is -specialized for instances of type @code{}, and this method -performs the slot calculation. -@end itemize - -In other words, rather than being hardcoded in @code{define-class}, the -behaviour of class definition is encapsulated by generic function -methods that are specialized for the class @code{}. - -It is possible to create a new class that inherits from @code{}, -which is called a ``metaclass'', and to write a new @code{initialize} -method that is specialized for instances of the new metaclass. Then, if -the @code{define-class} form includes a @code{#:metaclass} class option -whose value is the new metaclass, the class that is defined by the -@code{define-class} form will be an instance of the new metaclass rather -than of the default @code{}, and will be defined in accordance -with the new @code{initialize} method. Thus the default slot -calculation, as well as any other aspect of the new class's relationship -with its superclasses, can be modified or overridden. - -In a similar way, the behaviour of generic functions can be modified or -overridden by creating a new class that inherits from the standard -generic function class @code{}, writing appropriate methods -that are specialized to the new class, and creating new generic -functions that are instances of the new class. - -The same is true for method metaobjects. And the same basic mechanism -allows the application class author to write an @code{initialize} method -that is specialized to their application class, to initialize instances -of that class. - -Such is the power of the MOP. Note that @code{initialize} is just one -of a large number of generic functions that can be customized to modify -the behaviour of application objects and classes and of GOOPS itself. -Each subsequent section of the reference manual covers a particular area -of GOOPS functionality, and describes the generic functions that are -relevant for customization of that area. - -We conclude this subsection by emphasizing a point that may seem -obvious, but contrasts with the corresponding situation in some other -MOP implementations, such as CLOS. The point is simply that an -identifier which represents a GOOPS class or generic function is a -variable with a first-class value, the value being an instance of class -@code{} or @code{}. (In CLOS, on the other hand, a -class identifier is a symbol that indexes the corresponding class -metaobject in a separate namespace for classes.) This is, of course, -simply an extension of the tendency in Scheme to avoid the unnecessary -use of, on the one hand, syntactic forms that require unevaluated -arguments and, on the other, separate identifier namespaces (e.g. for -class names), but it is worth noting that GOOPS conforms fully to this -Schemely principle. - -@node Terminology -@subsection Terminology - -It is assumed that the reader is already familiar with standard object -orientation concepts such as classes, objects/instances, -inheritance/subclassing, generic functions and methods, encapsulation -and polymorphism. - -This section explains some of the less well known concepts and -terminology that GOOPS uses, which are assumed by the following sections -of the reference manual. - -@menu -* Metaclass:: -* Class Precedence List:: -* Accessor:: -@end menu - -@node Metaclass -@subsubsection Metaclass - -A @dfn{metaclass} is the class of an object which represents a GOOPS -class. Put more succinctly, a metaclass is a class's class. - -Most GOOPS classes have the metaclass @code{} and, by default, -any new class that is created using @code{define-class} has the -metaclass @code{}. - -But what does this really mean? To find out, let's look in more detail -at what happens when a new class is created using @code{define-class}: - -@example -(define-class () . slots) -@end example - -GOOPS actually expands the @code{define-class} form to something like -this - -@example -(define (class () . slots)) -@end example - -and thence to - -@example -(define - (make #:supers (list ) #:slots slots)) -@end example - -In other words, the value of @code{} is in fact an instance of -the class @code{} with slot values specifying the superclasses -and slot definitions for the class @code{}. (@code{#:supers} -and @code{#:slots} are initialization keywords for the @code{dsupers} -and @code{dslots} slots of the @code{} class.) - -In order to take advantage of the full power of the GOOPS metaobject -protocol (@pxref{MOP Specification}), it is sometimes desirable to -create a new class with a metaclass other than the default -@code{}. This is done by writing: - -@example -(define-class () - slot @dots{} - #:metaclass ) -@end example - -GOOPS expands this to something like: - -@example -(define - (make #:supers (list ) #:slots slots)) -@end example - -In this case, the value of @code{} is an instance of the more -specialized class @code{}. Note that -@code{} itself must previously have been defined as a -subclass of @code{}. For a full discussion of when and how it is -useful to define new metaclasses, see @ref{MOP Specification}. - -Now let's make an instance of @code{}: - -@example -(define my-object (make ...)) -@end example - -All of the following statements are correct expressions of the -relationships between @code{my-object}, @code{}, -@code{} and @code{}. - -@itemize @bullet -@item -@code{my-object} is an instance of the class @code{}. - -@item -@code{} is an instance of the class @code{}. - -@item -@code{} is an instance of the class @code{}. - -@item -The class of @code{my-object} is @code{}. - -@item -The metaclass of @code{my-object} is @code{}. - -@item -The class of @code{} is @code{}. - -@item -The metaclass of @code{} is @code{}. - -@item -The class of @code{} is @code{}. - -@item -The metaclass of @code{} is @code{}. - -@item -@code{} is not a metaclass, since it is does not inherit from -@code{}. - -@item -@code{} is a metaclass, since it inherits from -@code{}. -@end itemize - -@node Class Precedence List -@subsubsection Class Precedence List - -The @dfn{class precedence list} of a class is the list of all direct and -indirect superclasses of that class, including the class itself. - -In the absence of multiple inheritance, the class precedence list is -ordered straightforwardly, beginning with the class itself and ending -with @code{}. - -For example, given this inheritance hierarchy: - -@example -(define-class () @dots{}) -(define-class () @dots{}) -(define-class () @dots{}) -@end example - -the class precedence list of would be - -@example -( ) -@end example - -With multiple inheritance, the algorithm is a little more complicated. -A full description is provided by the GOOPS Tutorial: see @ref{Class -precedence list}. - -``Class precedence list'' is often abbreviated, in documentation and -Scheme variable names, to @dfn{cpl}. - -@node Accessor -@subsubsection Accessor - -An @dfn{accessor} is a generic function with both reference and setter -methods. - -@example -(define-accessor perimeter) -@end example - -Reference methods for an accessor are defined in the same way as generic -function methods. - -@example -(define-method (perimeter (s )) - (* 4 (side-length s))) -@end example - -Setter methods for an accessor are defined by specifying ``(setter -)'' as the first parameter of the @code{define-method} -call. - -@example -(define-method ((setter perimeter) (s ) (n )) - (set! (side-length s) (/ n 4))) -@end example - -Once an appropriate setter method has been defined in this way, it can -be invoked using the generalized @code{set!} syntax, as in: - -@example -(set! (perimeter s1) 18.3) -@end example - -@node Defining New Classes -@section Defining New Classes - -[ *fixme* Somewhere in this manual there needs to be an introductory -discussion about GOOPS classes, generic functions and methods, covering - -@itemize @bullet -@item -how classes encapsulate related items of data in @dfn{slots} - -@item -why it is that, unlike in C++ and Java, a class does not encapsulate the -methods that act upon the class (at least not in the C++/Java sense) - -@item -how generic functions provide a more general solution that provides for -dispatch on all argument types, and avoids idiosyncracies like C++'s -friend classes - -@item -how encapsulation in the sense of data- and code-hiding, or of -distinguishing interface from implementation, is treated in Guile as an -orthogonal concept to object orientation, and is the responsibility of -the module system. -@end itemize - -Some of this is covered in the Tutorial chapter, in @ref{Generic -functions and methods} - perhaps the best solution would be to expand -the discussion there. ] - -@menu -* Basic Class Definition:: -* Class Options:: -* Slot Options:: -* Class Definition Internals:: -* Customizing Class Definition:: -* STKlos Compatibility:: -@end menu - -@node Basic Class Definition -@subsection Basic Class Definition - -New classes are defined using the @code{define-class} syntax, with -arguments that specify the classes that the new class should inherit -from, the direct slots of the new class, and any required class options. - -@deffn syntax define-class name (super @dots{}) slot-definition @dots{} . options -Define a class called @var{name} that inherits from @var{super}s, with -direct slots defined by @var{slot-definition}s and class options -@var{options}. The newly created class is bound to the variable name -@var{name} in the current environment. - -Each @var{slot-definition} is either a symbol that names the slot or a -list, - -@example -(@var{slot-name-symbol} . @var{slot-options}) -@end example - -where @var{slot-name-symbol} is a symbol and @var{slot-options} is a -list with an even number of elements. The even-numbered elements of -@var{slot-options} (counting from zero) are slot option keywords; the -odd-numbered elements are the corresponding values for those keywords. - -@var{options} is a similarly structured list containing class option -keywords and corresponding values. -@end deffn - -The standard GOOPS class and slot options are described in the following -subsections: see @ref{Class Options} and @ref{Slot Options}. - -Example 1. Define a class that combines two pre-existing classes by -inheritance but adds no new slots. - -@example -(define-class ( )) -@end example - -Example 2. Define a @code{regular-polygon} class with slots for side -length and number of sides that have default values and can be accessed -via the generic functions @code{side-length} and @code{num-sides}. - -@example -(define-class () - (sl #:init-value 1 #:accessor side-length) - (ns #:init-value 5 #:accessor num-sides)) -@end example - -Example 3. Define a class whose behavior (and that of its instances) is -customized via an application-defined metaclass. - -@example -(define-class () - (s #:init-value #f #:accessor state) - ... - #:metaclass ) -@end example - -@node Class Options -@subsection Class Options - -@deffn {class option} #:metaclass metaclass -The @code{#:metaclass} class option specifies the metaclass of the class -being defined. @var{metaclass} must be a class that inherits from -@code{}. For an introduction to the use of metaclasses, see -@ref{Metaobjects and the Metaobject Protocol} and @ref{Metaclass}. - -If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a -metaclass for the new class by calling @code{ensure-metaclass} -(@pxref{Class Definition Internals,, ensure-metaclass}). -@end deffn - -@deffn {class option} #:name name -The @code{#:name} class option specifies the new class's name. This -name is used to identify the class whenever related objects - the class -itself, its instances and its subclasses - are printed. - -If the @code{#:name} option is absent, GOOPS uses the first argument to -@code{define-class} as the class name. -@end deffn - -@deffn {class option} #:environment environment -*fixme* Not sure about this one, but I think that the -@code{#:environment} option specifies the environment in which the -class's getters and setters are computed and evaluated. - -If the @code{#:environment} option is not specified, the class's -environment defaults to the top-level environment in which the -@code{define-class} form appears. -@end deffn - -@node Slot Options -@subsection Slot Options - -@deffn {slot option} #:allocation allocation -The @code{#:allocation} option tells GOOPS how to allocate storage for -the slot. Possible values for @var{allocation} are - -@itemize @bullet -@item @code{#:instance} - -Indicates that GOOPS should create separate storage for this slot in -each new instance of the containing class (and its subclasses). - -@item @code{#:class} - -Indicates that GOOPS should create storage for this slot that is shared -by all instances of the containing class (and its subclasses). In other -words, a slot in class @var{C} with allocation @code{#:class} is shared -by all @var{instance}s for which @code{(is-a? @var{instance} @var{c})}. - -@item @code{#:each-subclass} - -Indicates that GOOPS should create storage for this slot that is shared -by all @emph{direct} instances of the containing class, and that -whenever a subclass of the containing class is defined, GOOPS should -create a new storage for the slot that is shared by all @emph{direct} -instances of the subclass. In other words, a slot with allocation -@code{#:each-subclass} is shared by all instances with the same -@code{class-of}. - -@item @code{#:virtual} - -Indicates that GOOPS should not allocate storage for this slot. The -slot definition must also include the @code{#:slot-ref} and -@code{#:slot-set!} options to specify how to reference and set the value -for this slot. -@end itemize - -The default value is @code{#:instance}. - -Slot allocation options are processed when defining a new class by the -generic function @code{compute-get-n-set}, which is specialized by the -class's metaclass. Hence new types of slot allocation can be -implemented by defining a new metaclass and a method for -@code{compute-get-n-set} that is specialized for the new metaclass. For -an example of how to do this, see @ref{Customizing Class Definition}. -@end deffn - -@deffn {slot option} #:slot-ref getter -@deffnx {slot option} #:slot-set! setter -The @code{#:slot-ref} and @code{#:slot-set!} options must be specified -if the slot allocation is @code{#:virtual}, and are ignored otherwise. - -@var{getter} should be a closure taking a single @var{instance} parameter -that returns the current slot value. @var{setter} should be a closure -taking two parameters - @var{instance} and @var{new-val} - that sets the -slot value to @var{new-val}. -@end deffn - -@deffn {slot option} #:getter getter -@deffnx {slot option} #:setter setter -@deffnx {slot option} #:accessor accessor -These options, if present, tell GOOPS to create generic function and -method definitions that can be used to get and set the slot value more -conveniently than by using @code{slot-ref} and @code{slot-set!}. - -@var{getter} specifies a generic function to which GOOPS will add a -method for getting the slot value. @var{setter} specifies a generic -function to which GOOPS will add a method for setting the slot value. -@var{accessor} specifies an accessor to which GOOPS will add methods for -both getting and setting the slot value. - -So if a class includes a slot definition like this: - -@example -(c #:getter get-count #:setter set-count #:accessor count) -@end example - -GOOPS defines generic function methods such that the slot value can be -referenced using either the getter or the accessor - - -@example -(let ((current-count (get-count obj))) @dots{}) -(let ((current-count (count obj))) @dots{}) -@end example - -- and set using either the setter or the accessor - - -@example -(set-count obj (+ 1 current-count)) -(set! (count obj) (+ 1 current-count)) -@end example - -Note that - -@itemize @bullet -@item -with an accessor, the slot value is set using the generalized -@code{set!} syntax - -@item -in practice, it is unusual for a slot to use all three of these options: -read-only, write-only and read-write slots would typically use only -@code{#:getter}, @code{#:setter} and @code{#:accessor} options -respectively. -@end itemize - -If the specified names are already bound in the top-level environment to -values that cannot be upgraded to generic functions, those values are -overwritten during evaluation of the @code{define-class} that contains -the slot definition. For details, see @ref{Generic Function Internals,, -ensure-generic}. -@end deffn - -@deffn {slot option} #:init-value init-value -@deffnx {slot option} #:init-form init-form -@deffnx {slot option} #:init-thunk init-thunk -@deffnx {slot option} #:init-keyword init-keyword -These options provide various ways to specify how to initialize the -slot's value at instance creation time. @var{init-value} is a fixed -value. @var{init-thunk} is a procedure of no arguments that is called -when a new instance is created and should return the desired initial -slot value. @var{init-form} is an unevaluated expression that gets -evaluated when a new instance is created and should return the desired -initial slot value. @var{init-keyword} is a keyword that can be used to -pass an initial slot value to @code{make} when creating a new instance. - -If more than one of these options is specified for the same slot, the -order of precedence, highest first is - -@itemize @bullet -@item -@code{#:init-keyword}, if @var{init-keyword} is present in the options -passed to @code{make} - -@item -@code{#:init-thunk}, @code{#:init-form} or @code{#:init-value}. -@end itemize - -If the slot definition contains more than one initialization option of -the same precedence, the later ones are ignored. If a slot is not -initialized at all, its value is unbound. - -In general, slots that are shared between more than one instance are -only initialized at new instance creation time if the slot value is -unbound at that time. However, if the new instance creation specifies -a valid init keyword and value for a shared slot, the slot is -re-initialized regardless of its previous value. - -Note, however, that the power of GOOPS' metaobject protocol means that -everything written here may be customized or overridden for particular -classes! The slot initializations described here are performed by the least -specialized method of the generic function @code{initialize}, whose -signature is - -@example -(define-method (initialize (object ) initargs) ...) -@end example - -The initialization of instances of any given class can be customized by -defining a @code{initialize} method that is specialized for that class, -and the author of the specialized method may decide to call -@code{next-method} - which will result in a call to the next less -specialized @code{initialize} method - at any point within the -specialized code, or maybe not at all. In general, therefore, the -initialization mechanisms described here may be modified or overridden by -more specialized code, or may not be supported at all for particular -classes. -@end deffn - -@node Class Definition Internals -@subsection Class Definition Internals - -Implementation notes: @code{define-class} expands to an expression which - -@itemize @bullet -@item -checks that it is being evaluated only at top level - -@item -defines any accessors that are implied by the @var{slot-definition}s - -@item -uses @code{class} to create the new class (@pxref{Class Definition -Internals,, class}) - -@item -checks for a previous class definition for @var{name} and, if found, -handles the redefinition by invoking @code{class-redefinition} -(@pxref{Redefining a Class}). -@end itemize - -@deffn syntax class name (super @dots{}) slot-definition @dots{} . options -Return a newly created class that inherits from @var{super}s, with -direct slots defined by @var{slot-definition}s and class options -@var{options}. For the format of @var{slot-definition}s and -@var{options}, see @ref{Basic Class Definition,, define-class}. -@end deffn - -Implementation notes: @code{class} expands to an expression which - -@itemize @bullet -@item -processes the class and slot definition options to check that they are -well-formed, to convert the @code{#:init-form} option to an -@code{#:init-thunk} option, to supply a default environment parameter -(the current top-level environment) and to evaluate all the bits that -need to be evaluated - -@item -calls @code{make-class} to create the class with the processed and -evaluated parameters. -@end itemize - -@deffn procedure make-class supers slots . options -Return a newly created class that inherits from @var{supers}, with -direct slots defined by @var{slots} and class options @var{options}. -For the format of @var{slots} and @var{options}, see @ref{Basic Class -Definition,, define-class}, except note that for @code{make-class}, -@var{slots} and @var{options} are separate list parameters: @var{slots} -here is a list of slot definitions. -@end deffn - -Implementation notes: @code{make-class} - -@itemize @bullet -@item -adds @code{} to the @var{supers} list if @var{supers} is empty -or if none of the classes in @var{supers} have @code{} in their -class precedence list - -@item -defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass} -options, if they are not specified by @var{options}, to the current -top-level environment, the unbound value, and @code{(ensure-metaclass -@var{supers})} respectively (@pxref{Class Definition Internals,, -ensure-metaclass}) - -@item -checks for duplicate classes in @var{supers} and duplicate slot names in -@var{slots}, and signals an error if there are any duplicates - -@item -calls @code{make}, passing the metaclass as the first parameter and all -other parameters as option keywords with values. -@end itemize - -@deffn procedure ensure-metaclass supers env -Return a metaclass suitable for a class that inherits from the list of -classes in @var{supers}. The returned metaclass is the union by -inheritance of the metaclasses of the classes in @var{supers}. - -In the simplest case, where all the @var{supers} are straightforward -classes with metaclass @code{}, the returned metaclass is just -@code{}. - -For a more complex example, suppose that @var{supers} contained one -class with metaclass @code{} and one with metaclass -@code{}. Then the returned metaclass would be a -class that inherits from both @code{} and -@code{}. - -If @var{supers} is the empty list, @code{ensure-metaclass} returns the -default GOOPS metaclass @code{}. - -GOOPS keeps a list of the metaclasses created by -@code{ensure-metaclass}, so that each required type of metaclass only -has to be created once. - -The @code{env} parameter is ignored. -@end deffn - -@deffn procedure ensure-metaclass-with-supers meta-supers -@code{ensure-metaclass-with-supers} is an internal procedure used by -@code{ensure-metaclass} (@pxref{Class Definition Internals,, -ensure-metaclass}). It returns a metaclass that is the union by -inheritance of the metaclasses in @var{meta-supers}. -@end deffn - -The internals of @code{make}, which is ultimately used to create the new -class object, are described in @ref{Customizing Instance Creation}, -which covers the creation and initialization of instances in general. - -@node Customizing Class Definition -@subsection Customizing Class Definition - -During the initialization of a new class, GOOPS calls a number of generic -functions with the newly allocated class instance as the first -argument. Specifically, GOOPS calls the generic function - -@itemize @bullet -@item -(initialize @var{class} @dots{}) -@end itemize - -where @var{class} is the newly allocated class instance, and the default -@code{initialize} method for arguments of type @code{} calls the -generic functions - -@itemize @bullet -@item -(compute-cpl @var{class}) - -@item -(compute-slots @var{class}) - -@item -(compute-get-n-set @var{class} @var{slot-def}), for each of the slot -definitions returned by @code{compute-slots} - -@item -(compute-getter-method @var{class} @var{slot-def}), for each of the -slot definitions returned by @code{compute-slots} that includes a -@code{#:getter} or @code{#:accessor} slot option - -@item -(compute-setter-method @var{class} @var{slot-def}), for each of the -slot definitions returned by @code{compute-slots} that includes a -@code{#:setter} or @code{#:accessor} slot option. -@end itemize - -If the metaclass of the new class is something more specialized than the -default @code{}, then the type of @var{class} in the calls above -is more specialized than @code{}, and hence it becomes possible -to define generic function methods, specialized for the new class's -metaclass, that can modify or override the default behaviour of -@code{initialize}, @code{compute-cpl} or @code{compute-get-n-set}. - -@code{compute-cpl} computes the class precedence list (``CPL'') for the -new class (@pxref{Class precedence list}), and returns it as a list of -class objects. The CPL is important because it defines a superclass -ordering that is used, when a generic function is invoked upon an -instance of the class, to decide which of the available generic function -methods is the most specific. Hence @code{compute-cpl} could be -customized in order to modify the CPL ordering algorithm for all classes -with a special metaclass. - -The default CPL algorithm is encapsulated by the @code{compute-std-cpl} -procedure, which is in turn called by the default @code{compute-cpl} -method. - -@deffn procedure compute-std-cpl class -Compute and return the class precedence list for @var{class} according -to the algorithm described in @ref{Class precedence list}. -@end deffn - -@code{compute-slots} computes and returns a list of all slot definitions -for the new class. By default, this list includes the direct slot -definitions from the @code{define-class} form, plus the slot definitions -that are inherited from the new class's superclasses. The default -@code{compute-slots} method uses the CPL computed by @code{compute-cpl} -to calculate this union of slot definitions, with the rule that slots -inherited from superclasses are shadowed by direct slots with the same -name. One possible reason for customizing @code{compute-slots} would be -to implement an alternative resolution strategy for slot name conflicts. - -@code{compute-get-n-set} computes the low-level closures that will be -used to get and set the value of a particular slot, and returns them in -a list with two elements. - -The closures returned depend on how storage for that slot is allocated. -The standard @code{compute-get-n-set} method, specialized for classes of -type @code{}, handles the standard GOOPS values for the -@code{#:allocation} slot option (@pxref{Slot Options,, allocation}). By -defining a new @code{compute-get-n-set} method for a more specialized -metaclass, it is possible to support new types of slot allocation. - -Suppose you wanted to create a large number of instances of some class -with a slot that should be shared between some but not all instances of -that class - say every 10 instances should share the same slot storage. -The following example shows how to implement and use a new type of slot -allocation to do this. - -@example -(define-class ()) - -(let ((batch-allocation-count 0) - (batch-get-n-set #f)) - (define-method (compute-get-n-set (class ) s) - (case (slot-definition-allocation s) - ((#:batched) - ;; If we've already used the same slot storage for 10 instances, - ;; reset variables. - (if (= batch-allocation-count 10) - (begin - (set! batch-allocation-count 0) - (set! batch-get-n-set #f))) - ;; If we don't have a current pair of get and set closures, - ;; create one. make-closure-variable returns a pair of closures - ;; around a single Scheme variable - see goops.scm for details. - (or batch-get-n-set - (set! batch-get-n-set (make-closure-variable))) - ;; Increment the batch allocation count. - (set! batch-allocation-count (+ batch-allocation-count 1)) - batch-get-n-set) - - ;; Call next-method to handle standard allocation types. - (else (next-method))))) - -(define-class () - ... - (c #:allocation #:batched) - ... - #:metaclass ) -@end example - -The usage of @code{compute-getter-method} and @code{compute-setter-method} -is described in @ref{MOP Specification}. - -@code{compute-cpl} and @code{compute-get-n-set} are called by the -standard @code{initialize} method for classes whose metaclass is -@code{}. But @code{initialize} itself can also be modified, by -defining an @code{initialize} method specialized to the new class's -metaclass. Such a method could complete override the standard -behaviour, by not calling @code{(next-method)} at all, but more -typically it would perform additional class initialization steps before -and/or after calling @code{(next-method)} for the standard behaviour. - -@node STKlos Compatibility -@subsection STKlos Compatibility - -If the STKlos compatibility module is loaded, @code{define-class} is -overwritten by a STKlos-specific definition; the standard GOOPS -definition of @code{define-class} remains available in -@code{standard-define-class}. - -@deffn syntax standard-define-class name (super @dots{}) slot-definition @dots{} . options -@code{standard-define-class} is equivalent to the standard GOOPS -@code{define-class}. -@end deffn - -@node Creating Instances -@section Creating Instances - -@menu -* Basic Instance Creation:: -* Customizing Instance Creation:: -@end menu - -@node Basic Instance Creation -@subsection Basic Instance Creation - -To create a new instance of any GOOPS class, use the generic function -@code{make} or @code{make-instance}, passing the required class and any -appropriate instance initialization arguments as keyword and value -pairs. Note that @code{make} and @code{make-instances} are aliases for -each other - their behaviour is identical. - -@deffn generic make -@deffnx method make (class ) . initargs -Create and return a new instance of class @var{class}, initialized using -@var{initargs}. - -In theory, @var{initargs} can have any structure that is understood by -whatever methods get applied when the @code{initialize} generic function -is applied to the newly allocated instance. - -In practice, specialized @code{initialize} methods would normally call -@code{(next-method)}, and so eventually the standard GOOPS -@code{initialize} methods are applied. These methods expect -@var{initargs} to be a list with an even number of elements, where -even-numbered elements (counting from zero) are keywords and -odd-numbered elements are the corresponding values. - -GOOPS processes initialization argument keywords automatically for slots -whose definition includes the @code{#:init-keyword} option (@pxref{Slot -Options,, init-keyword}). Other keyword value pairs can only be -processed by an @code{initialize} method that is specialized for the new -instance's class. Any unprocessed keyword value pairs are ignored. -@end deffn - -@deffn generic make-instance -@deffnx method make-instance (class ) . initargs -@code{make-instance} is an alias for @code{make}. -@end deffn - -@node Customizing Instance Creation -@subsection Customizing Instance Creation - -@code{make} itself is a generic function. Hence the @code{make} -invocation itself can be customized in the case where the new instance's -metaclass is more specialized than the default @code{}, by -defining a @code{make} method that is specialized to that metaclass. - -Normally, however, the method for classes with metaclass @code{} -will be applied. This method calls two generic functions: - -@itemize @bullet -@item -(allocate-instance @var{class} . @var{initargs}) - -@item -(initialize @var{instance} . @var{initargs}) -@end itemize - -@code{allocate-instance} allocates storage for and returns the new -instance, uninitialized. You might customize @code{allocate-instance}, -for example, if you wanted to provide a GOOPS wrapper around some other -object programming system. - -To do this, you would create a specialized metaclass, which would act as -the metaclass for all classes and instances from the other system. Then -define an @code{allocate-instance} method, specialized to that -metaclass, which calls a Guile primitive C function, which in turn -allocates the new instance using the interface of the other object -system. - -In this case, for a complete system, you would also need to customize a -number of other generic functions like @code{make} and -@code{initialize}, so that GOOPS knows how to make classes from the -other system, access instance slots, and so on. - -@code{initialize} initializes the instance that is returned by -@code{allocate-instance}. The standard GOOPS methods perform -initializations appropriate to the instance class. - -@itemize @bullet -@item -At the least specialized level, the method for instances of type -@code{} performs internal GOOPS instance initialization, and -initializes the instance's slots according to the slot definitions and -any slot initialization keywords that appear in @var{initargs}. - -@item -The method for instances of type @code{} calls -@code{(next-method)}, then performs the class initializations described -in @ref{Customizing Class Definition}. - -@item -and so on for generic functions, method, operator classes @dots{} -@end itemize - -Similarly, you can customize the initialization of instances of any -application-defined class by defining an @code{initialize} method -specialized to that class. - -Imagine a class whose instances' slots need to be initialized at -instance creation time by querying a database. Although it might be -possible to achieve this a combination of @code{#:init-thunk} keywords -and closures in the slot definitions, it is neater to write an -@code{initialize} method for the class that queries the database once -and initializes all the dependent slot values according to the results. - -@node Accessing Slots -@section Accessing Slots - -The definition of a slot contains at the very least a slot name, and may -also contain various slot options, including getter, setter and/or -accessor functions for the slot. - -It is always possible to access slots by name, using the various -``slot-ref'' and ``slot-set!'' procedures described in the following -subsections. For example, - -@example -(define-class () ;; Define a class with slots - (count #:init-value 0) ;; named "count" and "cache". - (cache #:init-value '()) - @dots{}) - -(define inst (make )) ;; Make an instance of this class. - -(slot-set! inst 'count 5) ;; Set the value of the "count" - ;; slot to 5. - -(slot-set! inst 'cache ;; Modify the value of the - (cons (cons "^it" "It") ;; "cache" slot. - (slot-ref inst 'cache))) -@end example - -If a slot definition includes a getter, setter or accessor function, -these can be used instead of @code{slot-ref} and @code{slot-set!} to -access the slot. - -@example -(define-class () ;; Define a new class whose slots - (count #:setter set-count) ;; use a getter, a setter and - (cache #:accessor cache) ;; an accessor. - (csize #:getter cache-size) - @dots{}) - -(define inst (make )) ;; Make an instance of this class. - -(set-count inst 5) ;; Set the value of the "count" - ;; slot to 5. - -(set! (cache inst) ;; Modify the value of the - (cons (cons "^it" "It") ;; "cache" slot. - (cache inst))) - -(let ((size (cache-size inst))) ;; Get the value of the "csize" - @dots{}) ;; slot. -@end example - -Whichever of these methods is used to access slots, GOOPS always calls -the low-level @dfn{getter} and @dfn{setter} closures for the slot to get -and set its value. These closures make sure that the slot behaves -according to the @code{#:allocation} type that was specified in the slot -definition (@pxref{Slot Options,, allocation}). (For more about these -closures, see @ref{Customizing Class Definition,, compute-get-n-set}.) - -@menu -* Instance Slots:: -* Class Slots:: -* Handling Slot Access Errors:: -@end menu - -@node Instance Slots -@subsection Instance Slots - -Any slot, regardless of its allocation, can be queried, referenced and -set using the following four primitive procedures. - -@deffn {primitive procedure} slot-exists? obj slot-name -Return @code{#t} if @var{obj} has a slot with name @var{slot-name}, -otherwise @code{#f}. -@end deffn - -@deffn {primitive procedure} slot-bound? obj slot-name -Return @code{#t} if the slot named @var{slot-name} in @var{obj} has a -value, otherwise @code{#f}. - -@code{slot-bound?} calls the generic function @code{slot-missing} if -@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling -Slot Access Errors, slot-missing}). -@end deffn - -@deffn {primitive procedure} slot-ref obj slot-name -Return the value of the slot named @var{slot-name} in @var{obj}. - -@code{slot-ref} calls the generic function @code{slot-missing} if -@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling -Slot Access Errors, slot-missing}). - -@code{slot-ref} calls the generic function @code{slot-unbound} if the -named slot in @var{obj} does not have a value (@pxref{Handling Slot -Access Errors, slot-unbound}). -@end deffn - -@deffn {primitive procedure} slot-set! obj slot-name value -Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}. - -@code{slot-set!} calls the generic function @code{slot-missing} if -@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling -Slot Access Errors, slot-missing}). -@end deffn - -GOOPS stores information about slots in class metaobjects. Internally, -all of these procedures work by looking up the slot definition for the -slot named @var{slot-name} in the class metaobject for @code{(class-of -@var{obj})}, and then using the slot definition's ``getter'' and -``setter'' closures to get and set the slot value. - -The next four procedures differ from the previous ones in that they take -the class metaobject as an explicit argument, rather than assuming -@code{(class-of @var{obj})}. Therefore they allow you to apply the -``getter'' and ``setter'' closures of a slot definition in one class to -an instance of a different class. - -[ *fixme* I have no idea why this is useful! Perhaps when a slot in -@code{(class-of @var{obj})} shadows a slot with the same name in one of -its superclasses? There should be an enlightening example here. ] - -@deffn {primitive procedure} slot-exists-using-class? class obj slot-name -Return @code{#t} if the class metaobject @var{class} has a slot -definition for a slot with name @var{slot-name}, otherwise @code{#f}. -@end deffn - -@deffn {primitive procedure} slot-bound-using-class? class obj slot-name -Return @code{#t} if applying @code{slot-ref-using-class} to the same -arguments would call the generic function @code{slot-unbound}, otherwise -@code{#f}. - -@code{slot-bound-using-class?} calls the generic function -@code{slot-missing} if @var{class} does not have a slot definition for a -slot called @var{slot-name} (@pxref{Handling Slot Access Errors, -slot-missing}). -@end deffn - -@deffn {primitive procedure} slot-ref-using-class class obj slot-name -Apply the ``getter'' closure for the slot named @var{slot-name} in -@var{class} to @var{obj}, and return its result. - -@code{slot-ref-using-class} calls the generic function -@code{slot-missing} if @var{class} does not have a slot definition for a -slot called @var{slot-name} (@pxref{Handling Slot Access Errors, -slot-missing}). - -@code{slot-ref-using-class} calls the generic function -@code{slot-unbound} if the application of the ``getter'' closure to -@var{obj} returns an unbound value (@pxref{Handling Slot Access Errors, -slot-unbound}). -@end deffn - -@deffn {primitive procedure} slot-set-using-class! class obj slot-name value -Apply the ``setter'' closure for the slot named @var{slot-name} in -@var{class} to @var{obj} and @var{value}. - -@code{slot-set-using-class!} calls the generic function -@code{slot-missing} if @var{class} does not have a slot definition for a -slot called @var{slot-name} (@pxref{Handling Slot Access Errors, -slot-missing}). -@end deffn - -@node Class Slots -@subsection Class Slots - -Slots whose allocation is per-class rather than per-instance can be -referenced and set without needing to specify any particular instance. - -@deffn procedure class-slot-ref class slot-name -Return the value of the slot named @var{slot-name} in class @var{class}. -The named slot must have @code{#:class} or @code{#:each-subclass} -allocation (@pxref{Slot Options,, allocation}). - -If there is no such slot with @code{#:class} or @code{#:each-subclass} -allocation, @code{class-slot-ref} calls the @code{slot-missing} generic -function with arguments @var{class} and @var{slot-name}. Otherwise, if -the slot value is unbound, @code{class-slot-ref} calls the -@code{slot-missing} generic function, with the same arguments. -@end deffn - -@deffn procedure class-slot-set! class slot-name value -Set the value of the slot named @var{slot-name} in class @var{class} to -@var{value}. The named slot must have @code{#:class} or -@code{#:each-subclass} allocation (@pxref{Slot Options,, allocation}). - -If there is no such slot with @code{#:class} or @code{#:each-subclass} -allocation, @code{class-slot-ref} calls the @code{slot-missing} generic -function with arguments @var{class} and @var{slot-name}. -@end deffn - -@node Handling Slot Access Errors -@subsection Handling Slot Access Errors - -GOOPS calls one of the following generic functions when a ``slot-ref'' -or ``slot-set!'' call specifies a non-existent slot name, or tries to -reference a slot whose value is unbound. - -@deffn generic slot-missing -@deffnx method slot-missing (class ) slot-name -@deffnx method slot-missing (class ) (object ) slot-name -@deffnx method slot-missing (class ) (object ) slot-name value -When an application attempts to reference or set a class or instance -slot by name, and the slot name is invalid for the specified @var{class} -or @var{object}, GOOPS calls the @code{slot-missing} generic function. - -The default methods all call @code{goops-error} with an appropriate -message. -@end deffn - -@deffn generic slot-unbound -@deffnx method slot-unbound (object ) -@deffnx method slot-unbound (class ) slot-name -@deffnx method slot-unbound (class ) (object ) slot-name -When an application attempts to reference a class or instance slot, and -the slot's value is unbound, GOOPS calls the @code{slot-unbound} generic -function. - -The default methods all call @code{goops-error} with an appropriate -message. -@end deffn - -@node Creating Generic Functions -@section Creating Generic Functions - -A generic function is a collection of methods, with rules for -determining which of the methods should be applied for any given -invocation of the generic function. - -GOOPS represents generic functions as metaobjects of the class -@code{} (or one of its subclasses). - -@menu -* Basic Generic Function Creation:: -* Generic Function Internals:: -* Extending Guiles Primitives:: -@end menu - -@node Basic Generic Function Creation -@subsection Basic Generic Function Creation - -The following forms may be used to bind a variable to a generic -function. Depending on that variable's pre-existing value, the generic -function may be created empty - with no methods - or it may contain -methods that are inferred from the pre-existing value. - -It is not, in general, necessary to use @code{define-generic} or -@code{define-accessor} before defining methods for the generic function -using @code{define-method}, since @code{define-method} will -automatically interpolate a @code{define-generic} call, or upgrade an -existing generic to an accessor, if that is implied by the -@code{define-method} call. Note in particular that, -if the specified variable already has a @emph{generic function} value, -@code{define-generic} and @code{define-accessor} will @emph{discard} it! -Obviously it is application-dependent whether this is desirable or not. - -If, for example, you wanted to extend @code{+} for a class representing -a new numerical type, you probably want to inherit any existing methods -for @code{+} and so should not use @code{define-generic}. If, on the -other hand, you do not want to risk inheriting methods whose behaviour -might surprise you, you can use @code{define-generic} or -@code{define-accessor} to wipe the slate clean. - -@deffn syntax define-generic symbol -Create a generic function with name @var{symbol} and bind it to the -variable @var{symbol}. - -If the variable @var{symbol} was previously bound to a Scheme procedure -(or procedure-with-setter), the old procedure (and setter) is -incorporated into the new generic function as its default procedure (and -setter). Any other previous value that was bound to @var{symbol}, -including an existing generic function, is overwritten by the new -generic function. -@end deffn - -@deffn syntax define-accessor symbol -Create an accessor with name @var{symbol} and bind it to the variable -@var{symbol}. - -If the variable @var{symbol} was previously bound to a Scheme procedure -(or procedure-with-setter), the old procedure (and setter) is -incorporated into the new accessor as its default procedure (and -setter). Any other previous value that was bound to @var{symbol}, -including an existing generic function or accessor, is overwritten by -the new definition. -@end deffn - -@node Generic Function Internals -@subsection Generic Function Internals - -@code{define-generic} calls @code{ensure-generic} to upgrade a -pre-existing procedure value, or @code{make} with metaclass -@code{} to create a new generic function. - -@code{define-accessor} calls @code{ensure-accessor} to upgrade a -pre-existing procedure value, or @code{make-accessor} to create a new -accessor. - -@deffn procedure ensure-generic old-definition [name] -Return a generic function with name @var{name}, if possible by using or -upgrading @var{old-definition}. If unspecified, @var{name} defaults to -@code{#f}. - -If @var{old-definition} is already a generic function, it is returned -unchanged. - -If @var{old-definition} is a Scheme procedure or procedure-with-setter, -@code{ensure-generic} returns a new generic function that uses -@var{old-definition} for its default procedure and setter. - -Otherwise @code{ensure-generic} returns a new generic function with no -defaults and no methods. -@end deffn - -@deffn procedure make-generic [name] -Return a new generic function with name @code{(car @var{name})}. If -unspecified, @var{name} defaults to @code{#f}. -@end deffn - -@code{ensure-generic} calls @code{make} with metaclasses -@code{} and @code{}, depending on the -previous value of the variable that it is trying to upgrade. - -@code{make-generic} is a simple wrapper for @code{make} with metaclass -@code{}. - -@deffn procedure ensure-accessor proc [name] -Return an accessor with name @var{name}, if possible by using or -upgrading @var{proc}. If unspecified, @var{name} defaults to @code{#f}. - -If @var{proc} is already an accessor, it is returned unchanged. - -If @var{proc} is a Scheme procedure, procedure-with-setter or generic -function, @code{ensure-accessor} returns an accessor that reuses the -reusable elements of @var{proc}. - -Otherwise @code{ensure-accessor} returns a new accessor with no defaults -and no methods. -@end deffn - -@deffn procedure make-accessor [name] -Return a new accessor with name @code{(car @var{name})}. If -unspecified, @var{name} defaults to @code{#f}. -@end deffn - -@code{ensure-accessor} calls @code{make} with -metaclass @code{}, as well as calls to -@code{ensure-generic}, @code{make-accessor} and (tail recursively) -@code{ensure-accessor}. - -@code{make-accessor} calls @code{make} twice, first -with metaclass @code{} to create a generic function for the -setter, then with metaclass @code{} to create the -accessor, passing the setter generic function as the value of the -@code{#:setter} keyword. - -@node Extending Guiles Primitives -@subsection Extending Guile's Primitives - -When GOOPS is loaded, many of Guile's primitive procedures can be -extended by giving them a generic function definition that operates -in conjunction with their normal C-coded implementation. For -primitives that are extended in this way, the result from the user- -or application-level point of view is that the extended primitive -behaves exactly like a generic function with the C-coded implementation -as its default method. - -The @code{generic-capability?} predicate should be used to determine -whether a particular primitive is extensible in this way. - -@deffn {primitive procedure} generic-capability? primitive -Return @code{#t} if @var{primitive} can be extended by giving it a -generic function definition, otherwise @code{#f}. -@end deffn - -Even when a primitive procedure is extensible like this, its generic -function definition is not created until it is needed by a call to -@code{define-method}, or until the application explicitly requests it -by calling @code{enable-primitive-generic!}. - -@deffn {primitive procedure} enable-primitive-generic! primitive -Force the creation of a generic function definition for -@var{primitive}. -@end deffn - -Once the generic function definition for a primitive has been created, -it can be retrieved using @code{primitive-generic-generic}. - -@deffn {primitive procedure} primitive-generic-generic primitive -Return the generic function definition of @var{primitive}. - -@code{primitive-generic-generic} raises an error if @var{primitive} -is not a primitive with generic capability, or if its generic capability -has not yet been enabled, whether implicitly (by @code{define-method}) -or explicitly (by @code{enable-primitive-generic!}). -@end deffn - -Note that the distinction between, on the one hand, primitives with -additional generic function definitions and, on the other hand, generic -functions with a default method, may disappear when GOOPS is fully -integrated into the core of Guile. Consequently, the -procedures described in this section may disappear as well. - -@node Adding Methods to Generic Functions -@section Adding Methods to Generic Functions - -@menu -* Basic Method Definition:: -* Method Definition Internals:: -@end menu - -@node Basic Method Definition -@subsection Basic Method Definition - -To add a method to a generic function, use the @code{define-method} form. - -@deffn syntax define-method (generic parameter @dots{}) . body -Define a method for the generic function or accessor @var{generic} with -parameters @var{parameter}s and body @var{body}. - -@var{generic} is a generic function. If @var{generic} is a variable -which is not yet bound to a generic function object, the expansion of -@code{define-method} will include a call to @code{define-generic}. If -@var{generic} is @code{(setter @var{generic-with-setter})}, where -@var{generic-with-setter} is a variable which is not yet bound to a -generic-with-setter object, the expansion will include a call to -@code{define-accessor}. - -Each @var{parameter} must be either a symbol or a two-element list -@code{(@var{symbol} @var{class})}. The symbols refer to variables in -the @var{body} that will be bound to the parameters supplied by the -caller when calling this method. The @var{class}es, if present, -specify the possible combinations of parameters to which this method -can be applied. - -@var{body} is the body of the method definition. -@end deffn - -@code{define-method} expressions look a little like normal Scheme -procedure definitions of the form - -@example -(define (name formals @dots{}) . body) -@end example - -The most important difference is that each formal parameter, apart from the -possible ``rest'' argument, can be qualified by a class name: -@code{@var{formal}} becomes @code{(@var{formal} @var{class})}. The -meaning of this qualification is that the method being defined -will only be applicable in a particular generic function invocation if -the corresponding argument is an instance of @code{@var{class}} (or one of -its subclasses). If more than one of the formal parameters is qualified -in this way, then the method will only be applicable if each of the -corresponding arguments is an instance of its respective qualifying class. - -Note that unqualified formal parameters act as though they are qualified -by the class @code{}, which GOOPS uses to mean the superclass of -all valid Scheme types, including both primitive types and GOOPS classes. - -For example, if a generic function method is defined with -@var{parameter}s @code{((s1 ) (n ))}, that method is -only applicable to invocations of its generic function that have two -parameters where the first parameter is an instance of the -@code{} class and the second parameter is a number. - -If a generic function is invoked with a combination of parameters for which -there is no applicable method, GOOPS raises an error. For more about -invocation error handling, and generic function invocation in general, -see @ref{Invoking Generic Functions}. - -@node Method Definition Internals -@subsection Method Definition Internals - -@code{define-method} - -@itemize @bullet -@item -checks the form of the first parameter, and applies the following steps -to the accessor's setter if it has the @code{(setter @dots{})} form - -@item -interpolates a call to @code{define-generic} or @code{define-accessor} -if a generic function is not already defined with the supplied name - -@item -calls @code{method} with the @var{parameter}s and @var{body}, to make a -new method instance - -@item -calls @code{add-method!} to add this method to the relevant generic -function. -@end itemize - -@deffn syntax method (parameter @dots{}) . body -Make a method whose specializers are defined by the classes in -@var{parameter}s and whose procedure definition is constructed from the -@var{parameter} symbols and @var{body} forms. - -The @var{parameter} and @var{body} parameters should be as for -@code{define-method} (@pxref{Basic Method Definition,, define-method}). -@end deffn - -@code{method} - -@itemize @bullet -@item -extracts formals and specializing classes from the @var{parameter}s, -defaulting the class for unspecialized parameters to @code{} - -@item -creates a closure using the formals and the @var{body} forms - -@item -calls @code{make} with metaclass @code{} and the specializers -and closure using the @code{#:specializers} and @code{#:procedure} -keywords. -@end itemize - -@deffn procedure make-method specializers procedure -Make a method using @var{specializers} and @var{procedure}. - -@var{specializers} should be a list of classes that specifies the -parameter combinations to which this method will be applicable. - -@var{procedure} should be the closure that will applied to the generic -function parameters when this method is invoked. -@end deffn - -@code{make-method} is a simple wrapper around @code{make} with metaclass -@code{}. - -@deffn generic add-method! target method -Generic function for adding method @var{method} to @var{target}. -@end deffn - -@deffn method add-method! (generic ) (method ) -Add method @var{method} to the generic function @var{generic}. -@end deffn - -@deffn method add-method! (proc ) (method ) -If @var{proc} is a procedure with generic capability (@pxref{Extending -Guiles Primitives,, generic-capability?}), upgrade it to a -primitive generic and add @var{method} to its generic function -definition. -@end deffn - -@deffn method add-method! (pg ) (method ) -Add method @var{method} to the generic function definition of @var{pg}. - -Implementation: @code{(add-method! (primitive-generic-generic pg) method)}. -@end deffn - -@deffn method add-method! (whatever ) (method ) -Raise an error indicating that @var{whatever} is not a valid generic -function. -@end deffn - -@node Invoking Generic Functions -@section Invoking Generic Functions - -When a variable with a generic function definition appears as the first -element of a list that is being evaluated, the Guile evaluator tries -to apply the generic function to the arguments obtained by evaluating -the remaining elements of the list. [ *fixme* How do I put this in a -more Schemely and less Lispy way? ] - -Usually a generic function contains several method definitions, with -varying degrees of formal parameter specialization (@pxref{Basic -Method Definition,, define-method}). So it is necessary to sort these -methods by specificity with respect to the supplied arguments, and then -apply the most specific method definition. Less specific methods -may be applied subsequently if a method that is being applied calls -@code{next-method}. - -@menu -* Determining Which Methods to Apply:: -* Handling Invocation Errors:: -@end menu - -@node Determining Which Methods to Apply -@subsection Determining Which Methods to Apply - -[ *fixme* Sorry - this is the area of GOOPS that I understand least of -all, so I'm afraid I have to pass on this section. Would some other -kind person consider filling it in? ] - -@deffn generic apply-generic -@deffnx method apply-generic (gf ) args -@end deffn - -@deffn generic compute-applicable-methods -@deffnx method compute-applicable-methods (gf ) args -@end deffn - -@deffn generic sort-applicable-methods -@deffnx method sort-applicable-methods (gf ) methods args -@end deffn - -@deffn generic method-more-specific? -@deffnx method method-more-specific? (m1 ) (m2 ) args -@end deffn - -@deffn generic apply-method -@deffnx method apply-method (gf ) methods build-next args -@end deffn - -@deffn generic apply-methods -@deffnx method apply-methods (gf ) (l ) args -@end deffn - -@node Handling Invocation Errors -@subsection Handling Invocation Errors - -@deffn generic no-method -@deffnx method no-method (gf ) args -When an application invokes a generic function, and no methods at all -have been defined for that generic function, GOOPS calls the -@code{no-method} generic function. The default method calls -@code{goops-error} with an appropriate message. -@end deffn - -@deffn generic no-applicable-method -@deffnx method no-applicable-method (gf ) args -When an application applies a generic function to a set of arguments, -and no methods have been defined for those argument types, GOOPS calls -the @code{no-applicable-method} generic function. The default method -calls @code{goops-error} with an appropriate message. -@end deffn - -@deffn generic no-next-method -@deffnx method no-next-method (gf ) args -When a generic function method calls @code{(next-method)} to invoke the -next less specialized method for that generic function, and no less -specialized methods have been defined for the current generic function -arguments, GOOPS calls the @code{no-next-method} generic function. The -default method calls @code{goops-error} with an appropriate message. -@end deffn - -@node Redefining a Class -@section Redefining a Class - -Suppose that a class @code{} is defined using @code{define-class} -(@pxref{Basic Class Definition,, define-class}), with slots that have -accessor functions, and that an application has created several instances -of @code{} using @code{make} (@pxref{Basic Instance Creation,, -make}). What then happens if @code{} is redefined by calling -@code{define-class} again? - -@menu -* Default Class Redefinition Behaviour:: -* Customizing Class Redefinition:: -@end menu - -@node Default Class Redefinition Behaviour -@subsection Default Class Redefinition Behaviour - -GOOPS' default answer to this question is as follows. - -@itemize @bullet -@item -All existing direct instances of @code{} are converted to be -instances of the new class. This is achieved by preserving the values -of slots that exist in both the old and new definitions, and initializing the -values of new slots in the usual way (@pxref{Basic Instance Creation,, -make}). - -@item -All existing subclasses of @code{} are redefined, as though -the @code{define-class} expressions that defined them were re-evaluated -following the redefinition of @code{}, and the class -redefinition process described here is applied recursively to the -redefined subclasses. - -@item -Once all of its instances and subclasses have been updated, the class -metaobject previously bound to the variable @code{} is no -longer needed and so can be allowed to be garbage collected. -@end itemize - -To keep things tidy, GOOPS also needs to do a little housekeeping on -methods that are associated with the redefined class. - -@itemize @bullet -@item -Slot accessor methods for slots in the old definition should be removed -from their generic functions. They will be replaced by accessor methods -for the slots of the new class definition. - -@item -Any generic function method that uses the old @code{} metaobject -as one of its formal parameter specializers must be updated to refer to -the new @code{} metaobject. (Whenever a new generic function -method is defined, @code{define-method} adds the method to a list stored -in the class metaobject for each class used as a formal parameter -specializer, so it is easy to identify all the methods that must be -updated when a class is redefined.) -@end itemize - -If this class redefinition strategy strikes you as rather counter-intuitive, -bear in mind that it is derived from similar behaviour in other object -systems such as CLOS, and that experience in those systems has shown it to be -very useful in practice. - -Also bear in mind that, like most of GOOPS' default behaviour, it can -be customized@dots{} - -@node Customizing Class Redefinition -@subsection Customizing Class Redefinition - -When @code{define-class} notices that a class is being redefined, -it constructs the new class metaobject as usual, and then invokes the -@code{class-redefinition} generic function with the old and new classes -as arguments. Therefore, if the old or new classes have metaclasses -other than the default @code{}, class redefinition behaviour can -be customized by defining a @code{class-redefinition} method that is -specialized for the relevant metaclasses. - -@deffn generic class-redefinition -Handle the class redefinition from @var{old-class} to @var{new-class}, -and return the new class metaobject that should be bound to the -variable specified by @code{define-class}'s first argument. -@end deffn - -@deffn method class-redefinition (old-class ) (new-class ) -Implements GOOPS' default class redefinition behaviour, as described in -@ref{Default Class Redefinition Behaviour}. Returns the metaobject -for the new class definition. -@end deffn - -An alternative class redefinition strategy could be to leave all -existing instances as instances of the old class, but accepting that the -old class is now ``nameless'', since its name has been taken over by the -new definition. In this strategy, any existing subclasses could also -be left as they are, on the understanding that they inherit from a nameless -superclass. - -This strategy is easily implemented in GOOPS, by defining a new metaclass, -that will be used as the metaclass for all classes to which the strategy -should apply, and then defining a @code{class-redefinition} method that -is specialized for this metaclass: - -@example -(define-class ()) - -(define-method (class-redefinition (old ) (new )) - new) -@end example - -When customization can be as easy as this, aren't you glad that GOOPS -implements the far more difficult strategy as its default! - -Finally, note that, if @code{class-redefinition} itself is not customized, -the default @code{class-redefinition} method invokes three further -generic functions that could be individually customized: - -@itemize @bullet -@item -(remove-class-accessors! @var{old-class}) - -@item -(update-direct-method! @var{method} @var{old-class} @var{new-class}) - -@item -(update-direct-subclass! @var{subclass} @var{old-class} @var{new-class}) -@end itemize - -and the default methods for these generic functions invoke further -generic functions, and so on@dots{} The detailed protocol for all of these -is described in @ref{MOP Specification}. - -@node Changing the Class of an Instance -@section Changing the Class of an Instance - -You can change the class of an existing instance by invoking the -generic function @code{change-class} with two arguments: the instance -and the new class. - -@deffn generic change-class -@end deffn - -The default method for @code{change-class} decides how to implement the -change of class by looking at the slot definitions for the instance's -existing class and for the new class. If the new class has slots with -the same name as slots in the existing class, the values for those slots -are preserved. Slots that are present only in the existing class are -discarded. Slots that are present only in the new class are initialized -using the corresponding slot definition's init function (@pxref{Classes,, -slot-init-function}). - -@deffn {method} change-class (obj ) (new ) -Modify instance @var{obj} to make it an instance of class @var{new}. - -The value of each of @var{obj}'s slots is preserved only if a similarly named -slot exists in @var{new}; any other slot values are discarded. - -The slots in @var{new} that do not correspond to any of @var{obj}'s -pre-existing slots are initialized according to @var{new}'s slot definitions' -init functions. -@end deffn - -Customized change of class behaviour can be implemented by defining -@code{change-class} methods that are specialized either by the class -of the instances to be modified or by the metaclass of the new class. - -When a class is redefined (@pxref{Redefining a Class}), and the default -class redefinition behaviour is not overridden, GOOPS (eventually) -invokes the @code{change-class} generic function for each existing -instance of the redefined class. - -@node Introspection -@section Introspection - -@dfn{Introspection}, also known as @dfn{reflection}, is the name given -to the ability to obtain information dynamically about GOOPS metaobjects. -It is perhaps best illustrated by considering an object oriented language -that does not provide any introspection, namely C++. - -Nothing in C++ allows a running program to obtain answers to the following -types of question: - -@itemize @bullet -@item -What are the data members of this object or class? - -@item -What classes does this class inherit from? - -@item -Is this method call virtual or non-virtual? - -@item -If I invoke @code{Employee::adjustHoliday()}, what class contains the -@code{adjustHoliday()} method that will be applied? -@end itemize - -In C++, answers to such questions can only be determined by looking at -the source code, if you have access to it. GOOPS, on the other hand, -includes procedures that allow answers to these questions --- or their -GOOPS equivalents --- to be obtained dynamically, at run time. - -@menu -* Classes:: -* Slots:: -* Instances:: -* Generic Functions:: -* Generic Function Methods:: -@end menu - -@node Classes -@subsection Classes - -@deffn {primitive procedure} class-name class -Return the name of class @var{class}. -This is the value of the @var{class} metaobject's @code{name} slot. -@end deffn - -@deffn {primitive procedure} class-direct-supers class -Return a list containing the direct superclasses of @var{class}. -This is the value of the @var{class} metaobject's -@code{direct-supers} slot. -@end deffn - -@deffn {primitive procedure} class-direct-slots class -Return a list containing the slot definitions of the direct slots of -@var{class}. -This is the value of the @var{class} metaobject's @code{direct-slots} -slot. -@end deffn - -@deffn {primitive procedure} class-direct-subclasses class -Return a list containing the direct subclasses of @var{class}. -This is the value of the @var{class} metaobject's -@code{direct-subclasses} slot. -@end deffn - -@deffn {primitive procedure} class-direct-methods class -Return a list of all the generic function methods that use @var{class} -as a formal parameter specializer. -This is the value of the @var{class} metaobject's @code{direct-methods} -slot. -@end deffn - -@deffn {primitive procedure} class-precedence-list class -Return the class precedence list for class @var{class} (@pxref{Class -precedence list}). -This is the value of the @var{class} metaobject's @code{cpl} slot. -@end deffn - -@deffn {primitive procedure} class-slots class -Return a list containing the slot definitions for all @var{class}'s slots, -including any slots that are inherited from superclasses. -This is the value of the @var{class} metaobject's @code{slots} slot. -@end deffn - -@deffn {primitive procedure} class-environment class -Return the value of @var{class}'s @code{environment} slot. -[ *fixme* I don't know what this value is used for. ] -@end deffn - -@deffn procedure class-subclasses class -Return a list of all subclasses of @var{class}. -@end deffn - -@deffn procedure class-methods class -Return a list of all methods that use @var{class} or a subclass of -@var{class} as one of its formal parameter specializers. -@end deffn - -@node Slots -@subsection Slots - -@deffn procedure class-slot-definition class slot-name -Return the slot definition for the slot named @var{slot-name} in class -@var{class}. @var{slot-name} should be a symbol. -@end deffn - -@deffn procedure slot-definition-name slot-def -Extract and return the slot name from @var{slot-def}. -@end deffn - -@deffn procedure slot-definition-options slot-def -Extract and return the slot options from @var{slot-def}. -@end deffn - -@deffn procedure slot-definition-allocation slot-def -Extract and return the slot allocation option from @var{slot-def}. This -is the value of the @code{#:allocation} keyword (@pxref{Slot Options,, -allocation}), or @code{#:instance} if the @code{#:allocation} keyword is -absent. -@end deffn - -@deffn procedure slot-definition-getter slot-def -Extract and return the slot getter option from @var{slot-def}. This is -the value of the @code{#:getter} keyword (@pxref{Slot Options,, -getter}), or @code{#f} if the @code{#:getter} keyword is absent. -@end deffn - -@deffn procedure slot-definition-setter slot-def -Extract and return the slot setter option from @var{slot-def}. This is -the value of the @code{#:setter} keyword (@pxref{Slot Options,, -setter}), or @code{#f} if the @code{#:setter} keyword is absent. -@end deffn - -@deffn procedure slot-definition-accessor slot-def -Extract and return the slot accessor option from @var{slot-def}. This -is the value of the @code{#:accessor} keyword (@pxref{Slot Options,, -accessor}), or @code{#f} if the @code{#:accessor} keyword is absent. -@end deffn - -@deffn procedure slot-definition-init-value slot-def -Extract and return the slot init-value option from @var{slot-def}. This -is the value of the @code{#:init-value} keyword (@pxref{Slot Options,, -init-value}), or the unbound value if the @code{#:init-value} keyword is -absent. -@end deffn - -@deffn procedure slot-definition-init-form slot-def -Extract and return the slot init-form option from @var{slot-def}. This -is the value of the @code{#:init-form} keyword (@pxref{Slot Options,, -init-form}), or the unbound value if the @code{#:init-form} keyword is -absent. -@end deffn - -@deffn procedure slot-definition-init-thunk slot-def -Extract and return the slot init-thunk option from @var{slot-def}. This -is the value of the @code{#:init-thunk} keyword (@pxref{Slot Options,, -init-thunk}), or @code{#f} if the @code{#:init-thunk} keyword is absent. -@end deffn - -@deffn procedure slot-definition-init-keyword slot-def -Extract and return the slot init-keyword option from @var{slot-def}. -This is the value of the @code{#:init-keyword} keyword (@pxref{Slot -Options,, init-keyword}), or @code{#f} if the @code{#:init-keyword} -keyword is absent. -@end deffn - -@deffn procedure slot-init-function class slot-name -Return the initialization function for the slot named @var{slot-name} in -class @var{class}. @var{slot-name} should be a symbol. - -The returned initialization function incorporates the effects of the -standard @code{#:init-thunk}, @code{#:init-form} and @code{#:init-value} -slot options. These initializations can be overridden by the -@code{#:init-keyword} slot option or by a specialized @code{initialize} -method, so, in general, the function returned by -@code{slot-init-function} may be irrelevant. For a fuller discussion, -see @ref{Slot Options,, init-value}. -@end deffn - -@node Instances -@subsection Instances - -@deffn {primitive procedure} class-of value -Return the GOOPS class of any Scheme @var{value}. -@end deffn - -@deffn {primitive procedure} instance? object -Return @code{#t} if @var{object} is any GOOPS instance, otherwise -@code{#f}. -@end deffn - -@deffn procedure is-a? object class -Return @code{#t} if @var{object} is an instance of @var{class} or one of -its subclasses. -@end deffn - -Implementation notes: @code{is-a?} uses @code{class-of} and -@code{class-precedence-list} to obtain the class precedence list for -@var{object}. - -@node Generic Functions -@subsection Generic Functions - -@deffn {primitive procedure} generic-function-name gf -Return the name of generic function @var{gf}. -@end deffn - -@deffn {primitive procedure} generic-function-methods gf -Return a list of the methods of generic function @var{gf}. -This is the value of the @var{gf} metaobject's @code{methods} slot. -@end deffn - -@node Generic Function Methods -@subsection Generic Function Methods - -@deffn {primitive procedure} method-generic-function method -Return the generic function that @var{method} belongs to. -This is the value of the @var{method} metaobject's -@code{generic-function} slot. -@end deffn - -@deffn {primitive procedure} method-specializers method -Return a list of @var{method}'s formal parameter specializers . -This is the value of the @var{method} metaobject's -@code{specializers} slot. -@end deffn - -@deffn {primitive procedure} method-procedure method -Return the procedure that implements @var{method}. -This is the value of the @var{method} metaobject's -@code{procedure} slot. -@end deffn - -@deffn generic method-source -@deffnx method method-source (m ) -Return an expression that prints to show the definition of method -@var{m}. - -@example -(define-generic cube) - -(define-method (cube (n )) - (* n n n)) - -(map method-source (generic-function-methods cube)) -@result{} -((method ((n )) (* n n n))) -@end example -@end deffn - -@node Miscellaneous Functions -@section Miscellaneous Functions - -@menu -* Administrative Functions:: -* Error Handling:: -* Object Comparisons:: -* Cloning Objects:: -* Write and Display:: -@end menu - -@node Administrative Functions -@subsection Administration Functions - -This section describes administrative, non-technical GOOPS functions. - -@deffn primitive goops-version -Return the current GOOPS version as a string, for example ``0.2''. -@end deffn - -@node Error Handling -@subsection Error Handling - -The procedure @code{goops-error} is called to raise an appropriate error -by the default methods of the following generic functions: - -@itemize @bullet -@item -@code{slot-missing} (@pxref{Handling Slot Access Errors,, slot-missing}) - -@item -@code{slot-unbound} (@pxref{Handling Slot Access Errors,, slot-unbound}) - -@item -@code{no-method} (@pxref{Handling Invocation Errors,, no-method}) - -@item -@code{no-applicable-method} (@pxref{Handling Invocation Errors,, -no-applicable-method}) - -@item -@code{no-next-method} (@pxref{Handling Invocation Errors,, -no-next-method}) -@end itemize - -If you customize these functions for particular classes or metaclasses, -you may still want to use @code{goops-error} to signal any error -conditions that you detect. - -@deffn procedure goops-error format-string . args -Raise an error with key @code{goops-error} and error message constructed -from @var{format-string} and @var{args}. Error message formatting is -as done by @code{scm-error}. -@end deffn - -@node Object Comparisons -@subsection Object Comparisons - -@deffn generic object-eqv? -@deffnx method object-eqv? ((x ) (y )) -@deffnx generic object-equal? -@deffnx method object-equal? ((x ) (y )) -Generic functions and default (unspecialized) methods for comparing two -GOOPS objects. - -The default methods always return @code{#f}. Application class authors -may wish to define specialized methods for @code{object-eqv?} and -@code{object-equal?} that compare instances of the same class for -equality in whatever sense is useful to the application. -@end deffn - -@node Cloning Objects -@subsection Cloning Objects - -@deffn generic shallow-clone -@deffnx method shallow-clone (self ) -Return a ``shallow'' clone of @var{self}. The default method makes a -shallow clone by allocating a new instance and copying slot values from -self to the new instance. Each slot value is copied either as an -immediate value or by reference. -@end deffn - -@deffn generic deep-clone -@deffnx method deep-clone (self ) -Return a ``deep'' clone of @var{self}. The default method makes a deep -clone by allocating a new instance and copying or cloning slot values -from self to the new instance. If a slot value is an instance -(satisfies @code{instance?}), it is cloned by calling @code{deep-clone} -on that value. Other slot values are copied either as immediate values -or by reference. -@end deffn - -@node Write and Display -@subsection Write and Display - -@deffn {primitive generic} write object port -@deffnx {primitive generic} display object port -When GOOPS is loaded, @code{write} and @code{display} become generic -functions with special methods for printing - -@itemize @bullet -@item -objects - instances of the class @code{} - -@item -foreign objects - instances of the class @code{} - -@item -classes - instances of the class @code{} - -@item -generic functions - instances of the class @code{} - -@item -methods - instances of the class @code{}. -@end itemize - -@code{write} and @code{display} print non-GOOPS values in the same way -as the Guile primitive @code{write} and @code{display} functions. -@end deffn - -@node MOP Specification, Tutorial, Reference Manual, Top -@chapter MOP Specification - -For an introduction to metaobjects and the metaobject protocol, -see @ref{Metaobjects and the Metaobject Protocol}. - -The aim of the MOP specification in this chapter is to specify all the -customizable generic function invocations that can be made by the standard -GOOPS syntax, procedures and methods, and to explain the protocol for -customizing such invocations. - -A generic function invocation is customizable if the types of the arguments -to which it is applied are not all determined by the lexical context in -which the invocation appears. For example, - -@itemize @bullet -@item -the @code{(initialize @var{instance} @var{initargs})} invocation in the -default @code{make-instance} method is customizable, because the type of the -@code{@var{instance}} argument is determined by the class that was passed to -@code{make-instance}. - -@item -the @code{(make #:name ',name)} invocation in @code{define-generic} -is not customizable, because all of its arguments have lexically determined -types. -@end itemize - -When using this rule to decide whether a given generic function invocation -is customizable, we ignore arguments that are expected to be handled in -method definitions as a single ``rest'' list argument. - -For each customizable generic function invocation, the @dfn{invocation -protocol} is explained by specifying - -@itemize @bullet -@item -what, conceptually, the applied method is intended to do - -@item -what assumptions, if any, the caller makes about the applied method's side -effects - -@item -what the caller expects to get as the applied method's return value. -@end itemize - -@menu -* Class Definition:: -* Instance Creation:: -* Class Redefinition:: -* Method Definition:: -* Generic Function Invocation:: -@end menu - -@node Class Definition -@section Class Definition - -@code{define-class} (syntax) - -@itemize @bullet -@item -@code{class} (syntax) - -@itemize @bullet -@item -@code{make-class} (procedure) - -@itemize @bullet -@item -@code{make @var{metaclass} @dots{}} (generic) - -@var{metaclass} is the metaclass of the class being defined, either -taken from the @code{#:metaclass} class option or computed by -@code{ensure-metaclass}. The applied method must create and return the -fully initialized class metaobject for the new class definition. -@end itemize - -@end itemize - -@item -@code{class-redefinition @var{old-class} @var{new-class}} (generic) - -@code{define-class} calls @code{class-redefinition} if the variable -specified by its first argument already held a GOOPS class definition. -@var{old-class} and @var{new-class} are the old and new class metaobjects. -The applied method should perform whatever is necessary to handle the -redefinition, and should return the class metaobject that is to be bound -to @code{define-class}'s variable. The default class redefinition -protocol is described in @ref{Class Redefinition}. -@end itemize - -The @code{(make @var{metaclass} @dots{})} invocation above will create -an class metaobject with metaclass @var{metaclass}. By default, this -metaobject will be initialized by the @code{initialize} method that is -specialized for instances of type @code{}. - -@code{initialize @var{initargs}} (method) - -@itemize @bullet -@item -@code{compute-cpl @var{class}} (generic) - -The applied method should compute and return the class precedence list -for @var{class} as a list of class metaobjects. When @code{compute-cpl} -is called, the following @var{class} metaobject slots have all been -initialized: @code{name}, @code{direct-supers}, @code{direct-slots}, -@code{direct-subclasses} (empty), @code{direct-methods}. The value -returned by @code{compute-cpl} will be stored in the @code{cpl} slot. - -@item -@code{compute-slots @var{class}} (generic) - -The applied method should compute and return the slots (union of direct -and inherited) for @var{class} as a list of slot definitions. When -@code{compute-slots} is called, all the @var{class} metaobject slots -mentioned for @code{compute-cpl} have been initialized, plus the -following: @code{cpl}, @code{redefined} (@code{#f}), @code{environment}. -The value returned by @code{compute-slots} will be stored in the -@code{slots} slot. - -@item -@code{compute-get-n-set @var{class} @var{slot-def}} (generic) - -@code{initialize} calls @code{compute-get-n-set} for each slot computed -by @code{compute-slots}. The applied method should compute and return a -pair of closures that, respectively, get and set the value of the specified -slot. The get closure should have arity 1 and expect a single argument -that is the instance whose slot value is to be retrieved. The set closure -should have arity 2 and expect two arguments, where the first argument is -the instance whose slot value is to be set and the second argument is the -new value for that slot. The closures should be returned in a two element -list: @code{(list @var{get} @var{set})}. - -The closures returned by @code{compute-get-n-set} are stored as part of -the value of the @var{class} metaobject's @code{getters-n-setters} slot. -Specifically, the value of this slot is a list with the same number of -elements as there are slots in the class, and each element looks either like - -@example -@code{(@var{slot-name-symbol} @var{init-function} . @var{index})} -@end example - -or like - -@example -@code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})} -@end example - -Where the get and set closures are replaced by @var{index}, the slot is -an instance slot and @var{index} is the slot's index in the underlying -structure: GOOPS knows how to get and set the value of such slots and so -does not need specially constructed get and set closures. Otherwise, -@var{get} and @var{set} are the closures returned by @code{compute-get-n-set}. - -The structure of the @code{getters-n-setters} slot value is important when -understanding the next customizable generic functions that @code{initialize} -calls@dots{} - -@item -@code{compute-getter-method @var{class} @var{gns}} (generic) - -@code{initialize} calls @code{compute-getter-method} for each of the class's -slots (as determined by @code{compute-slots}) that includes a -@code{#:getter} or @code{#:accessor} slot option. @var{gns} is the -element of the @var{class} metaobject's @code{getters-n-setters} slot that -specifies how the slot in question is referenced and set, as described -above under @code{compute-get-n-set}. The applied method should create -and return a method that is specialized for instances of type @var{class} -and uses the get closure to retrieve the slot's value. [ *fixme Need -to insert something here about checking that the value is not unbound. ] -@code{initialize} uses @code{add-method!} to add the returned method to -the generic function named by the slot definition's @code{#:getter} or -@code{#:accessor} option. - -@item -@code{compute-setter-method @var{class} @var{gns}} (generic) - -@code{compute-setter-method} is invoked with the same arguments as -@code{compute-getter-method}, for each of the class's slots that includes -a @code{#:setter} or @code{#:accessor} slot option. The applied method -should create and return a method that is specialized for instances of -type @var{class} and uses the set closure to set the slot's value. -@code{initialize} then uses @code{add-method!} to add the returned method -to the generic function named by the slot definition's @code{#:setter} -or @code{#:accessor} option. -@end itemize - -@node Instance Creation -@section Instance Creation - -@code{make . @var{initargs}} (method) - -@itemize @bullet -@item -@code{allocate-instance @var{class} @var{initargs}} (generic) - -The applied @code{allocate-instance} method should allocate storage for -a new instance of class @var{class} and return the uninitialized instance. - -@item -@code{initialize @var{instance} @var{initargs}} (generic) - -@var{instance} is the uninitialized instance returned by -@code{allocate-instance}. The applied method should initialize the new -instance in whatever sense is appropriate for its class. The method's -return value is ignored. -@end itemize - -@node Class Redefinition -@section Class Redefinition - -The default @code{class-redefinition} method, specialized for classes -with the default metaclass @code{}, has the following internal -protocol. - -[ *fixme* I'm not sure that I understand this sufficiently to explain -it. Also, the internals of the default class redefinition method are -extremely implementation-specific, and I'm not sure that there is that -much point trying to describe the internal protocol such that it could -be customized without going to look at the source code. ] - -@code{class-redefinition @var{(old )} @var{(new )}} -(method) - -@itemize @bullet -@item -@code{remove-class-accessors! @var{old}} (generic) - -@item -@code{update-direct-method! @var{method} @var{old} @var{new}} (generic) - -@item -@code{update-direct-subclass! @var{subclass} @var{old} @var{new}} (generic) -@end itemize - -The default @code{update-direct-subclass!} method invokes -@code{class-redefinition} recursively to handle the redefinition of the -subclass. - -When a class is redefined, any existing instance of the redefined class -will be modified for the new class definition before the next time that -any of the instance's slot is referenced or set. GOOPS modifies each -instance by calling the generic function @code{change-class}. [ *fixme* -Actually it sometimes calls @code{change-class} and sometimes -@code{change-object-class}, and I don't understand why. ] - -The default @code{change-class} method copies slot values from the old -to the modified instance, and initializes new slots, as described in -@ref{Changing the Class of an Instance}. After doing so, it makes a -generic function invocation that can be used to customize the instance -update algorithm. - -@code{change-class @var{(old-instance )} @var{(new )}} (method) - -@itemize @bullet -@item -@code{update-instance-for-different-class @var{old-instance} @var{new-instance}} (generic) - -@code{change-class} invokes @code{update-instance-for-different-class} -as the last thing that it does before returning. The applied method can -make any further adjustments to @var{new-instance} that are required to -complete or modify the change of class. The return value from the -applied method is ignored. - -The default @code{update-instance-for-different-class} method does -nothing. -@end itemize - -@node Method Definition -@section Method Definition - -@code{define-method} (syntax) - -@itemize @bullet -@item -@code{add-method! @var{target} @var{method}} (generic) - -@code{define-method} invokes the @code{add-method!} generic function to -handle adding the new method to a variety of possible targets. GOOPS -includes methods to handle @var{target} as - -@itemize @bullet -@item -a generic function (the most common case) - -@item -a procedure - -@item -a primitive generic (@pxref{Extending Guiles Primitives}) -@end itemize - -By defining further methods for @code{add-method!}, you can -theoretically handle adding methods to further types of target. -@end itemize - -@node Generic Function Invocation -@section Generic Function Invocation - -[ *fixme* Description required here. ] - -@code{apply-generic} - -@itemize @bullet -@item -@code{no-method} - -@item -@code{compute-applicable-methods} - -@item -@code{sort-applicable-methods} - -@item -@code{apply-methods} - -@item -@code{no-applicable-method} -@end itemize - -@code{sort-applicable-methods} - -@itemize @bullet -@item -@code{method-more-specific?} -@end itemize - -@code{apply-methods} - -@itemize @bullet -@item -@code{apply-method} -@end itemize - -@code{next-method} - -@itemize @bullet -@item -@code{no-next-method} -@end itemize - -@node Tutorial, Index, MOP Specification, Top -@chapter Tutorial -@include goops-tutorial.texi - -@node Index, Concept Index, Tutorial, Top -@chapter Index -@page -@node Concept Index, Function and Variable Index, Index, Top -@unnumberedsec Concept Index - -@printindex cp - -@node Function and Variable Index, , Concept Index, Top -@unnumberedsec Function and Variable Index - -@printindex fn - -@summarycontents -@contents -@bye diff --git a/doc/guile-tut.texi b/doc/guile-tut.texi dissimilarity index 100% index f2489cdaa..e69de29bb 100644 --- a/doc/guile-tut.texi +++ b/doc/guile-tut.texi @@ -1,1336 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename guile-tut.info -@settitle Guile Tutorial - -@include version-tutorial.texi - -@dircategory The Algorithmic Language Scheme -@direntry -* Guile Tutorial: (guile-tut). The Guile tutorial. -@end direntry - -@setchapternewpage off -@c Choices for setchapternewpage are {on,off,odd}. -@paragraphindent 2 -@c %**end of header - -@iftex -@finalout -@c DL: lose the egregious vertical whitespace, esp. around examples -@c but paras in @defun-like things don't have parindent -@parskip 4pt plus 1pt -@end iftex - -@titlepage -@title Guile Tutorial -@subtitle For use with Guile @value{VERSION} -@subtitle Last updated @value{UPDATED} -@author Mark Galassi -@author Cygnus Solutions and -@author Los Alamos National Laboratory -@author @email{rosalia@@nis.lanl.gov} - -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1997, 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. - -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 author. -@end titlepage - - -@ifinfo -@node Top -@top Guile Tutorial -@end ifinfo - -@ifinfo -This file gives a tutorial introductionto Guile. - -Copyright (C) 1997 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 author. -@end ifinfo - - -@menu -* Jump Start:: -* Introduction:: -* Using Guile to program in Scheme:: -* Guile in a Library:: -* Regular Expression Support:: -* UNIX System Programming:: -* Where to find more Guile/Scheme resources:: -* Concept Index:: -* Procedure and Macro Index:: -* Variable Index:: -* Type Index:: -@end menu - -@node Jump Start -@chapter Jump Start - -@noindent -Before giving an overview of Guile, I present some simple commands and -programs that you can type to get going immediately. - -Start by invoking the Guile interpreter (usually you do this by just -typing @code{guile}). Then type (or paste) the following expressions at -the prompt; the interpreter's response is preceded (in this manual) by -@result{}. - -@example - guile -@end example -@lisp -(+ 20 35) -@result{} 55 -(define (recursive-factorial n) - (if (= n 0) - 1 - (* n (recursive-factorial (- n 1))))) -(recursive-factorial 5) -@result{} 120 -(recursive-factorial 500) -@result{} 1220136825991110068701238785423046926253574342803192842192413588 - 3858453731538819976054964475022032818630136164771482035841633787 - 2207817720048078520515932928547790757193933060377296085908627042 - 9174547882424912726344305670173270769461062802310452644218878789 - 4657547771498634943677810376442740338273653974713864778784954384 - 8959553753799042324106127132698432774571554630997720278101456108 - 1188373709531016356324432987029563896628911658974769572087926928 - 8712817800702651745077684107196243903943225364226052349458501299 - 1857150124870696156814162535905669342381300885624924689156412677 - 5654481886506593847951775360894005745238940335798476363944905313 - 0623237490664450488246650759467358620746379251842004593696929810 - 2226397195259719094521782333175693458150855233282076282002340262 - 6907898342451712006207714640979456116127629145951237229913340169 - 5523638509428855920187274337951730145863575708283557801587354327 - 6888868012039988238470215146760544540766353598417443048012893831 - 3896881639487469658817504506926365338175055478128640000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000 - -@end lisp - -In this example we did some simple arithmetic @code{(+ 20 35)} and got -the answer @code{55}. Then we coded the classic (and rather wasteful) -factorial algorithm, and got a glimpse of Scheme's nice -@emph{bignumbers} by asking for the factorial of 1000. Then we quit -with @code{(quit)}. -@cindex bignumbers - -This is the most basic use of Guile: a simple Scheme interpreter. In -the rest of this tutorial I will show you how Guile has many facets: it -is also an @emph{extensible} interpreter (to which many features can be -easilly added) and an @emph{embeddable} interpreter (which can be -invoked from your C programs). - - -@node Introduction -@chapter Introduction - -@noindent -@dfn{Guile} (which can stand for @emph{GNU Ubiquitous Intelligent -Language Extension}) is the GNU extension language. It started out as -an embeddable Scheme interpreter, and has rapidly evolved into a -kitchen-sink package including a standalone Scheme interpreter, an -embeddable Scheme interpreter, several graphics options, other languages -that can be used along with Scheme (for now just @emph{ctax} and -@emph{Tcl}), and hooks for much more. - - -@menu -* What are scripting and extension languages:: -* History of Guile and its motivations:: -* How to characterize Guile:: -@end menu - -@node What are scripting and extension languages -@section What are scripting and extension languages -@cindex scripting languages -@cindex extension languages - -A @dfn{scripting language} is a programming language which serves as -glue between other system programs. In the UNIX world, the traditional -scripting language is the @emph{Bourne shell}, which allows many UNIX -commands to be executed in sequence, or in a pipeline. Traditional UNIX -commands are cleverly written to work well when put together in a -script. - -Other examples of UNIX scripting languages are AWK, Perl, Scsh (the -Scheme Shell: a Scheme interpreter enhanced to do good scripting), -Python, Tcl, Java @dots{} -@cindex scripting languages - examples - -UNIX programmers noticed, more than 25 years ago, that scripting -languages can do serious work, so the Bourne shell was written to have -variables, operators and control structures, just like a full-featured -programming language. -@cindex Bourne shell - -What scripting languages have, that traditional programming languages do -not, is the ability to easily run an external program (or a pipeline of -external programs) and use the returned values and output from that -program in useful ways. - -An @dfn{extension language} is a programming language interpreter -offered by an application program, so that users can write macros or -even full-fledged programs to extend the original application. -Extension languages have a C interface (it is usually C, but it could be -any other compiled language), and can be given access to the C data -structures. Likewise, there are C routines to access the extension -language data structures. - -Extension languages abound in the software world, even though the name -@emph{extension language} is seldom used. Examples are: -@cindex extension languages - examples - -@itemize @bullet -@item -Emacs Lisp, the language used to program and customize GNU Emacs. -@cindex Emacs Lisp - -@item -Tcl, John Ousterhout's general-purpose scripting and extension language. -@cindex Tcl - -@item -The Lotus 1-2-3 macro language (any spreadsheet macro language, -really). I mention this one first because it is a classic, even though -it is seldom used any more. -@cindex Lotus 1-2-3 - -@item -Other spreadsheet and database macro languages. - -@item -The Dominion empire-style game's @emph{exec} files. -@cindex Dominion - -@item -Any syntax for a ".*rc" file you might have used. Almost all programs -end up parsing some kind of startup or configuration file. The syntax -for those can get pretty involved, thus justifying calling them -"extension languages". The @emph{fvwm} window manager, for example, -parses a rather elaborate @file{.fvwmrc} file. - -@item -Brent Benson's libscheme.a, an embeddable Scheme interpreter. -@cindex Benson, Brent -@cindex libscheme - -@item -Guile, the GNU extension language, which is the subject of this -tutorial. - -@end itemize - -One lesson we can learn from looking at classical large software -applications is that "writers of large programs" always end up throwing -in some kind of parser for configuration or scripting. - -Of the examples listed above, Emacs Lisp, Tcl, Libscheme and Guile have -an important property: they are not added as an afterthought for a -specific application. They are general-purpose languages which a user -can learn (even in college courses) and then use to customize the -application program. - -This is a recent and (in my opinion) very exciting direction in -large-program software engineering: program designers can link in the -Guile or Tcl library from the very beginning, and tell their users "You -want to customize this program? Just use Scheme (or Tcl, or whatever -language), which you already know!" -@cindex large programs - - -@node History of Guile and its motivations -@section History of Guile and its motivations - -A few separate threads of events led to the development of Guile. - -In the fall of 1994, Richard Stallman, director of the GNU project, -posted an article with the subject "Why you should not use Tcl", in -which he argued that Tcl is inadequate as an extension language. This -generated a flurry of flames (available in the hypermail archive -(@url{http://www.utdallas.edu/acc/glv/Tcl/war/}) @strong{The Tcl War}). -@cindex Stallman, Richard -@cindex GNU project -@cindex Tcl - -The result was that Stallman then proposed his design for the GNU -Extension Language, first called GEL and then renamed Guile. The -discussion triggered by that article is also available in a hypermail -archive, @url{http://www.utdallas.edu/acc/glv/Tcl/war2/}. - -One interesting feature of this GNU Extension Language plan was that -users should have a @emph{choice} of languages to use in extending their -program. The basic language would be a slightly modified Scheme, and -translators would be written to convert other languages (like Tcl, -Python, Perl, C-like languages @dots{}) into Scheme. - -Tom Lord started working on this project immediately, taking Aubrey -Jaffer's small and portable implementation of Scheme, SCM, and making it -into an embeddable interpreter: callable from C and allowing new Scheme -procedures to be written in C. -@cindex Lord, Tom -@cindex Jaffer, Aubrey - -In the spring of 1995, the guile-ii snapshot was released. This made it -possible to start writing code in C and Scheme using the guile -facilities. - -The guile-iii snapshot was released the summer of 1995, and it had fixed -enough problems so that the access to Scheme data structures from C was -almost complete. - -After this, Cygnus Support added many features to Guile and finished -implementing others, so that Guile acquired thread support, a regular -expression matcher, a Tk interface, an interface to the SGI OpenGL -graphics system, an @emph{applet} formalism, and some other packages. -This was all in the Cygnus Guile r0.3 and r0.4 releases. -@cindex Cygnus Support - -Meanwhile, Tom Lord left the project after having produced a divergent -version of Guile: 1.0b2. The Free Software Foundation hired Jim Blandy -to coordinate Guile development. The FSF released its first version of -Guile in January 1997. In the future, many of the Cygnus packages will -be re-integrated into Guile. -@cindex Blandy, Jim -@cindex Free Software Foundation - - - -@node How to characterize Guile -@section How to characterize Guile - -I have already mentioned that Guile has become a kitchen sink package; -here you can see how Guile freely takes new commands and constructs from -the portable Scheme library @emph{slib}, the @emph{Tk} widget set, a -posix library (useful for UNIX systems programming), the regular -expression library @emph{rx}, and many more @dots{} -@cindex slib -@cindex Tk -@cindex POSIX -@c @cindex OpenGL -@cindex rx - -So Guile has many more primitive procedures available to it than those -specified in @ref{Standard Procedures, Revised(5) Report on the -Algorithmic Language Scheme, , r5rs, Revised(5) Report on the -Algorithmic Language Scheme}. On top of that, Guile will interpret -almost all standard Scheme programs. The only incompatible difference -between the basic Guile language and R5RS Scheme is that Guile is case -sensitive, whereas R5RS is case insensitive. We hope that few people -have written Scheme programs that depend on case insensitivity. -@cindex case sensitivity -@cindex Revised(5) Report on the Algorithmic Language Scheme -@cindex report on Scheme -@cindex Scheme language - report -@cindex Scheme language - definition - -Here is a possible view of the @emph{sum of the parts} in Guile: -@cindex extensions to standard Scheme -@cindex extensions to R5RS -@cindex Scheme extensions -@example -guile = standard Scheme (R5RS) - PLUS extensions to R5RS offered by SCM - PLUS some extra primitives offered by Guile (catch/throw) - PLUS portable Scheme library (SLIB) - PLUS embeddable Scheme interpreter library (libguile) - PLUS Tk toolkit - PLUS threads - PLUS Posix library -@c PLUS OpenGL library (mesa) -@c PLUS OpenGL toolkit (glut) - PLUS Regular expression library (rx) -@c PLUS Applet formalism - PLUS Tcl library -@end example - - -@node Using Guile to program in Scheme -@chapter Using Guile to program in Scheme -@cindex Scheme programming tutorial -@cindex tutorial on Scheme programming - -In this section I give a tutorial introduction to programming in Scheme, -with a slant toward the interesting things that can be done in Guile. - -@c Applets are so @emph{chic} that they get their own section, but this -This section will try to touch on many of the interesting and cool -aspects of Guile, showing you how new types of problems can be solved -with Guile. Note that using Guile as a library with @code{libguile.a} -is described in its own chapter (@pxref{Guile in a Library}). Also note -that some small examples are given in @ref{Jump Start}. - -To get started you need to know how to program in @dfn{Scheme} (a -dialect of LISP). Fortunately Scheme is a small, clean language and is -not hard to learn. It is also used in many undergraduate courses to -introduce computer programming. -@cindex lisp dialects - -I will not try to teach you Scheme here (although you might end up -learning by example), since there are many good books on the subject, -listed in @ref{Where to find more Guile/Scheme resources}. @footnote{To -get started, look at the books @cite{Simply Scheme} and @cite{The Little -Schemer} from that list.} - - -@subsection Hello World -@cindex hello world - -Our first program is the typical Scheme "hello world" program. Put the -following code in a file called @code{hello.scm} (this can be find in -@file{examples/scheme/hello.scm}). - -@smalllisp -#!/usr/local/bin/guile -s -!# - -(display "hello world") -(newline) -@end smalllisp - -Then run guile on it. One way to do so is to start up guile and load -this file: - -@smallexample - @kbd{guile} -guile> @kbd{(load "hello")} -@end smallexample - -Another way is to make the file executable and execute it directly. -Notice how Guile recognizes a @code{-s} option which tells it to run a -script and then exit. Guile also has a new type of block comment -enclosed by @code{#!} and @code{!#}, so that you can make executable -Scheme scripts with the standard UNIX @code{#!} mechanism. - -In the given example, the first line is used to invoke the Guile -interpreter (make sure you correct the path if you installed Guile in -something other than /usr/local/bin). Once Guile is invoked on this -file, it will understand that the first line is a comment. The comment -is then terminated with @code{!#} on the second line so as to not -interfere with the execution mechanism. - - -@subsection A bunch of operations in Scheme - -Here is some code you can type at the @code{guile>} prompt to see some -of the Scheme data types at work (mostly lists and vectors). I have -inserted brief comments @emph{before} each line of code explaining what -happens. - -@smalllisp -;; @r{make a list and bind it to the symbol @code{ls}} -guile> @kbd{(define ls (list 1 2 3 4 5 6 7))} - @result{} -;; @r{display the list} -guile> @kbd{ls} - @result{(1 2 3 4 5 6 7)} -;; @r{ask if @code{ls} is a vector; @code{#f} means it is not} -guile> @kbd{(vector? ls)} - @result{#f} -;; @r{ask if @code{ls} is a list; @code{#t} means it is} -guile> @kbd{(list? ls)} - @result{#t} -;; @r{ask for the length of @code{ls}} -guile> @kbd{(length ls)} - @result{7} -;; @r{pick out the first element of the list} -guile> @kbd{(car ls)} - @result{1} -;; @r{pick the rest of the list without the first element} -guile> @kbd{(cdr ls)} - @result{(2 3 4 5 6 7} -;; @r{this should pick out the 3rd element of the list} -guile> @kbd{(car (cdr (cdr ls)))} - @result{3} -;; @r{a shorthand for doing the same thing} -guile> @kbd{(caddr ls)} - @result{3} -;; @r{append the given list onto @code{ls}, print the result} -;; @r{@strong{NOTE:} the original list @code{ls} is @emph{not} modified} -guile> @kbd{(append ls (list 8 9 10))} - @result{(1 2 3 4 5 6 7 8 9 10)} -guile> @kbd{(reverse ls)} - @result{(10 9 8 7 6 5 4 3 2 1)} -;; @r{ask if 12 is in the list --- it obviously is not} -guile> @kbd{(memq 12 ls)} - @result{#f} -;; @r{ask if 4 is in the list --- returns the list from 4 on.} -;; @r{Notice that the result will behave as true in conditionals} -guile> @kbd{(memq 4 ls)} - @result{(4 5 6 7)} -;; @r{an @code{if} statement using the aforementioned result} -guile> @kbd{(if (memq 4 ls) - (display "hey, it's true!\n") - (display "dude, it's false\n"))} - @print{hey, it's true!} - @result{} -guile> @kbd{(if (memq 12 ls) - (display "hey, it's true!\n") - (display "dude, it's false\n"))} - @print{dude, it's false} - @result{} -guile> @kbd{(memq 4 (reverse ls))} - @result{(4 3 2 1)} -;; @r{make a smaller list @code{ls2} to work with} -guile> @kbd{(define ls2 (list 2 3 4))} -;; @r{make a list in which the function @code{sin} has been} -;; @r{applied to all elements of @code{ls2}} -guile> @kbd{(map sin ls2)} - @result{(0.909297426825682 0.141120008059867 -0.756802495307928)} -;; @r{make a list in which the squaring function has been} -;; @r{applied to all elements of @code{ls}} -guile> @kbd{(map (lambda (n) (expt n n)) ls)} - @result{(1 4 27 256 3125 46656 823543)} -@end smalllisp - -@smalllisp -;; @r{make a vector and bind it to the symbol @code{v}} -guile> @kbd{(define v #(1 2 3 4 5 6 7))} -guile> @kbd{v} - @result{#(1 2 3 4 5 6 7)} -guile> @kbd{(vector? v)} - @result{#t} -guile> @kbd{(list? v)} - @result{#f} -guile> @kbd{(vector-length v)} - @result{7} -;; @r{vector-ref allows you to pick out elements by index} -guile> @kbd{(vector-ref v 2)} - @result{3} -;; @r{play around with the vector: make it into a list, reverse} -;; @r{the list, go back to a vector and take the second element} -guile> @kbd{(vector-ref (list->vector (reverse (vector->list v))) 2)} - @result{5} -;; @r{this demonstrates that the entries in a vector do not have} -;; @r{to be of uniform type} -guile> @kbd{(vector-set! v 4 "hi there")} - @result{"hi there"} -guile> @kbd{v} - @result{#(1 2 3 4 "hi there" 6 7)} -@end smalllisp - - -@subsection Using recursion to process lists -@cindex recursion -@cindex list processing - -Here are some typical examples of using recursion to process a list. - -@smalllisp -;; @r{this is a rather trivial way of reversing a list} -(define (my-reverse l) - (if (null? l) - l - (append (my-reverse (cdr l)) (list (car l))))) -(my-reverse '(27 32 33 40)) -@result{(40 33 32 27)} -@end smalllisp - - -@subsection Processing matrices - -Suppose you have a matrix represented as a list of lists: - -@smalllisp -(define m - (list - (list 7 2 1 3 2 8 5 3 6) - (list 4 1 1 1 3 8 9 8 1) - (list 5 5 4 8 1 8 2 2 4))) -@end smalllisp - -Then you could apply a certain function to each element of the matrix in -the following manner: -@smalllisp -;; @r{apply the function func to the matrix m element-by-element;} -;; @r{return a matrix with the result.} -(define (process-matrix m func) - (map (lambda (l) - (map func l)) - m)) -@end smalllisp -Notice that I have used the Scheme @code{map} procedure because I am -interested in the matrix that results from the application of -@code{func}, rather than in the side effects associated with applying -@code{func}. - -This could be invoked with @code{(process-matrix m sin)} or -@code{(process-matrix m (lambda (x) (* x x)))}; for example: - -@smalllisp -(process-matrix m (lambda (x) (* x x))) -@result{((49 4 1 9 4 64 25 9 36) (16 1 1 1 9 64 81 64 1) (25 25 16 64 1 64 4 4 16))} -@end smalllisp - -To print a representation of the matrix, we could define a generalized -routine: -@smalllisp -;; @r{proc is a procedure to represent the single element,} -;; @r{row-proc is a procedure that is invoked after each row.} -;; @r{Example: proc could be (lambda (x) (begin (display x) (display " ")))} -;; @r{and row-proc could be (lambda (l) (display "\n"))} -(define (represent-matrix m proc row-proc) - (for-each (lambda (l) - (begin - (for-each proc l) - (row-proc l))) - m)) -@end smalllisp -@findex represent-matrix - -And then invoke it with -@smalllisp -(represent-matrix m - (lambda (x) (begin (display x) (display " "))) - (lambda (l) (begin (display "\n")))) -@print{7 2 1 3 2 8 5 3 6} -@print{4 1 1 1 3 8 9 8 1} -@print{5 5 4 8 1 8 2 2 4} -@end smalllisp - -@cindex objects - -Now we write a helper routine that uses Scheme @dfn{closures} to make -objects with state that then receive messages to draw little squares. -@cindex closures -@cindex syntactic closures - -But let us take it one step at a time. I will start by showing you a -simple example of object in Scheme. The object I make here represents a -cell, which could be a cell in a matrix. The cell responds to commands -to draw itself, to return the next cell, and so forth. @emph{Guile does -not currently have a Tk interface, so I will leave the hooks for -graphical rendering. In a future release of Guile I will add graphical -rendering messages to the cell object.} - -@smallexample -;; @r{cell-object.scm: routines for creating and manipulating cell objects} - -;; @r{(the-x, the-y) is the initial position of the cell.} -;; @r{the-color is a string representing a color; must be something Tk can grok.} -;; @r{square-size is the size of the square that gets drawn.} -;; @r{(sizex, sizey) is the size of the matrix.} -(define (MAKE-CELL the-x the-y the-color square-size sizex sizey) - (define (get-x) the-x) - (define (get-y) the-y) - - (define (set-x! new-x) - (set! the-x new-x) - the-x) - (define (set-y! new-y) - (set! the-y new-y) - the-y) - (define (get-color) the-color) - (define (set-color! new-color) - (set! the-color new-color) - the-color) - (define (next!) - (set! the-x (+ the-x 1)) - (if (>= the-x sizex) - (begin - (set! the-x 0) - (set! the-y (+ the-y 1)))) - (if (>= the-y sizey) - (begin - (display "CELL next!: value of y is too big; not changing it\n") - (set! the-y (- the-y 1)))) - (cons the-x the-y)) - (define (draw) - (let* ((x0 (* the-x square-size)) - (y0 (* the-y square-size)) - (x1 (+ x0 square-size)) - (y1 (+ y0 square-size))) - (display "I should draw a ") - (display the-color) - (display " rectangle with corners at ") - (display x0) (display y0) (display x1) (display y1) - )) - - ;; self is the dispatch procedure - (define (self message) - (case message - ((x) get-x) - ((y) get-y) - ((set-x!) set-x!) - ((set-y!) set-y!) - ((color) get-color) - ((set-color!) set-color!) - ((next!) next!) - ((draw) draw) - (else (error "CELL: Unknown message -> " message)))) - ;; and now return the dispatch procedure - self - ) -@end smallexample -@cindex cell-object -@findex MAKE-CELL - -What does this procedure do? It returns another procedure -(@code{self}) which receives a message (x, y, set-x!, set-y!, @dots{}) -and takes an action to return or modify its state. The state consists -of the values of variables @code{the-x}, @code{the-y}, @code{the-color} -and so forth. - -Here are some examples of how to use MAKE-CELL and the cell object it -creates: -@smallexample -(define c (MAKE-CELL 0 0 "red" 10 7 9)) - -;; @r{retrieve the x and y coordinates} -((c 'x)) -@result{0} -((c 'y)) -@result{0} -;; @r{change the x coordinate} -((c 'set-x!) 5) -@result{5} -((c 'x)) -@result{5} -;; @r{change the color} -((c 'color)) -@result{"red"} -((c 'set-color!) "green") -@result{"green"} -((c 'color)) -@result{"green"} -;; @r{now use the next! message to move to the next cell} -((c 'next!)) -@result{(6 . 0)} -((c 'x)) -@result{6} -((c 'y)) -@result{0} -;; @r{now make things wrap around} -((c 'next!)) -@result{(0 . 1)} -((c 'next!)) -@result{(1 . 1)} -((c 'next!)) -@result{(2 . 1)} -((c 'x)) -@result{2} -((c 'y)) -@result{1} -@end smallexample - -You will notice that expressions like @code{(c 'next)} return procedures -that do the job, so we have to use extra parentheses to make the job -happen. This syntax is rather awkward; one way around it is to define a -@code{send} procedure: - -@smallexample -;; @r{send makes object syntax a bit easier; instead of saying} -;; @r{ ((my-cell 'set-x!) 4)} -;; @r{you can say} -;; @r{ (send my-cell 'set-x! 4)} -(define (send obj . args) - (let ((first-eval (apply obj (list (car args))))) - (if (null? (cdr args)) - (first-eval) - (apply first-eval (cdr args))))) -@end smallexample -@findex send - -You can see that @code{send} passes the message to the object, making -sure that things are evaluated the proper number of times. You can now -type: - -@smallexample -(define c2 (MAKE-CELL 0 0 "red" 10 7 9)) -(send c2 'x) -@result{0} -(send c2 'set-x! 5) -@result{5} -(send c2 'color) -@result{"red"} -(send c2 'set-color! "green") -@result{"green"} -(send c2 'next!) -@result{(1 . 0)} -(send c2 'x) -@result{1} -(send c2 'y) -@result{0} -@end smallexample - -@cindex object-based programming -@cindex object-oriented programming - -This is the simplest way of implementing objects in Scheme, but it does -not really allow for full @emph{object-oriented programming} (for -example, there is no inheritance). But it is useful for -@emph{object-based programming}. - -Guile comes with a couple more complete object-oriented extensions to -Scheme: these are part of slib (@pxref{Object, , , slib, SLIB: the -portable Scheme library} and @pxref{Yasos, , , slib, SLIB: the portable -Scheme library}). - -@node Guile in a Library -@chapter Guile in a Library - -@iftex -@nobreak -@end iftex -In the previous chapters Guile was used to write programs entirely in -Scheme, and no C code was seen; but I have been claiming @emph{ad -nauseam} that Guile is an @emph{extension} language. Here we see how -that is done, and how that can be useful. -@cindex libguile -@cindex extending C programs - - -@menu -* Two world views:: -* What is libguile:: -* How to get started with libguile:: -* More interesting programming with libguile:: -* Further examples:: -@end menu - -@node Two world views -@section Two world views -@cindex master world - -In this manual, I usually jump into examples and explain them as you -type in the code; here I will digress and ramble for a few paragraphs to -set some concepts straight, and then let you type (or paste) in fun -examples. - -In 1995, I implemented a large program, @dfn{Gnudl}, using Guile quite -extensively. In the design phase of Gnudl, I found I had to make a -choice: should the fundamental data structures be C or Scheme data -structures? -@cindex gnudl -@cindex GNU Data Language -@cindex Galassi, Mark - -Guile allows C to see its data structures (scalar types, lists, vectors, -strings @dots{}). C also allows Guile to see its data structures. As a -large program designer, you have to decide which of those capabilities -to use. You have two main choices: - -@enumerate 1 -@item -You can write your software mostly in Scheme. In this case, your C -software will mostly parse the Scheme code with Guile calls, and provide -some new primitive procedures to be used by Scheme. This is what Gnudl -does. - -@item -You can write your software mostly in C, occasionally allowing Scheme -code to be parsed by Guile, either to allow the user to modify data -structures, or to parse a configuration file, @dots{} -@end enumerate - -Mixing the two approaches seems unwise: the overall layout would be -confusing. But who knows? There might be problems that are best solved -by a hybrid approach. Please let me know if you think of such a -problem. - -If you use the former approach, we will say that the @dfn{master world} -is Scheme, and the C routines serve Scheme and access Scheme data -structures. In the latter case, the master world is C, and Scheme -routines serve the C code and access C data structures. - -In both approaches the @code{libguile.a} library is the same, but a -predominantly different set of routines will be used. When we go -through examples of libguile use, we will point out which is the master -world in order to clarify these two approaches. - - -@node What is libguile -@section What is libguile -@cindex libguile -@cindex gh interface -@cindex scm interface - -@dfn{Libguile} is the library which allows C programs to start a Scheme -interpreter and execute Scheme code. There are also facilities in -libguile to make C data structures available to Scheme, and vice versa. - -The interface provided by the libguile C library is somewhat specific to -the implementation of the Scheme interpreter. This low-level libguile -interface is usually referred to as the @code{scm_} interface, since its -public calls (API) all have the @code{scm_} prefix. - -There is also a higher-level libguile interface, which is usually -referred to as the @code{gh_} interface (libGuile High). Its public -calls all have the @code{gh_} prefix. The @code{gh_} library interface -is designed to hide the implementation details, thus making it easier to -assimilate and portable to other underlying Scheme implementations. - -People extending Guile by adding bindings to C libraries (like OpenGL or -Rx) are encouraged to use the @code{gh_} interface, so their work will -be portable to other Scheme systems. The @code{gh_} interface should be -more stable, because it is simpler. - -The @code{scm_} interface is necessary if you want to poke into the -innards of Scheme data structures, or do anything else that is not -offered by the @code{gh_} interface. It is not covered in this -tutorial, but is covered extensively in @ref{Scheme data representation, -Guile Reference Manual, guile-ref, Guile Reference Manual}. - -This chapter gives a gentle introduction to the @code{gh_} interface, -presenting some @emph{hello world}-style programs which I wrote while -teaching myself to use libguile. -@cindex hello world - -The @cite{Guile Programmer's Manual} gives more examples of programs -written using libguile, illustrating diverse applications. You can also -consult my @emph{Gnudl} documentation at -@url{http://nis-www.lanl.gov/~rosalia/mydocs/} to see a large scale -project that uses C and Scheme code together. - - -@node How to get started with libguile -@section How to get started with libguile -@cindex learn0 - -Here is an elementary first program, @code{learn0}, to get going with -libguile. The program (which uses Scheme as a master world) is in a -single source file, @code{learn0.c}: - -@smallexample -/* @r{test the new libgh.a (Guile High-level library) with a trivial - program} */ - -#include - -#include - -void main_prog(int argc, char *argv[]); - -main(int argc, char *argv[]) -@{ - gh_enter(argc, argv, main_prog); -@} - -void main_prog(int argc, char *argv[]) -@{ - int done; - char input_str[200]; - - gh_eval_str("(display \"hello Guile\")"); - gh_eval_str("(newline)"); - - /* @r{for fun, evaluate some simple Scheme expressions here} */ - gh_eval_str("(define (square x) (* x x))"); - gh_eval_str("(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))"); - gh_eval_str("(square 9)"); - - /* @r{now sit in a Scheme eval loop: I input the expressions, have - Guile evaluate them, and then get another expression.} */ - done = 0; - fputs("learn0> ", stdout); - while (fgets(input_str, 199, stdin) != NULL) @{ - gh_eval_str(input_str); - fputs("\nlearn0> ", stdout); - @} - - exit(0); -@} -@end smallexample - -If you name this program @code{learn0.c}, it can now be compiled with: -@smallexample -gcc -g -c learn0.c -o learn0.o -gcc -o learn0 learn0.o -lguile -lm -@end smallexample - -@c @emph{NOTE: If you are in the Guile development tree, you can simply do -@c ``cd doc/examples/c; make; ./learn0''.} - -The program is simple: it creates a Scheme interpreter, passes a couple -of strings to it that define new Scheme functions @code{square} and -@code{factorial}, and then a couple of strings that invoke those -functions. - -It then goes into a read-eval-print-loop (REPL), so you could type -one-line Scheme expressions to it and have them evaluated. For example: -@smallexample - ./learn0 -hello Guile -learn0> (display (sin 1.3)) -963.558185417193e-3 -learn0> (display (fact 10)) -3628800 -learn0> (quit) - -@end smallexample - -You should notice the key steps involved in this @code{learn0} program: - -@cartouche -@enumerate -@item -@code{#include } -@item -You need to invoke the initialization routine @code{gh_enter()}. This -starts up a Scheme interpreter, handling many implementation-specific -details. -@item -Your main() function should be almost empty: the real main program goes -in a separate function main_prog() which is passed to gh_enter(). This -rather arcane convention is due to the way Guile's garbage collector -works: the whole program has to run in the dynamic context of -@code{gh_enter()}. -@item -You pass strings to the Scheme interpreter with the @code{gh_eval_str()} -routine. -@item -You link your program with @code{-lguile}. -@end enumerate -@end cartouche - - -@node More interesting programming with libguile -@section More interesting programming with libguile -@cindex learn1 -@cindex callback -@cindex builtin functions - -The @code{learn0} program shows how you can invoke Scheme commands from -a C program. This is not such a great achievement: the same could have -been done by opening a pipe to SCM or any other Scheme interpreter. - -A true extension language must allow @dfn{callbacks}. Callbacks allow -you to write C routines that can be invoked as Scheme procedures, thus -adding new primitive procedures to Scheme. This also means that a -Scheme procedure can modify a C data structure. - -Guile allows you to define new Scheme procedures in C, and provides a -mechanism to go back and forth between C and Scheme data types. - -Here is a second program, @code{learn1}, which demonstrates these -features. It is split into three source files: @code{learn1.c}, -@code{c_builtins.h} and @code{c_builtins.c}. I am including the code -here. -@c , but you might just want to look at the online source code and the -@c Makefile.am that come with Guile in the -@c @file{doc/examples/c} directory. - -Notice that @code{learn1} uses a Scheme master world, and the C routines -in @code{c_builtins.c} are simply adding new primitives to Scheme. - -@menu -* learn1.c:: -* c_builtins.h:: -* c_builtins.c:: -* What learn1 is doing:: -* Compiling and running learn1:: -@end menu - -@node learn1.c -@subsection learn1.c - -Here is @file{learn1.c}: -@smallexample -#include - -#include - -#include "c_builtins.h" - -void main_prog(int argc, char *argv[]); - -main(int argc, char *argv[]) -@{ - gh_enter(argc, argv, main_prog); -@} - -void main_prog(int argc, char *argv[]) -@{ - char input_str[200]; /* @r{ugly hack: assume strlen(line) < 200} */ - int done; - - /* @r{for fun, evaluate some simple Scheme expressions here} */ - gh_eval_str("(define (square x) (* x x))"); - gh_eval_str("(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))"); - gh_eval_str("(square 9)"); - gh_eval_str("(fact 100)"); - - /* @r{now try to define some new builtins, coded in C, so that they are - available in Scheme.} */ - gh_new_procedure1_0("c-factorial", c_factorial); - gh_new_procedure1_0("c-sin", c_sin); - gh_new_procedure1_0("v-t", vector_test); - - /* @r{now sit in a Scheme eval loop: I input the expressions, have - Guile evaluate them, and then get another expression.} */ - done = 0; - fputs("learn1> ", stdout); - while (!done) @{ - if (gets(input_str) == NULL) @{ - done = 1; - @} else @{ - gh_eval_str(input_str); - fputs("learn1> ", stdout); - @} - @} - - exit(0); -@} -@end smallexample - -@node c_builtins.h -@subsection c_builtins.h - -Here is @file{c_builtins.h}: -@smallexample -/* @r{builtin function prototypes} */ - -#include - -SCM c_factorial(SCM n); -SCM c_sin(SCM n); -SCM vector_test(SCM s_length); -@end smallexample - -@node c_builtins.c -@subsection c_builtins.c - -Here is @file{c_builtins.c}: -@smallexample -#include -#include - -#include - -#include "c_builtins.h" - -/* @r{this is a factorial routine in C, made to be callable by Scheme} */ -SCM c_factorial(SCM s_n) -@{ - int i; - unsigned long result = 1, n; - - n = gh_scm2ulong(s_n); - - gh_defer_ints(); - for (i = 1; i <= n; ++i) @{ - result = result*i; - @} - gh_allow_ints(); - return gh_ulong2scm(result); -@} - -/* @r{a sin routine in C, callable from Scheme. it is named c_sin() to - distinguish it from the default Scheme sin function} */ -SCM c_sin(SCM s_x) -@{ - double x = gh_scm2double(s_x); - - return gh_double2scm(sin(x)); -@} - -/* @r{play around with vectors in Guile: this routine creates a vector of - the given length, initializes it all to zero except element 2 which - is set to 1.9.} */ -SCM vector_test(SCM s_length) -@{ - SCM xvec; - - c_length = gh_scm2ulong(s_length); - printf("requested length for vector: %ld\n", gh_scm2ulong(s_length)); - - /* create a vector */ - xvec = gh_make_vector(s_length, gh_double2scm(0.0)); - /* set the second element in it */ - gh_vector_set_x(xvec, gh_int2scm(2), gh_double2scm(1.9)); - - return xvec; -@} -@end smallexample - -@node What learn1 is doing -@subsection What learn1 is doing -@cindex registering callbacks -@cindex registering C functions -@cindex primitive procedures - -If you compare learn1 to learn0, you will find that learn1 uses a new -Guile construct: the function @code{gh_new_procedure()}, and its -siblings: - -@smallexample - /* @r{now try to define some new builtins, coded in C, so that they are - available in Scheme.} */ - gh_new_procedure1_0("c-factorial", c_factorial); - gh_new_procedure1_0("c-sin", c_sin); - gh_new_procedure1_0("v-t", vector_test); -@end smallexample - -It is clear that @code{gh_new_procedure()} adds a new builtin -routine written in C which can be invoked from Scheme. We can now -revise our checklist for programming with libguile, so it includes -adding callbacks. -@cindex libguile - step by step - -@cartouche -@enumerate -@item -@code{#include } -@item -You need to invoke the initialization routine @code{gh_enter()}. This -starts up a Scheme interpreter, handling many details. -@item -Your main() function should be almost empty: the real main program goes -in a separate function main_prog() which is passed to gh_enter(). This -rather arcane convention is due to the way Guile's garbage collector -works: the whole program has to run in the dynamic context of -@code{gh_enter()}. -@item -You pass strings to the Scheme interpreter with the @code{gh_eval_str()} -routine. -@item -@strong{[new]} You can now define new builtin Scheme functions; -i.e. define new builtin Scheme functions, with the -@code{gh_new_procedure()} routine. -@item -You pass strings to the Scheme interpreter with the -@code{gh_eval_str()} routine. -@item -You link your program with @code{-lguile}. -@end enumerate -@end cartouche - -I breezed by the issue of how to write your C routines that are -registered to be called from Scheme. This is non-trivial, and is -discussed at length in the @cite{Guile Programmer's Manual}. - - -@node Compiling and running learn1 -@subsection Compiling and running learn1 - -@smallexample -gcc -g -c learn1.c -o learn1.o -gcc -g -c c_builtins.c -o c_builtins.o -gcc -o learn1 learn1.o c_builtins.o -lguile -lm -@end smallexample - -If you run @code{learn1}, it will prompt you for a one-line Scheme -expression, just as @code{learn0} did. The difference is that you can -use the new C builtin procedures (@code{c-factorial}, @code{c-sin}, -@code{v-t}). - -@smallexample - ./learn1 -welcome to Guile -hello Guile -learn1> (display (c-factorial 6)) -720 -learn1> (display (c-factorial 20)) -2192834560 -learn1> (display (c-factorial 100)) -0 -learn1> (display (c-sin 1.5)) -0.997494986604054 -learn1> (display (v-t 10)) -requested length for vector: 10 -#(0.0 0.0 1.9 0.0 0.0 0.0 0.0 0.0 0.0 0.0) -learn1> (display (v-t 15)) -requested length for vector: 15 -#(0.0 0.0 1.9 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0) -learn1> (quit) - -@end smallexample - -As you see, taking @code{(c-factorial 100)} does not use bignumbers and -returns a bogus answer. - -@node Further examples -@section Further examples - -Further ``idealized'' examples are included in the @code{doc/examples/c} -distribution. They include programs to: - -@c [FIXME: still have to write some of these; then I will revise the list.] - -@itemize @bullet -@item -Parse a startup file (C is the master world). -@item -Set up initial conditions for an n-body simulation (C is the master -world). -@item -Implement a Scheme interpreter with all of Guile's goodies, @emph{plus} -the readline library @emph{and} a fast Fourier transform routine -provided in C (Scheme is the master world). -@end itemize - -@node Regular Expression Support -@chapter Regular Expression Support - -@node UNIX System Programming -@chapter UNIX System Programming - -@node Where to find more Guile/Scheme resources -@chapter Where to find more Guile/Scheme resources - - -@node Concept Index -@unnumbered Concept Index - -@printindex cp - -@node Procedure and Macro Index -@unnumbered Procedure and Macro Index - -This is an alphabetical list of all the procedures and macros in Dominion. - -@printindex fn - -@node Variable Index -@unnumbered Variable Index - -This is an alphabetical list of the major global variables in Dominion. - -@printindex vr - -@node Type Index -@unnumbered Type Index - -This is an alphabetical list of the major data structures in Dominion. - -@printindex tp - -@contents - -@bye diff --git a/doc/guile.texi b/doc/guile.texi index 3571a51a9..a163dfaad 100644 --- a/doc/guile.texi +++ b/doc/guile.texi @@ -3,90 +3,30 @@ @c %**start of header @setfilename guile.info @settitle Guile Reference Manual +@set guile @c %**end of header -@c Neil's notes: - -@c This file started life as a copy of guile-ref.texi, which I then -@c modified to reflect the organization described in -@c sources/jimb-org.texi. - -@c Jim's notes: - -@c Remember to use "subr" whereever appropriate. -@c Actually, use "primitive", not "subr." Why coin a new term? +@c Notes: (distilled from Jim's and Tim's notes, and kept up to date) +@c +@c Remember to use "primitive" whereever appropriate. @c FIXME: gotta change existing "subr" uses to "Primitive". -@c In my text for the Guile snarfer, I've used the term "subr" to denote -@c a C function made available to the Scheme world as a function. This -@c terminology is weird, but consistent with the function names and also -@c with Emacs Lisp, which I assume takes Maclisp's lead. - -@c Tim's notes: - +@c [JimB:] In my text for the Guile snarfer, I've used the term "subr" +@c to denote a C function made available to the Scheme world as a +@c function. This terminology is weird, but consistent with the +@c function names and also with Emacs Lisp, which I assume takes +@c Maclisp's lead. +@c @c When adding a new function to the Guile manual, please document @c it with @deffn as one of `primitive', `procedure', or `syntax'. @c -@c The following Guile primitives are not documented. We have a lot -@c of work to do. -@c -@c arbiters.c: make-arbiter, try-arbiter, release-arbiter -@c async.c: async, async-mark, system-async, system-async-mark, -@c run-asyncs, noop, set-tick-rate, set-switch-rate, -@c unmask-signals, mask-signals -@c backtrace.c: backtrace, display-error, display-application, -@c display-backtrace -@c chars.c: char-is-both? -@c debug.c: single-step, memoized?, unmemoize, memoized-environment, -@c procedure-name, procedure-source, procedure-environment, -@c local-eval, debug-object?, debug-hang -@c dynl.c: c-registered-modules, c-clear-registered-modules, -@c dynamic-link, dynamic-object?, dynamic-unlink, dynamic-func, -@c dynamic-call, dynamic-args-call -@c eval.c: procedure->syntax, procedure->macro, procedure->memoizing-macro, -@c macro-name, macro-transformer -@c fluids.c: make-fluid, fluid?, fluid-ref, fluid-set, with-fluids* -@c gc.c: map-free-list, unhash-name -@c kw.c: make-keyword-from-dash-symbol -@c net_db.c: sethost, setnet, setproto, setserv -@c print.c: current-pstate -@c procs.c: make-cclo, closure?, thunk? -@c read.c: read-hash-extend -@c readline.c: readline, add-history -@c srcprop.c: source-properties, set-source-properties!, -@c source-property, set-source-property! -@c stacks.c: make-stack, stack-ref, stack-length, -@c frame?, last-stack-frame, frame-number, frame-source, -@c frame-procedure, frame-arguments, frame-previous, frame-next, -@c frame-real?, frame-procedure?, frame-evaluating-args?, -@c frame-overflow -@c struct.c: struct-vtable-tag -@c symbols.c: builtin-weak-bindings -@c tag.c: tag -@c threads.c: single-active-thread?, yield, call-with-new-thread, -@c make-condition-variable, wait-condition-variable, -@c signal-condition-variable -@c throw.c: lazy-catch, vector-set-length! -@c unif.c: uniform-vector-ref, uniform-array-set1! -@c variable.c: make-variable, make-undefined-variable, variable?, -@c variable-ref, variable-set!, builtin-variable, variable-bound? -@c weaks.c: make-weak-vector, weak-vector, list->weak-vector, -@c weak-vector? make-weak-key-hash-table, -@c make-weak-value-hash-table, make-doubly-weak-hash-table, -@c weak-key-hash-table?, weak-value-hash-table?, -@c doubly-weak-hash-table? -@c -@c If you have worked with some of these concepts, implemented them, -@c or just happen to know what they do, please write up a little -@c explanation -- it would be a big help. Alternatively, if you -@c know of a great reason why some of these should *not* go in the -@c manual, please let me know. -@c -@c The following functions are currently left undocumented for various reasons. -@c * should be documented in a section on debugging or Guile internals: -@c ports.c: pt-size, pt-member -@c eval.c: apply:nconc2last -@c -@c Thanks. -twp +@c For a list of Guile primitives that are not yet incorporated into the +@c reference manual, see the file `new-docstrings.texi', which holds all +@c the docstrings snarfed from the libguile C sources for primitives +@c that are not in the reference manual. If you have worked with some +@c of these concepts, implemented them, or just happen to know what they +@c do, please write up a little explanation -- it would be a big help. +@c Alternatively, if you know of a great reason why some of these should +@c *not* go in the manual, please let me know. @c Define indices that are used in the Guile Scheme part of the @c reference manual to group stuff according to whether it is R5RS or a @@ -140,24 +80,10 @@ by the Free Software Foundation. @sp 10 @comment The title is printed in a large font. @title Guile Reference Manual -@subtitle $Id: guile.texi,v 1.6 2001-04-28 09:00:31 ossau Exp $ +@subtitle $Id: guile.texi,v 1.7 2001-04-28 23:38:52 ossau Exp $ @subtitle For use with Guile @value{VERSION} -@author Mark Galassi -@author Cygnus Solution and Los Alamos National Laboratory -@author @email{rosalia@@cygnus.com} -@author -@author Jim Blandy -@author Free Software Foundation and MIT AI Lab -@author @email{jimb@@red-bean.com} -@author -@author Gary Houston -@author @email{ghouston@@arglist.com} -@author -@author Tim Pierce -@author @email{twp@@skepsis.com} -@author -@author Neil Jerram -@author @email{neil@@ossau.uklinux.net} +@include AUTHORS + @c The following two commands start the copyright page. @page @vskip 0pt plus 1filll @@ -207,6 +133,7 @@ Preface * Guile License:: Conditions for copying and using Guile. * Manual Layout:: How to read the rest of this manual. +* Manual Conventions:: Conventional terminology. Part I: Introduction to Guile -- 2.20.1