diff options
Diffstat (limited to 'doc/ref')
45 files changed, 7440 insertions, 442 deletions
diff --git a/doc/ref/.gitignore b/doc/ref/.gitignore index fc69e3188..c76e2e4af 100644 --- a/doc/ref/.gitignore +++ b/doc/ref/.gitignore @@ -1,2 +1,3 @@ autoconf-macros.texi lib-version.texi +effective-version.texi diff --git a/doc/ref/ChangeLog-goops-2008 b/doc/ref/ChangeLog-goops-2008 new file mode 100644 index 000000000..a5a637d7b --- /dev/null +++ b/doc/ref/ChangeLog-goops-2008 @@ -0,0 +1,76 @@ +2008-02-06 Neil Jerram <neil@ossau.uklinux.net> + + * goops-tutorial.texi (Next-method): Minor improvements to the + text. + +2006-09-28 Neil Jerram <neil@ossau.uklinux.net> + + * goops.texi (Slot Options): Added example from Ludovic Courtès + about difference between init-value, -form and -thunk. + +2006-04-21 Kevin Ryde <user42@zip.com.au> + + * hierarchy.pdf: New file, converted from hierarchy.eps using + epstopdf, to let "make pdf" work. + * Makefile.am: (goops_TEXINFOS): Add it. + +2006-03-08 Ludovic Courtès <ludovic.courtes@laas.fr> + + * goops.texi (Slot Options): Note init-value is shared. + +2006-02-06 Marius Vollmer <mvo@zagadka.de> + + * goops.texi (Basic Generic Function Creation): Added blurb about + merge-generics duplicates handler from NEWS. + +2004-06-28 Marius Vollmer <marius.vollmer@uni-dortmund.de> + + * Makefile.am: Removed home-grown code for HTML generation. + Automake does it for us now. + (goops_TEXINFOS): Added hierarchy.png + + * hierarchy.png: New file. + +2004-05-19 Kevin Ryde <user42@zip.com.au> + + * Makefile.am (CLEANFILES): Remove, goops.tmp goops.cps cleaned by + automake these days. + +2003-04-17 Mikael Djurfeldt <djurfeldt@nada.kth.se> + + * goops.texi (Object Comparisons): Removed object-eqv? and + object-equal? and added eqv?, equal? and =. + +2003-01-10 Mikael Djurfeldt <djurfeldt@nada.kth.se> + + * goops.texi (Class Redefinition): Clarifications; Removed + mentioning of change-object-class. + +2002-11-07 Neil Jerram <neil@ossau.uklinux.net> + + * goops.texi (Top): Say "Indices" before index nodes in main menu. + (Index): Removed (it was empty). Generally remove unnecessary + padding text that looks bad in HTML. + +2002-04-17 Marius Vollmer <mvo@zagadka.ping.de> + + * Makefile.am (CLEANFILES): Added goops.tmp, goops.cps. + +2001-12-03 Thien-Thi Nguyen <ttn@giblet.glug.org> + + * goops.texi: Grammar fix. + +2001-08-27 Neil Jerram <neil@ossau.uklinux.net> + + * Makefile.am (goops_TEXINFOS): Remove ../AUTHORS. + (TEXINFO_TEX): Added; avoids shipping multiple copies of + texinfo.tex in a single distribution. + + * goops.texi: Incorporate text previously in separate AUTHORS + file. + +2001-08-27 Neil Jerram <neil@ossau.uklinux.net> + + The change log for files in this directory continues backwards + from 2001-08-27 in ../ChangeLog, as all the Guile documentation + prior to this date was contained in a single directory. diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am index 2ca550ab3..2f218a565 100644 --- a/doc/ref/Makefile.am +++ b/doc/ref/Makefile.am @@ -4,20 +4,20 @@ ## ## This file is part of GUILE. ## -## GUILE is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as -## published by the Free Software Foundation; either version 2, or +## GUILE is free software; you can redistribute it and/or modify it +## under the terms of the GNU Lesser General Public License as +## published by the Free Software Foundation; either version 3, or ## (at your option) any later version. ## ## GUILE is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. +## GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU General Public -## License along with GUILE; see the file COPYING. If not, write -## to the Free Software Foundation, Inc., 51 Franklin Street, Fifth -## Floor, Boston, MA 02110-1301 USA +## You should have received a copy of the GNU Lesser General Public +## License along with GUILE; see the file COPYING.LESSER. If not, +## write to the Free Software Foundation, Inc., 51 Franklin Street, +## Fifth Floor, Boston, MA 02110-1301 USA AUTOMAKE_OPTIONS = gnu @@ -68,6 +68,9 @@ guile_TEXINFOS = preface.texi \ autoconf.texi \ autoconf-macros.texi \ tools.texi \ + history.texi \ + vm.texi \ + compiler.texi \ fdl.texi \ libguile-concepts.texi \ libguile-smobs.texi \ @@ -75,19 +78,29 @@ guile_TEXINFOS = preface.texi \ libguile-linking.texi \ libguile-extensions.texi \ api-init.texi \ - mod-getopt-long.texi + mod-getopt-long.texi \ + goops.texi \ + goops-tutorial.texi \ + effective-version.texi ETAGS_ARGS = $(info_TEXINFOS) $(guile_TEXINFOS) -EXTRA_DIST = ChangeLog-2008 +PICTURES = hierarchy.eps \ + hierarchy.pdf \ + hierarchy.png \ + hierarchy.txt \ + mop.text + +EXTRA_DIST = ChangeLog-2008 $(PICTURES) include $(top_srcdir)/am/pre-inst-guile # Automated snarfing autoconf.texi: autoconf-macros.texi -autoconf-macros.texi: $(top_srcdir)/guile-config/guile.m4 - $(preinstguiletool)/snarf-guile-m4-docs $(top_srcdir)/guile-config/guile.m4 \ +autoconf-macros.texi: $(top_srcdir)/meta/guile.m4 + GUILE_AUTO_COMPILE=0 $(top_builddir)/meta/uninstalled-env guile-tools \ + snarf-guile-m4-docs $(top_srcdir)/meta/guile.m4 \ > $(srcdir)/$@ lib-version.texi: $(top_srcdir)/GUILE-VERSION diff --git a/doc/ref/api-binding.texi b/doc/ref/api-binding.texi index b42f5567f..e53c48040 100644 --- a/doc/ref/api-binding.texi +++ b/doc/ref/api-binding.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -271,10 +271,16 @@ with duplicate bindings. Guile provides a procedure for checking whether a symbol is bound in the top level environment. -@c NJFIXME explain [env] -@deffn {Scheme Procedure} defined? sym [env] -@deffnx {C Function} scm_defined_p (sym, env) -Return @code{#t} if @var{sym} is defined in the lexical environment @var{env}. When @var{env} is not specified, look in the top-level environment as defined by the current module. +@deffn {Scheme Procedure} defined? sym [module] +@deffnx {C Function} scm_defined_p (sym, module) +Return @code{#t} if @var{sym} is defined in the module @var{module} or +the current module when @var{module} is not specified; otherwise return +@code{#f}. + +Up to Guile 1.8, the second optional argument had to be @dfn{lexical +environment} as returned by @code{the-environment}, for example. The +behavior of this function remains unchanged when the second argument is +omitted. @end deffn diff --git a/doc/ref/api-compound.texi b/doc/ref/api-compound.texi index c551c4d10..059390bb8 100644 --- a/doc/ref/api-compound.texi +++ b/doc/ref/api-compound.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -1344,9 +1344,9 @@ otherwise. @deftypefn {C Function} SCM scm_take_u8vector (const scm_t_uint8 *data, size_t len) @deftypefnx {C Function} SCM scm_take_s8vector (const scm_t_int8 *data, size_t len) @deftypefnx {C Function} SCM scm_take_u16vector (const scm_t_uint16 *data, size_t len) -@deftypefnx {C Function} SCM scm_take_s168vector (const scm_t_int16 *data, size_t len) +@deftypefnx {C Function} SCM scm_take_s16vector (const scm_t_int16 *data, size_t len) @deftypefnx {C Function} SCM scm_take_u32vector (const scm_t_uint32 *data, size_t len) -@deftypefnx {C Function} SCM scm_take_s328vector (const scm_t_int32 *data, size_t len) +@deftypefnx {C Function} SCM scm_take_s32vector (const scm_t_int32 *data, size_t len) @deftypefnx {C Function} SCM scm_take_u64vector (const scm_t_uint64 *data, size_t len) @deftypefnx {C Function} SCM scm_take_s64vector (const scm_t_int64 *data, size_t len) @deftypefnx {C Function} SCM scm_take_f32vector (const float *data, size_t len) @@ -1405,6 +1405,12 @@ C}), but returns a pointer to the elements of a uniform numeric vector of the indicated kind. @end deftypefn +Uniform numeric vectors can be written to and read from input/output +ports using the procedures listed below. However, bytevectors may often +be more convenient for binary input/output since they provide more +flexibility in the interpretation of raw byte sequences +(@pxref{Bytevectors}). + @deffn {Scheme Procedure} uniform-vector-read! uvec [port_or_fd [start [end]]] @deffnx {C Function} scm_uniform_vector_read_x (uvec, port_or_fd, start, end) Fill the elements of @var{uvec} by reading @@ -1643,18 +1649,18 @@ and writing. @subsection Generalized Vectors Guile has a number of data types that are generally vector-like: -strings, uniform numeric vectors, bitvectors, and of course ordinary -vectors of arbitrary Scheme values. These types are disjoint: a -Scheme value belongs to at most one of the four types listed above. +strings, uniform numeric vectors, bytevectors, bitvectors, and of course +ordinary vectors of arbitrary Scheme values. These types are disjoint: +a Scheme value belongs to at most one of the five types listed above. If you want to gloss over this distinction and want to treat all four types with common code, you can use the procedures in this section. They work with the @emph{generalized vector} type, which is the union -of the four vector-like types. +of the five vector-like types. @deffn {Scheme Procedure} generalized-vector? obj @deffnx {C Function} scm_generalized_vector_p (obj) -Return @code{#t} if @var{obj} is a vector, string, +Return @code{#t} if @var{obj} is a vector, bytevector, string, bitvector, or uniform numeric vector. @end deffn @@ -1743,9 +1749,9 @@ matrix with zero columns and 3 rows is different from a matrix with 3 columns and zero rows, which again is different from a vector of length zero. -Generalized vectors, such as strings, uniform numeric vectors, bit -vectors and ordinary vectors, are the special case of one dimensional -arrays. +Generalized vectors, such as strings, uniform numeric vectors, +bytevectors, bit vectors and ordinary vectors, are the special case of +one dimensional arrays. @menu * Array Syntax:: @@ -1828,6 +1834,16 @@ is a rank-zero array with contents 12. @end table +In addition, bytevectors are also arrays, but use a different syntax +(@pxref{Bytevectors}): + +@table @code + +@item #vu8(1 2 3) +is a 3-byte long bytevector, with contents 1, 2, 3. + +@end table + @node Array Procedures @subsubsection Array Procedures @@ -1985,13 +2001,24 @@ enclosed array is unspecified. For example, @lisp -(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) +(enclose-array '#3(((a b c) + (d e f)) + ((1 2 3) + (4 5 6))) + 1) @result{} -#<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))> - -(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) +#<enclosed-array (#1(a d) #1(b e) #1(c f)) + (#1(1 4) #1(2 5) #1(3 6))> + +(enclose-array '#3(((a b c) + (d e f)) + ((1 2 3) + (4 5 6))) + 1 0) @result{} -#<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))> +#<enclosed-array #2((a 1) (d 4)) + #2((b 2) (e 5)) + #2((c 3) (f 6))> @end lisp @end deffn @@ -2342,21 +2369,13 @@ the danger of a deadlock. In a multi-threaded program, you will need additional synchronization to avoid modifying reserved arrays.) You must take care to always unreserve an array after reserving it, -also in the presence of non-local exits. To simplify this, reserving -and unreserving work like a dynwind context (@pxref{Dynamic Wind}): a -call to @code{scm_array_get_handle} can be thought of as beginning a -dynwind context and @code{scm_array_handle_release} as ending it. -When a non-local exit happens between these two calls, the array is -implicitely unreserved. - -That is, you need to properly pair reserving and unreserving in your -code, but you don't need to worry about non-local exits. - -These calls and other pairs of calls that establish dynwind contexts -need to be properly nested. If you begin a context prior to reserving -an array, you need to unreserve the array before ending the context. -Likewise, when reserving two or more arrays in a certain order, you -need to unreserve them in the opposite order. +even in the presence of non-local exits. If a non-local exit can +happen between these two calls, you should install a dynwind context +that releases the array when it is left (@pxref{Dynamic Wind}). + +In addition, array reserving and unreserving must be properly +paired. For instance, when reserving two or more arrays in a certain +order, you need to unreserve them in the opposite order. Once you have reserved an array and have retrieved the pointer to its elements, you must figure out the layout of the elements in memory. @@ -2797,11 +2816,11 @@ structure. @example (make-vtable "prpw" (lambda (struct port) - (display "#<") - (display (struct-ref 0)) - (display " and ") - (display (struct-ref 1)) - (display ">"))) + (display "#<" port) + (display (struct-ref struct 0) port) + (display " and " port) + (display (struct-ref struct 1) port) + (display ">" port))) @end example @end deffn @@ -3075,8 +3094,10 @@ which can be changed. (color ball) (owner ball))) ball-color)) -(define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user)) -(define (owner ball) (struct-ref ball 0)) +(define (color ball) + (struct-ref (struct-vtable ball) vtable-offset-user)) +(define (owner ball) + (struct-ref ball 0)) (define red (make-ball-type 'red)) (define green (make-ball-type 'green)) @@ -3452,7 +3473,8 @@ whole is not a proper list: (assoc "mary" '((1 . 2) ("key" . "door") . "open sesame")) @result{} ERROR: In procedure assoc in expression (assoc "mary" (quote #)): -ERROR: Wrong type argument in position 2 (expecting association list): ((1 . 2) ("key" . "door") . "open sesame") +ERROR: Wrong type argument in position 2 (expecting + association list): ((1 . 2) ("key" . "door") . "open sesame") (sloppy-assoc "mary" '((1 . 2) ("key" . "door") . "open sesame")) @result{} @@ -3466,7 +3488,8 @@ Secondly, if one of the entries in the specified alist is not a pair: (assoc 2 '((1 . 1) 2 (3 . 9))) @result{} ERROR: In procedure assoc in expression (assoc 2 (quote #)): -ERROR: Wrong type argument in position 2 (expecting association list): ((1 . 1) 2 (3 . 9)) +ERROR: Wrong type argument in position 2 (expecting + association list): ((1 . 1) 2 (3 . 9)) (sloppy-assoc 2 '((1 . 1) 2 (3 . 9))) @result{} diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi index ed6411f29..e7614d136 100644 --- a/doc/ref/api-control.texi +++ b/doc/ref/api-control.texi @@ -22,6 +22,7 @@ flow of Scheme affects C code. * Error Reporting:: Procedures for signaling errors. * Dynamic Wind:: Dealing with non-local entrance/exit. * Handling Errors:: How to handle errors in C code. +* Continuation Barriers:: Protection from non-local control flow. @end menu @node begin @@ -1501,6 +1502,33 @@ which is the name of the procedure incorrectly invoked. @end deftypefn +@node Continuation Barriers +@subsection Continuation Barriers + +The non-local flow of control caused by continuations might sometimes +not be wanted. You can use @code{with-continuation-barrier} etc to +errect fences that continuations can not pass. + +@deffn {Scheme Procedure} with-continuation-barrier proc +@deffnx {C Function} scm_with_continuation_barrier (proc) +Call @var{proc} and return its result. Do not allow the invocation of +continuations that would leave or enter the dynamic extent of the call +to @code{with-continuation-barrier}. Such an attempt causes an error +to be signaled. + +Throws (such as errors) that are not caught from within @var{proc} are +caught by @code{with-continuation-barrier}. In that case, a short +message is printed to the current error port and @code{#f} is returned. + +Thus, @code{with-continuation-barrier} returns exactly once. +@end deffn + +@deftypefn {C Function} {void *} scm_c_with_continuation_barrier (void *(*func) (void *), void *data) +Like @code{scm_with_continuation_barrier} but call @var{func} on +@var{data}. When an error is caught, @code{NULL} is returned. +@end deftypefn + + @c Local Variables: @c TeX-master: "guile.texi" @c End: diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index e1db2a612..0fd4ee1cf 100755 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -45,6 +45,7 @@ For the documentation of such @dfn{compound} data types, see * Characters:: Single characters. * Character Sets:: Sets of characters. * Strings:: Sequences of characters. +* Bytevectors:: Sequences of bytes. * Regular Expressions:: Pattern matching and substitution. * Symbols:: Symbols. * Keywords:: Self-quoting, customizable display keywords. @@ -331,7 +332,7 @@ integers. The motivation for this behavior is that the inexactness of a number should not be lost silently. If you want to allow inexact integers, -you can explicitely insert a call to @code{inexact->exact} or to its C +you can explicitly insert a call to @code{inexact->exact} or to its C equivalent @code{scm_inexact_to_exact}. (Only inexact integers will be converted by this call into exact integers; inexact non-integers will become exact fractions.) @@ -3476,9 +3477,9 @@ allocated string. @deffnx {C Function} scm_string_concatenate_reverse (ls, final_string, end) Without optional arguments, this procedure is equivalent to -@smalllisp +@lisp (string-concatenate (reverse ls)) -@end smalllisp +@end lisp If the optional argument @var{final_string} is specified, it is consed onto the beginning to @var{ls} before performing the @@ -3534,11 +3535,12 @@ For example, to change characters to alternately upper and lower case, @example (define str (string-copy "studly")) -(string-for-each-index (lambda (i) - (string-set! str i - ((if (even? i) char-upcase char-downcase) - (string-ref str i)))) - str) +(string-for-each-index + (lambda (i) + (string-set! str i + ((if (even? i) char-upcase char-downcase) + (string-ref str i)))) + str) str @result{} "StUdLy" @end example @end deffn @@ -3746,6 +3748,445 @@ is larger than @var{max_len}, only @var{max_len} bytes have been stored and you probably need to try again with a larger buffer. @end deftypefn +@node Bytevectors +@subsection Bytevectors + +@cindex bytevector +@cindex R6RS + +A @dfn{bytevector} is a raw bit string. The @code{(rnrs bytevector)} +module provides the programming interface specified by the +@uref{http://www.r6rs.org/, Revised^6 Report on the Algorithmic Language +Scheme (R6RS)}. It contains procedures to manipulate bytevectors and +interpret their contents in a number of ways: bytevector contents can be +accessed as signed or unsigned integer of various sizes and endianness, +as IEEE-754 floating point numbers, or as strings. It is a useful tool +to encode and decode binary data. + +The R6RS (Section 4.3.4) specifies an external representation for +bytevectors, whereby the octets (integers in the range 0--255) contained +in the bytevector are represented as a list prefixed by @code{#vu8}: + +@lisp +#vu8(1 53 204) +@end lisp + +denotes a 3-byte bytevector containing the octets 1, 53, and 204. Like +string literals, booleans, etc., bytevectors are ``self-quoting'', i.e., +they do not need to be quoted: + +@lisp +#vu8(1 53 204) +@result{} #vu8(1 53 204) +@end lisp + +Bytevectors can be used with the binary input/output primitives of the +R6RS (@pxref{R6RS I/O Ports}). + +@menu +* Bytevector Endianness:: Dealing with byte order. +* Bytevector Manipulation:: Creating, copying, manipulating bytevectors. +* Bytevectors as Integers:: Interpreting bytes as integers. +* Bytevectors and Integer Lists:: Converting to/from an integer list. +* Bytevectors as Floats:: Interpreting bytes as real numbers. +* Bytevectors as Strings:: Interpreting bytes as Unicode strings. +* Bytevectors as Generalized Vectors:: Guile extension to the bytevector API. +@end menu + +@node Bytevector Endianness +@subsubsection Endianness + +@cindex endianness +@cindex byte order +@cindex word order + +Some of the following procedures take an @var{endianness} parameter. +The @dfn{endianness} is defined as the order of bytes in multi-byte +numbers: numbers encoded in @dfn{big endian} have their most +significant bytes written first, whereas numbers encoded in +@dfn{little endian} have their least significant bytes +first@footnote{Big-endian and little-endian are the most common +``endiannesses'', but others do exist. For instance, the GNU MP +library allows @dfn{word order} to be specified independently of +@dfn{byte order} (@pxref{Integer Import and Export,,, gmp, The GNU +Multiple Precision Arithmetic Library Manual}).}. + +Little-endian is the native endianness of the IA32 architecture and +its derivatives, while big-endian is native to SPARC and PowerPC, +among others. The @code{native-endianness} procedure returns the +native endianness of the machine it runs on. + +@deffn {Scheme Procedure} native-endianness +@deffnx {C Function} scm_native_endianness () +Return a value denoting the native endianness of the host machine. +@end deffn + +@deffn {Scheme Macro} endianness symbol +Return an object denoting the endianness specified by @var{symbol}. If +@var{symbol} is neither @code{big} nor @code{little} then an error is +raised at expand-time. +@end deffn + +@defvr {C Variable} scm_endianness_big +@defvrx {C Variable} scm_endianness_little +The objects denoting big- and little-endianness, respectively. +@end defvr + + +@node Bytevector Manipulation +@subsubsection Manipulating Bytevectors + +Bytevectors can be created, copied, and analyzed with the following +procedures and C functions. + +@deffn {Scheme Procedure} make-bytevector len [fill] +@deffnx {C Function} scm_make_bytevector (len, fill) +@deffnx {C Function} scm_c_make_bytevector (size_t len) +Return a new bytevector of @var{len} bytes. Optionally, if @var{fill} +is given, fill it with @var{fill}; @var{fill} must be in the range +[-128,255]. +@end deffn + +@deffn {Scheme Procedure} bytevector? obj +@deffnx {C Function} scm_bytevector_p (obj) +Return true if @var{obj} is a bytevector. +@end deffn + +@deftypefn {C Function} int scm_is_bytevector (SCM obj) +Equivalent to @code{scm_is_true (scm_bytevector_p (obj))}. +@end deftypefn + +@deffn {Scheme Procedure} bytevector-length bv +@deffnx {C Function} scm_bytevector_length (bv) +Return the length in bytes of bytevector @var{bv}. +@end deffn + +@deftypefn {C Function} size_t scm_c_bytevector_length (SCM bv) +Likewise, return the length in bytes of bytevector @var{bv}. +@end deftypefn + +@deffn {Scheme Procedure} bytevector=? bv1 bv2 +@deffnx {C Function} scm_bytevector_eq_p (bv1, bv2) +Return is @var{bv1} equals to @var{bv2}---i.e., if they have the same +length and contents. +@end deffn + +@deffn {Scheme Procedure} bytevector-fill! bv fill +@deffnx {C Function} scm_bytevector_fill_x (bv, fill) +Fill bytevector @var{bv} with @var{fill}, a byte. +@end deffn + +@deffn {Scheme Procedure} bytevector-copy! source source-start target target-start len +@deffnx {C Function} scm_bytevector_copy_x (source, source_start, target, target_start, len) +Copy @var{len} bytes from @var{source} into @var{target}, starting +reading from @var{source-start} (a positive index within @var{source}) +and start writing at @var{target-start}. +@end deffn + +@deffn {Scheme Procedure} bytevector-copy bv +@deffnx {C Function} scm_bytevector_copy (bv) +Return a newly allocated copy of @var{bv}. +@end deffn + +@deftypefn {C Function} scm_t_uint8 scm_c_bytevector_ref (SCM bv, size_t index) +Return the byte at @var{index} in bytevector @var{bv}. +@end deftypefn + +@deftypefn {C Function} void scm_c_bytevector_set_x (SCM bv, size_t index, scm_t_uint8 value) +Set the byte at @var{index} in @var{bv} to @var{value}. +@end deftypefn + +Low-level C macros are available. They do not perform any +type-checking; as such they should be used with care. + +@deftypefn {C Macro} size_t SCM_BYTEVECTOR_LENGTH (bv) +Return the length in bytes of bytevector @var{bv}. +@end deftypefn + +@deftypefn {C Macro} {signed char *} SCM_BYTEVECTOR_CONTENTS (bv) +Return a pointer to the contents of bytevector @var{bv}. +@end deftypefn + + +@node Bytevectors as Integers +@subsubsection Interpreting Bytevector Contents as Integers + +The contents of a bytevector can be interpreted as a sequence of +integers of any given size, sign, and endianness. + +@lisp +(let ((bv (make-bytevector 4))) + (bytevector-u8-set! bv 0 #x12) + (bytevector-u8-set! bv 1 #x34) + (bytevector-u8-set! bv 2 #x56) + (bytevector-u8-set! bv 3 #x78) + + (map (lambda (number) + (number->string number 16)) + (list (bytevector-u8-ref bv 0) + (bytevector-u16-ref bv 0 (endianness big)) + (bytevector-u32-ref bv 0 (endianness little))))) + +@result{} ("12" "1234" "78563412") +@end lisp + +The most generic procedures to interpret bytevector contents as integers +are described below. + +@deffn {Scheme Procedure} bytevector-uint-ref bv index endianness size +@deffnx {Scheme Procedure} bytevector-sint-ref bv index endianness size +@deffnx {C Function} scm_bytevector_uint_ref (bv, index, endianness, size) +@deffnx {C Function} scm_bytevector_sint_ref (bv, index, endianness, size) +Return the @var{size}-byte long unsigned (resp. signed) integer at +index @var{index} in @var{bv}, decoded according to @var{endianness}. +@end deffn + +@deffn {Scheme Procedure} bytevector-uint-set! bv index value endianness size +@deffnx {Scheme Procedure} bytevector-sint-set! bv index value endianness size +@deffnx {C Function} scm_bytevector_uint_set_x (bv, index, value, endianness, size) +@deffnx {C Function} scm_bytevector_sint_set_x (bv, index, value, endianness, size) +Set the @var{size}-byte long unsigned (resp. signed) integer at +@var{index} to @var{value}, encoded according to @var{endianness}. +@end deffn + +The following procedures are similar to the ones above, but specialized +to a given integer size: + +@deffn {Scheme Procedure} bytevector-u8-ref bv index +@deffnx {Scheme Procedure} bytevector-s8-ref bv index +@deffnx {Scheme Procedure} bytevector-u16-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-s16-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-u32-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-s32-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-u64-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-s64-ref bv index endianness +@deffnx {C Function} scm_bytevector_u8_ref (bv, index) +@deffnx {C Function} scm_bytevector_s8_ref (bv, index) +@deffnx {C Function} scm_bytevector_u16_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_s16_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_u32_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_s32_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_u64_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_s64_ref (bv, index, endianness) +Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8, +16, 32 or 64) from @var{bv} at @var{index}, decoded according to +@var{endianness}. +@end deffn + +@deffn {Scheme Procedure} bytevector-u8-set! bv index value +@deffnx {Scheme Procedure} bytevector-s8-set! bv index value +@deffnx {Scheme Procedure} bytevector-u16-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-s16-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-u32-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-s32-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-u64-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-s64-set! bv index value endianness +@deffnx {C Function} scm_bytevector_u8_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s8_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_u16_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_s16_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_u32_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_s32_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_u64_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_s64_set_x (bv, index, value, endianness) +Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is +8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to +@var{endianness}. +@end deffn + +Finally, a variant specialized for the host's endianness is available +for each of these functions (with the exception of the @code{u8} +accessors, for obvious reasons): + +@deffn {Scheme Procedure} bytevector-u16-native-ref bv index +@deffnx {Scheme Procedure} bytevector-s16-native-ref bv index +@deffnx {Scheme Procedure} bytevector-u32-native-ref bv index +@deffnx {Scheme Procedure} bytevector-s32-native-ref bv index +@deffnx {Scheme Procedure} bytevector-u64-native-ref bv index +@deffnx {Scheme Procedure} bytevector-s64-native-ref bv index +@deffnx {C Function} scm_bytevector_u16_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_s16_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_u32_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_s32_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_u64_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_s64_native_ref (bv, index) +Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8, +16, 32 or 64) from @var{bv} at @var{index}, decoded according to the +host's native endianness. +@end deffn + +@deffn {Scheme Procedure} bytevector-u16-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-s16-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-u32-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-s32-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-u64-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-s64-native-set! bv index value +@deffnx {C Function} scm_bytevector_u16_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s16_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_u32_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s32_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_u64_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_s64_native_set_x (bv, index, value) +Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is +8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to the +host's native endianness. +@end deffn + + +@node Bytevectors and Integer Lists +@subsubsection Converting Bytevectors to/from Integer Lists + +Bytevector contents can readily be converted to/from lists of signed or +unsigned integers: + +@lisp +(bytevector->sint-list (u8-list->bytevector (make-list 4 255)) + (endianness little) 2) +@result{} (-1 -1) +@end lisp + +@deffn {Scheme Procedure} bytevector->u8-list bv +@deffnx {C Function} scm_bytevector_to_u8_list (bv) +Return a newly allocated list of unsigned 8-bit integers from the +contents of @var{bv}. +@end deffn + +@deffn {Scheme Procedure} u8-list->bytevector lst +@deffnx {C Function} scm_u8_list_to_bytevector (lst) +Return a newly allocated bytevector consisting of the unsigned 8-bit +integers listed in @var{lst}. +@end deffn + +@deffn {Scheme Procedure} bytevector->uint-list bv endianness size +@deffnx {Scheme Procedure} bytevector->sint-list bv endianness size +@deffnx {C Function} scm_bytevector_to_uint_list (bv, endianness, size) +@deffnx {C Function} scm_bytevector_to_sint_list (bv, endianness, size) +Return a list of unsigned (resp. signed) integers of @var{size} bytes +representing the contents of @var{bv}, decoded according to +@var{endianness}. +@end deffn + +@deffn {Scheme Procedure} uint-list->bytevector lst endianness size +@deffnx {Scheme Procedure} sint-list->bytevector lst endianness size +@deffnx {C Function} scm_uint_list_to_bytevector (lst, endianness, size) +@deffnx {C Function} scm_sint_list_to_bytevector (lst, endianness, size) +Return a new bytevector containing the unsigned (resp. signed) integers +listed in @var{lst} and encoded on @var{size} bytes according to +@var{endianness}. +@end deffn + +@node Bytevectors as Floats +@subsubsection Interpreting Bytevector Contents as Floating Point Numbers + +@cindex IEEE-754 floating point numbers + +Bytevector contents can also be accessed as IEEE-754 single- or +double-precision floating point numbers (respectively 32 and 64-bit +long) using the procedures described here. + +@deffn {Scheme Procedure} bytevector-ieee-single-ref bv index endianness +@deffnx {Scheme Procedure} bytevector-ieee-double-ref bv index endianness +@deffnx {C Function} scm_bytevector_ieee_single_ref (bv, index, endianness) +@deffnx {C Function} scm_bytevector_ieee_double_ref (bv, index, endianness) +Return the IEEE-754 single-precision floating point number from @var{bv} +at @var{index} according to @var{endianness}. +@end deffn + +@deffn {Scheme Procedure} bytevector-ieee-single-set! bv index value endianness +@deffnx {Scheme Procedure} bytevector-ieee-double-set! bv index value endianness +@deffnx {C Function} scm_bytevector_ieee_single_set_x (bv, index, value, endianness) +@deffnx {C Function} scm_bytevector_ieee_double_set_x (bv, index, value, endianness) +Store real number @var{value} in @var{bv} at @var{index} according to +@var{endianness}. +@end deffn + +Specialized procedures are also available: + +@deffn {Scheme Procedure} bytevector-ieee-single-native-ref bv index +@deffnx {Scheme Procedure} bytevector-ieee-double-native-ref bv index +@deffnx {C Function} scm_bytevector_ieee_single_native_ref (bv, index) +@deffnx {C Function} scm_bytevector_ieee_double_native_ref (bv, index) +Return the IEEE-754 single-precision floating point number from @var{bv} +at @var{index} according to the host's native endianness. +@end deffn + +@deffn {Scheme Procedure} bytevector-ieee-single-native-set! bv index value +@deffnx {Scheme Procedure} bytevector-ieee-double-native-set! bv index value +@deffnx {C Function} scm_bytevector_ieee_single_native_set_x (bv, index, value) +@deffnx {C Function} scm_bytevector_ieee_double_native_set_x (bv, index, value) +Store real number @var{value} in @var{bv} at @var{index} according to +the host's native endianness. +@end deffn + + +@node Bytevectors as Strings +@subsubsection Interpreting Bytevector Contents as Unicode Strings + +@cindex Unicode string encoding + +Bytevector contents can also be interpreted as Unicode strings encoded +in one of the most commonly available encoding formats@footnote{Guile +1.8 does @emph{not} support Unicode strings. Therefore, the procedures +described here assume that Guile strings are internally encoded +according to the current locale. For instance, if @code{$LC_CTYPE} is +@code{fr_FR.ISO-8859-1}, then @code{string->utf-8} @i{et al.} will +assume that Guile strings are Latin-1-encoded.}. + +@lisp +(utf8->string (u8-list->bytevector '(99 97 102 101))) +@result{} "cafe" + +(string->utf8 "caf@'e") ;; SMALL LATIN LETTER E WITH ACUTE ACCENT +@result{} #vu8(99 97 102 195 169) +@end lisp + +@deffn {Scheme Procedure} string->utf8 str +@deffnx {Scheme Procedure} string->utf16 str +@deffnx {Scheme Procedure} string->utf32 str +@deffnx {C Function} scm_string_to_utf8 (str) +@deffnx {C Function} scm_string_to_utf16 (str) +@deffnx {C Function} scm_string_to_utf32 (str) +Return a newly allocated bytevector that contains the UTF-8, UTF-16, or +UTF-32 (aka. UCS-4) encoding of @var{str}. +@end deffn + +@deffn {Scheme Procedure} utf8->string utf +@deffnx {Scheme Procedure} utf16->string utf +@deffnx {Scheme Procedure} utf32->string utf +@deffnx {C Function} scm_utf8_to_string (utf) +@deffnx {C Function} scm_utf16_to_string (utf) +@deffnx {C Function} scm_utf32_to_string (utf) +Return a newly allocated string that contains from the UTF-8-, UTF-16-, +or UTF-32-decoded contents of bytevector @var{utf}. +@end deffn + +@node Bytevectors as Generalized Vectors +@subsubsection Accessing Bytevectors with the Generalized Vector API + +As an extension to the R6RS, Guile allows bytevectors to be manipulated +with the @dfn{generalized vector} procedures (@pxref{Generalized +Vectors}). This also allows bytevectors to be accessed using the +generic @dfn{array} procedures (@pxref{Array Procedures}). When using +these APIs, bytes are accessed one at a time as 8-bit unsigned integers: + +@example +(define bv #vu8(0 1 2 3)) + +(generalized-vector? bv) +@result{} #t + +(generalized-vector-ref bv 2) +@result{} 2 + +(generalized-vector-set! bv 2 77) +(array-ref bv 2) +@result{} 77 + +(array-type bv) +@result{} vu8 +@end example + + @node Regular Expressions @subsection Regular Expressions @tpindex Regular expressions @@ -4007,7 +4448,8 @@ Or matching a @sc{yyyymmdd} format date such as @samp{20020828} and re-ordering and hyphenating the fields. @lisp -(define date-regex "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])") +(define date-regex + "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])") (define s "Date 20020429 12am.") (regexp-substitute #f (string-match date-regex s) 'pre 2 "-" 3 "-" 1 'post " (" 0 ")") @@ -4067,7 +4509,8 @@ example the following is the date example from @code{string-match} call. @lisp -(define date-regex "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])") +(define date-regex + "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])") (define s "Date 20020429 12am.") (regexp-substitute/global #f date-regex s 'pre 2 "-" 3 "-" 1 'post " (" 0 ")") @@ -5062,7 +5505,7 @@ the @code{read-set!} procedure documented in @ref{User level options interfaces} and @ref{Reader options}. Note that the @code{prefix} and @code{postfix} syntax are mutually exclusive. -@smalllisp +@lisp (read-set! keywords 'prefix) #:type @@ -5094,7 +5537,7 @@ type: ERROR: In expression :type: ERROR: Unbound variable: :type ABORT: (unbound-variable) -@end smalllisp +@end lisp @node Keyword Procedures @subsubsection Keyword Procedures diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi index 0d4398015..c29bfdf12 100644 --- a/doc/ref/api-debug.texi +++ b/doc/ref/api-debug.texi @@ -283,9 +283,9 @@ runs a script non-interactively. The following procedures can be used to access and set the source properties of read expressions. -@deffn {Scheme Procedure} set-source-properties! obj plist -@deffnx {C Function} scm_set_source_properties_x (obj, plist) -Install the association list @var{plist} as the source property +@deffn {Scheme Procedure} set-source-properties! obj alist +@deffnx {C Function} scm_set_source_properties_x (obj, alist) +Install the association list @var{alist} as the source property list for @var{obj}. @end deffn @@ -302,12 +302,12 @@ Return the source property association list of @var{obj}. @deffn {Scheme Procedure} source-property obj key @deffnx {C Function} scm_source_property (obj, key) -Return the source property specified by @var{key} from -@var{obj}'s source property list. +Return the property specified by @var{key} from @var{obj}'s source +properties. @end deffn In practice there are only two ways that you should use the ability to -set an expression's source breakpoints. +set an expression's source properties. @itemize @item @@ -330,9 +330,9 @@ involved in a backtrace or error report. If you are looking for a way to attach arbitrary information to an expression other than these properties, you should use -@code{make-object-property} instead (@pxref{Object Properties}), because -that will avoid bloating the source property hash table, which is really -only intended for the specific purposes described in this section. +@code{make-object-property} instead (@pxref{Object Properties}). That +will avoid bloating the source property hash table, which is really +only intended for the debugging purposes just described. @node Decoding Memoized Source Expressions @@ -1708,7 +1708,7 @@ facilities just described. A good way to explore in detail what a Scheme procedure does is to set a trap on it and then single step through what it does. To do this, make and install a @code{<procedure-trap>} with the @code{debug-trap} -behaviour from @code{(ice-9 debugging ice-9-debugger-extensions)}. +behaviour from @code{(ice-9 debugger)}. The following sample session illustrates this. It assumes that the file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is @@ -1718,7 +1718,6 @@ calls @code{mkmatrix}. @lisp $ /usr/bin/guile -q guile> (use-modules (ice-9 debugger) - (ice-9 debugging ice-9-debugger-extensions) (ice-9 debugging traps)) guile> (load "matrix.scm") guile> (install-trap (make <procedure-trap> @@ -1732,16 +1731,16 @@ Frame 2 at matrix.scm:8:3 [mkmatrix] debug> next Frame 3 at matrix.scm:4:3 - (let ((x 1)) (quote this-is-a-matric)) + (let ((x 1)) (quote hi!)) debug> info frame Stack frame: 3 This frame is an evaluation. The expression being evaluated is: matrix.scm:4:3: - (let ((x 1)) (quote this-is-a-matric)) + (let ((x 1)) (quote hi!)) debug> next Frame 3 at matrix.scm:5:21 - (quote this-is-a-matric) + (quote hi!) debug> bt In unknown file: ?: 0* [primitive-eval (do-main 4)] @@ -1750,18 +1749,17 @@ In standard input: In matrix.scm: 8: 2 [mkmatrix] ... - 5: 3 (quote this-is-a-matric) + 5: 3 (quote hi!) debug> quit -this-is-a-matric +hi! guile> @end lisp Or you can use Guile's Emacs interface (GDS), by using the module @code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and -@code{(ice-9 debugging ice-9-debugger-extensions)}, and changing -@code{debug-trap} to @code{gds-debug-trap}. Then the stack and -corresponding source locations are displayed in Emacs instead of on -the Guile command line. +changing @code{debug-trap} to @code{gds-debug-trap}. Then the stack and +corresponding source locations are displayed in Emacs instead of on the +Guile command line. @node Profiling or Tracing a Procedure's Code @@ -1813,7 +1811,7 @@ guile> (do-main 4) | 5: (memq sym bindings) | 5: [memq let (debug)] | 5: =>#f -| 2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric))) +| 2: (letrec ((yy 23)) (let ((x 1)) (quote hi!))) | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | 4: (and (memq sym bindings) (let ...)) @@ -1832,7 +1830,7 @@ guile> (do-main 4) | 5: (memq sym bindings) | 5: [memq let (debug)] | 5: =>#f -| 2: (let ((x 1)) (quote this-is-a-matric)) +| 2: (let ((x 1)) (quote hi!)) | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | 4: (and (memq sym bindings) (let ...)) @@ -1841,15 +1839,15 @@ guile> (do-main 4) | 5: =>#f | 2: [let (let # #) (# # #)] | 2: [let (let # #) (# # #)] -| 2: =>(#@@let* (x 1) #@@let (quote this-is-a-matric)) -this-is-a-matric +| 2: =>(#@@let* (x 1) #@@let (quote hi!)) +hi! guile> (do-main 4) | 2: [mkmatrix] -| 2: (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric))) -| 2: (let* ((x 1)) (quote this-is-a-matric)) -| 2: (quote this-is-a-matric) -| 2: =>this-is-a-matric -this-is-a-matric +| 2: (letrec ((yy 23)) (let* ((x 1)) (quote hi!))) +| 2: (let* ((x 1)) (quote hi!)) +| 2: (quote hi!) +| 2: =>hi! +hi! guile> @end lisp @@ -1881,14 +1879,16 @@ each trace line instead of the stack depth. guile> (set-trace-layout "|~16@@a: ~a\n" trace/source trace/info) guile> (do-main 4) | matrix.scm:7:2: [mkmatrix] -| : (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric))) -| matrix.scm:3:2: (let* ((x 1)) (quote this-is-a-matric)) -| matrix.scm:4:4: (quote this-is-a-matric) -| matrix.scm:4:4: =>this-is-a-matric -this-is-a-matric +| : (letrec ((yy 23)) (let* ((x 1)) (quote hi!))) +| matrix.scm:3:2: (let* ((x 1)) (quote hi!)) +| matrix.scm:4:4: (quote hi!) +| matrix.scm:4:4: =>hi! +hi! guile> @end lisp +@anchor{Memoization} +@cindex Memoization (For anyone wondering why the first @code{(do-main 4)} call above generates lots more trace lines than the subsequent calls: these examples also demonstrate how the Guile evaluator ``memoizes'' code. diff --git a/doc/ref/api-evaluation.texi b/doc/ref/api-evaluation.texi index 6fd363df2..d8412154c 100644 --- a/doc/ref/api-evaluation.texi +++ b/doc/ref/api-evaluation.texi @@ -5,20 +5,22 @@ @c See the file guile.texi for copying conditions. @page -@node Read/Load/Eval +@node Read/Load/Eval/Compile @section Reading and Evaluating Scheme Code This chapter describes Guile functions that are concerned with reading, -loading and evaluating Scheme code at run time. +loading, evaluating, and compiling Scheme code at run time. @menu * Scheme Syntax:: Standard and extended Scheme syntax. * Scheme Read:: Reading Scheme code. * Fly Evaluation:: Procedures for on the fly evaluation. +* Compilation:: How to compile Scheme files and procedures. * Loading:: Loading Scheme code from file. * Delayed Evaluation:: Postponing evaluation until it is needed. * Local Evaluation:: Evaluation in a local environment. * Evaluator Behaviour:: Modifying Guile's evaluator. +* VM Behaviour:: Modifying Guile's virtual machine. @end menu @@ -411,6 +413,69 @@ the current module. @end deffn +@node Compilation +@subsection Compiling Scheme Code + +The @code{eval} procedure directly interprets the S-expression +representation of Scheme. An alternate strategy for evaluation is to +determine ahead of time what computations will be necessary to +evaluate the expression, and then use that recipe to produce the +desired results. This is known as @dfn{compilation}. + +While it is possible to compile simple Scheme expressions such as +@code{(+ 2 2)} or even @code{"Hello world!"}, compilation is most +interesting in the context of procedures. Compiling a lambda expression +produces a compiled procedure, which is just like a normal procedure +except typically much faster, because it can bypass the generic +interpreter. + +Functions from system modules in a Guile installation are normally +compiled already, so they load and run quickly. + +Note that well-written Scheme programs will not typically call the +procedures in this section, for the same reason that it is often bad +taste to use @code{eval}. The normal interface to the compiler is the +command-line file compiler, which can be invoked from the shell as +@code{guile-tools compile @var{foo.scm}}. This interface needs more +documentation. + +(Why are calls to @code{eval} and @code{compile} usually in bad taste? +Because they are limited, in that they can only really make sense for +top-level expressions. Also, most needs for ``compile-time'' +computation are fulfilled by macros and closures. Of course one good +counterexample is the REPL itself, or any code that reads expressions +from a port.) + +For more information on the compiler itself, see @ref{Compiling to the +Virtual Machine}. For information on the virtual machine, see @ref{A +Virtual Machine for Guile}. + +@deffn {Scheme Procedure} compile exp [env=#f] [from=(current-language)] [to=value] [opts=()] +Compile the expression @var{exp} in the environment @var{env}. If +@var{exp} is a procedure, the result will be a compiled procedure; +otherwise @code{compile} is mostly equivalent to @code{eval}. + +For a discussion of languages and compiler options, @xref{Compiling to +the Virtual Machine}. +@end deffn + +@deffn {Scheme Procedure} compile-file file [to=objcode] [opts='()] +Compile the file named @var{file}. + +Output will be written to a file in the current directory whose name +is computed as @code{(compiled-file-name @var{file})}. +@end deffn + +@deffn {Scheme Procedure} compiled-file-name file +Compute an appropriate name for a compiled version of a Scheme file +named @var{file}. + +Usually, the result will be the original file name with the +@code{.scm} suffix replaced with @code{.go}, but the exact behavior +depends on the contents of the @code{%load-extensions} and +@code{%load-compiled-extensions} lists. +@end deffn + @node Loading @subsection Loading Scheme Code from File @@ -435,9 +500,19 @@ procedure that will be called before any code is loaded. See documentation for @code{%load-hook} later in this section. @end deffn +@deffn {Scheme Procedure} load-compiled filename +Load the compiled file named @var{filename}. The load paths are not +searched. + +Compiling a source file (@pxref{Read/Load/Eval/Compile}) and then +calling @code{load-compiled} on the resulting file is equivalent to +calling @code{load} on the source file. +@end deffn + @deffn {Scheme Procedure} load-from-path filename Similar to @code{load}, but searches for @var{filename} in the load -paths. +paths. Preferentially loads a compiled version of the file, if it is +available and up-to-date. @end deffn @deffn {Scheme Procedure} primitive-load filename @@ -461,7 +536,8 @@ documentation for @code{%load-hook} later in this section. Search @code{%load-path} for the file named @var{filename} and load it into the top-level environment. If @var{filename} is a relative pathname and is not found in the list of search paths, -an error is signalled. +an error is signalled. Preferentially loads a compiled version of the +file, if it is available and up-to-date. @end deffn @deffn {Scheme Procedure} %search-load-path filename @@ -639,6 +715,30 @@ trap handlers. Option interface for the evaluator trap options. @end deffn +@node VM Behaviour +@subsection VM Behaviour + +Like the procedures from the previous section that operate on the +evaluator, there are also procedures to modify the behavior of a +virtual machine. + +The most useful thing that a user can do is to add to one of the +virtual machine's predefined hooks: + +@deffn {Scheme Procedure} vm-next-hook vm +@deffnx {Scheme Procedure} vm-apply-hook vm +@deffnx {Scheme Procedure} vm-boot-hook vm +@deffnx {Scheme Procedure} vm-return-hook vm +@deffnx {Scheme Procedure} vm-break-hook vm +@deffnx {Scheme Procedure} vm-exit-hook vm +@deffnx {Scheme Procedure} vm-halt-hook vm +@deffnx {Scheme Procedure} vm-enter-hook vm +Accessors to a virtual machine's hooks. Usually you pass +@code{(the-vm)} as the @var{vm}. +@end deffn + +@xref{A Virtual Machine for Guile}, for more information on Guile's +virtual machine. @c Local Variables: @c TeX-master: "guile.texi" diff --git a/doc/ref/api-init.texi b/doc/ref/api-init.texi index 0e4e8b8b7..f9714c3b6 100644 --- a/doc/ref/api-init.texi +++ b/doc/ref/api-init.texi @@ -61,7 +61,7 @@ Arrange things so that all of the code in the current thread executes as if from within a call to @code{scm_with_guile}. That is, all functions called by the current thread can assume that @code{SCM} values on their stack frames are protected from the garbage collector (except when the -thread has explicitely left guile mode, of course). +thread has explicitly left guile mode, of course). When @code{scm_init_guile} is called from a thread that already has been in guile mode once, nothing happens. This behavior matters when you diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi index f69d07ede..96cd147f3 100644 --- a/doc/ref/api-io.texi +++ b/doc/ref/api-io.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -18,6 +18,7 @@ * Block Reading and Writing:: Reading and writing blocks of text. * Default Ports:: Defaults for input, output and errors. * Port Types:: Types of port and how to make them. +* R6RS I/O Ports:: The R6RS port API. * I/O Extensions:: Using and extending ports in C. @end menu @@ -423,9 +424,9 @@ the current size, but this is not mandatory in the POSIX standard. The delimited-I/O module can be accessed with: -@smalllisp +@lisp (use-modules (ice-9 rdelim)) -@end smalllisp +@end lisp It can be used to read or write lines of text, or read text delimited by a specified set of characters. It's similar to the @code{(scsh rdelim)} @@ -535,9 +536,9 @@ delimiter may be either a newline or the @var{eof-object}; if The Block-string-I/O module can be accessed with: -@smalllisp +@lisp (use-modules (ice-9 rw)) -@end smalllisp +@end lisp It currently contains procedures that help to implement the @code{(scsh rw)} module in guile-scsh. @@ -794,17 +795,17 @@ current interfaces. @rnindex open-input-file @deffn {Scheme Procedure} open-input-file filename Open @var{filename} for input. Equivalent to -@smalllisp +@lisp (open-file @var{filename} "r") -@end smalllisp +@end lisp @end deffn @rnindex open-output-file @deffn {Scheme Procedure} open-output-file filename Open @var{filename} for output. Equivalent to -@smalllisp +@lisp (open-file @var{filename} "w") -@end smalllisp +@end lisp @end deffn @deffn {Scheme Procedure} call-with-input-file filename proc @@ -1023,6 +1024,269 @@ documentation for @code{open-file} in @ref{File Ports}. @end deffn +@node R6RS I/O Ports +@subsection R6RS I/O Ports + +@cindex R6RS +@cindex R6RS ports + +The I/O port API of the @uref{http://www.r6rs.org/, Revised Report^6 on +the Algorithmic Language Scheme (R6RS)} is provided by the @code{(rnrs +io ports)} module. It provides features, such as binary I/O and Unicode +string I/O, that complement or refine Guile's historical port API +presented above (@pxref{Input and Output}). + +@c FIXME: Update description when implemented. +@emph{Note}: The implementation of this R6RS API is currently far from +complete, notably due to the lack of support for Unicode I/O and strings. + +@menu +* R6RS End-of-File:: The end-of-file object. +* R6RS Port Manipulation:: Manipulating R6RS ports. +* R6RS Binary Input:: Binary input. +* R6RS Binary Output:: Binary output. +@end menu + +@node R6RS End-of-File +@subsubsection The End-of-File Object + +@cindex EOF +@cindex end-of-file + +R5RS' @code{eof-object?} procedure is provided by the @code{(rnrs io +ports)} module: + +@deffn {Scheme Procedure} eof-object? obj +@deffnx {C Function} scm_eof_object_p (obj) +Return true if @var{obj} is the end-of-file (EOF) object. +@end deffn + +In addition, the following procedure is provided: + +@deffn {Scheme Procedure} eof-object +@deffnx {C Function} scm_eof_object () +Return the end-of-file (EOF) object. + +@lisp +(eof-object? (eof-object)) +@result{} #t +@end lisp +@end deffn + + +@node R6RS Port Manipulation +@subsubsection Port Manipulation + +The procedures listed below operate on any kind of R6RS I/O port. + +@deffn {Scheme Procedure} port-position port +If @var{port} supports it (see below), return the offset (an integer) +indicating where the next octet will be read from/written to in +@var{port}. If @var{port} does not support this operation, an error +condition is raised. + +This is similar to Guile's @code{seek} procedure with the +@code{SEEK_CUR} argument (@pxref{Random Access}). +@end deffn + +@deffn {Scheme Procedure} port-has-port-position? port +Return @code{#t} is @var{port} supports @code{port-position}. +@end deffn + +@deffn {Scheme Procedure} set-port-position! port offset +If @var{port} supports it (see below), set the position where the next +octet will be read from/written to @var{port} to @var{offset} (an +integer). If @var{port} does not support this operation, an error +condition is raised. + +This is similar to Guile's @code{seek} procedure with the +@code{SEEK_SET} argument (@pxref{Random Access}). +@end deffn + +@deffn {Scheme Procedure} port-has-set-port-position!? port +Return @code{#t} is @var{port} supports @code{set-port-position!}. +@end deffn + +@deffn {Scheme Procedure} call-with-port port proc +Call @var{proc}, passing it @var{port} and closing @var{port} upon exit +of @var{proc}. Return the return values of @var{proc}. +@end deffn + + +@node R6RS Binary Input +@subsubsection Binary Input + +@cindex binary input + +R6RS binary input ports can be created with the procedures described +below. + +@deffn {Scheme Procedure} open-bytevector-input-port bv [transcoder] +@deffnx {C Function} scm_open_bytevector_input_port (bv, transcoder) +Return an input port whose contents are drawn from bytevector @var{bv} +(@pxref{Bytevectors}). + +@c FIXME: Update description when implemented. +The @var{transcoder} argument is currently not supported. +@end deffn + +@cindex custom binary input ports + +@deffn {Scheme Procedure} make-custom-binary-input-port id read! get-position set-position! close +@deffnx {C Function} scm_make_custom_binary_input_port (id, read!, get-position, set-position!, close) +Return a new custom binary input port@footnote{This is similar in spirit +to Guile's @dfn{soft ports} (@pxref{Soft Ports}).} named @var{id} (a +string) whose input is drained by invoking @var{read!} and passing it a +bytevector, an index where bytes should be written, and the number of +bytes to read. The @code{read!} procedure must return an integer +indicating the number of bytes read, or @code{0} to indicate the +end-of-file. + +Optionally, if @var{get-position} is not @code{#f}, it must be a thunk +that will be called when @var{port-position} is invoked on the custom +binary port and should return an integer indicating the position within +the underlying data stream; if @var{get-position} was not supplied, the +returned port does not support @var{port-position}. + +Likewise, if @var{set-position!} is not @code{#f}, it should be a +one-argument procedure. When @var{set-port-position!} is invoked on the +custom binary input port, @var{set-position!} is passed an integer +indicating the position of the next byte is to read. + +Finally, if @var{close} is not @code{#f}, it must be a thunk. It is +invoked when the custom binary input port is closed. + +Using a custom binary input port, the @code{open-bytevector-input-port} +procedure could be implemented as follows: + +@lisp +(define (open-bytevector-input-port source) + (define position 0) + (define length (bytevector-length source)) + + (define (read! bv start count) + (let ((count (min count (- length position)))) + (bytevector-copy! source position + bv start count) + (set! position (+ position count)) + count)) + + (define (get-position) position) + + (define (set-position! new-position) + (set! position new-position)) + + (make-custom-binary-input-port "the port" read! + get-position + set-position!)) + +(read (open-bytevector-input-port (string->utf8 "hello"))) +@result{} hello +@end lisp +@end deffn + +@cindex binary input +Binary input is achieved using the procedures below: + +@deffn {Scheme Procedure} get-u8 port +@deffnx {C Function} scm_get_u8 (port) +Return an octet read from @var{port}, a binary input port, blocking as +necessary, or the end-of-file object. +@end deffn + +@deffn {Scheme Procedure} lookahead-u8 port +@deffnx {C Function} scm_lookahead_u8 (port) +Like @code{get-u8} but does not update @var{port}'s position to point +past the octet. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-n port count +@deffnx {C Function} scm_get_bytevector_n (port, count) +Read @var{count} octets from @var{port}, blocking as necessary and +return a bytevector containing the octets read. If fewer bytes are +available, a bytevector smaller than @var{count} is returned. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-n! port bv start count +@deffnx {C Function} scm_get_bytevector_n_x (port, bv, start, count) +Read @var{count} bytes from @var{port} and store them in @var{bv} +starting at index @var{start}. Return either the number of bytes +actually read or the end-of-file object. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-some port +@deffnx {C Function} scm_get_bytevector_some (port) +Read from @var{port}, blocking as necessary, until data are available or +and end-of-file is reached. Return either a new bytevector containing +the data read or the end-of-file object. +@end deffn + +@deffn {Scheme Procedure} get-bytevector-all port +@deffnx {C Function} scm_get_bytevector_all (port) +Read from @var{port}, blocking as necessary, until the end-of-file is +reached. Return either a new bytevector containing the data read or the +end-of-file object (if no data were available). +@end deffn + +@node R6RS Binary Output +@subsubsection Binary Output + +Binary output ports can be created with the procedures below. + +@deffn {Scheme Procedure} open-bytevector-output-port [transcoder] +@deffnx {C Function} scm_open_bytevector_output_port (transcoder) +Return two values: a binary output port and a procedure. The latter +should be called with zero arguments to obtain a bytevector containing +the data accumulated by the port, as illustrated below. + +@lisp +(call-with-values + (lambda () + (open-bytevector-output-port)) + (lambda (port get-bytevector) + (display "hello" port) + (get-bytevector))) + +@result{} #vu8(104 101 108 108 111) +@end lisp + +@c FIXME: Update description when implemented. +The @var{transcoder} argument is currently not supported. +@end deffn + +@cindex custom binary output ports + +@deffn {Scheme Procedure} make-custom-binary-output-port id write! get-position set-position! close +@deffnx {C Function} scm_make_custom_binary_output_port (id, write!, get-position, set-position!, close) +Return a new custom binary output port named @var{id} (a string) whose +output is sunk by invoking @var{write!} and passing it a bytevector, an +index where bytes should be read from this bytevector, and the number of +bytes to be ``written''. The @code{write!} procedure must return an +integer indicating the number of bytes actually written; when it is +passed @code{0} as the number of bytes to write, it should behave as +though an end-of-file was sent to the byte sink. + +The other arguments are as for @code{make-custom-binary-input-port} +(@pxref{R6RS Binary Input, @code{make-custom-binary-input-port}}). +@end deffn + +@cindex binary output +Writing to a binary output port can be done using the following +procedures: + +@deffn {Scheme Procedure} put-u8 port octet +@deffnx {C Function} scm_put_u8 (port, octet) +Write @var{octet}, an integer in the 0--255 range, to @var{port}, a +binary output port. +@end deffn + +@deffn {Scheme Procedure} put-bytevector port bv [start [count]] +@deffnx {C Function} scm_put_bytevector (port, bv, start, count) +Write the contents of @var{bv} to @var{port}, optionally starting at +index @var{start} and limiting to @var{count} octets. +@end deffn + + @node I/O Extensions @subsection Using and Extending Ports in C @@ -1267,7 +1531,7 @@ implementations take care to avoid this problem. The procedure is set using -@deftypefun void scm_set_port_seek (scm_t_bits tc, off_t (*seek) (SCM port, off_t offset, int whence)) +@deftypefun void scm_set_port_seek (scm_t_bits tc, scm_t_off (*seek) (SCM port, scm_t_off offset, int whence)) @end deftypefun @item truncate @@ -1275,7 +1539,7 @@ Truncate the port data to be specified length. It can be assumed that the current state of @code{rw_active} is @code{SCM_PORT_NEITHER}. Set using -@deftypefun void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, off_t length)) +@deftypefun void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, scm_t_off length)) @end deftypefun @end table diff --git a/doc/ref/api-memory.texi b/doc/ref/api-memory.texi index 32d39982c..f492203f7 100644 --- a/doc/ref/api-memory.texi +++ b/doc/ref/api-memory.texi @@ -10,7 +10,7 @@ Guile uses a @emph{garbage collector} to manage most of its objects. While the garbage collector is designed to be mostly invisible, you -sometimes need to interact with it explicitely. +sometimes need to interact with it explicitly. See @ref{Garbage Collection} for a general discussion of how garbage collection relates to using Guile from C. @@ -201,7 +201,7 @@ below for a motivation. @deftypefn {C Function} void scm_gc_free (void *@var{mem}, size_t @var{size}, const char *@var{what}) Like @code{free}, but also call @code{scm_gc_unregister_collectable_memory}. -Note that you need to explicitely pass the @var{size} parameter. This +Note that you need to explicitly pass the @var{size} parameter. This is done since it should normally be easy to provide this parameter (for memory that is associated with GC controlled objects) and this frees us from tracking this value in the GC itself, which will keep diff --git a/doc/ref/api-modules.texi b/doc/ref/api-modules.texi index 9aeb08a44..1c9ab23ab 100644 --- a/doc/ref/api-modules.texi +++ b/doc/ref/api-modules.texi @@ -60,15 +60,15 @@ Library files in SLIB @emph{provide} a feature, and when user programs For example, the file @file{random.scm} in the SLIB package contains the line -@smalllisp +@lisp (provide 'random) -@end smalllisp +@end lisp so to use its procedures, a user would type -@smalllisp +@lisp (require 'random) -@end smalllisp +@end lisp and they would magically become available, @emph{but still have the same names!} So this method is nice, but not as good as a full-featured @@ -99,9 +99,9 @@ i.e., passed as the second argument to @code{eval}. Note: the following two procedures are available only when the @code{(ice-9 r5rs)} module is loaded: -@smalllisp +@lisp (use-modules (ice-9 r5rs)) -@end smalllisp +@end lisp @deffn {Scheme Procedure} scheme-report-environment version @deffnx {Scheme Procedure} null-environment version @@ -224,9 +224,9 @@ An @dfn{interface specification} has one of two forms. The first variation is simply to name the module, in which case its public interface is the one accessed. For example: -@smalllisp +@lisp (use-modules (ice-9 popen)) -@end smalllisp +@end lisp Here, the interface specification is @code{(ice-9 popen)}, and the result is that the current module now has access to @code{open-pipe}, @@ -241,11 +241,11 @@ module to be accessed, but also selects bindings from it and renames them to suit the current module's needs. For example: @cindex binding renamer -@smalllisp +@lisp (use-modules ((ice-9 popen) - :select ((open-pipe . pipe-open) close-pipe) - :renamer (symbol-prefix-proc 'unixy:))) -@end smalllisp + #:select ((open-pipe . pipe-open) close-pipe) + #:renamer (symbol-prefix-proc 'unixy:))) +@end lisp Here, the interface specification is more complex than before, and the result is that a custom interface with only two bindings is created and @@ -270,10 +270,10 @@ You can also directly refer to bindings in a module by using the open-pipe)}. Thus an alternative to the complete @code{use-modules} statement would be -@smalllisp +@lisp (define unixy:pipe-open (@@ (ice-9 popen) open-pipe)) (define unixy:close-pipe (@@ (ice-9 popen) close-pipe)) -@end smalllisp +@end lisp There is also @code{@@@@}, which can be used like @code{@@}, but does not check whether the variable that is being accessed is actually @@ -307,9 +307,9 @@ whose public interface is found and used. @var{spec} can also be of the form: @cindex binding renamer -@smalllisp +@lisp (MODULE-NAME [:select SELECTION] [:renamer RENAMER]) -@end smalllisp +@end lisp in which case a custom interface is newly created and used. @var{module-name} is a list of symbols, as above; @var{selection} is a @@ -373,9 +373,9 @@ by using @code{define-public} or @code{export} (both documented below). @var{module-name} is of the form @code{(hierarchy file)}. One example of this is -@smalllisp +@lisp (define-module (ice-9 popen)) -@end smalllisp +@end lisp @code{define-module} makes this module available to Guile programs under the given @var{module-name}. @@ -541,9 +541,9 @@ duplication to the next handler in @var{list}. The default duplicate binding resolution policy is given by the @code{default-duplicate-binding-handler} procedure, and is -@smalllisp +@lisp (replace warn-override-core warn last) -@end smalllisp +@end lisp @item #:no-backtrace @cindex no backtrace @@ -758,7 +758,7 @@ Record definition with @code{define-record-type} (@pxref{SRFI-9}). Read hash extension @code{#,()} (@pxref{SRFI-10}). @item (srfi srfi-11) -Multiple-value handling with @code{let-values} and @code{let-values*} +Multiple-value handling with @code{let-values} and @code{let*-values} (@pxref{SRFI-11}). @item (srfi srfi-13) @@ -1138,12 +1138,12 @@ gcc -shared -o libbessel.so -fPIC bessel.c Now fire up Guile: -@smalllisp +@lisp (define bessel-lib (dynamic-link "./libbessel.so")) (dynamic-call "init_math_bessel" bessel-lib) (j0 2) @result{} 0.223890779141236 -@end smalllisp +@end lisp The filename @file{./libbessel.so} should be pointing to the shared library produced with the @code{gcc} command above, of course. The diff --git a/doc/ref/api-options.texi b/doc/ref/api-options.texi index 20e32c51c..f7d0962df 100644 --- a/doc/ref/api-options.texi +++ b/doc/ref/api-options.texi @@ -82,10 +82,11 @@ general are stored. On Unix-like systems, this is usually @deffnx {C Function} scm_sys_library_dir () Return the name of the directory where the Guile Scheme files that belong to the core Guile installation (as opposed to files from a 3rd -party package) are installed. On Unix-like systems, this is usually +party package) are installed. On Unix-like systems this is usually @file{/usr/local/share/guile/<GUILE_EFFECTIVE_VERSION>} or -@file{/usr/share/guile/<GUILE_EFFECTIVE_VERSION>}, for example: -@file{/usr/local/share/guile/1.6}. +@file{/usr/share/guile/<GUILE_EFFECTIVE_VERSION>}; + +@noindent for example @file{/usr/local/share/guile/1.6}. @end deffn @deffn {Scheme Procedure} %site-dir @@ -503,9 +504,9 @@ Guile is case-sensitive by default. To make Guile case insensitive, you can type -@smalllisp +@lisp (read-enable 'case-insensitive) -@end smalllisp +@end lisp @node Printing options @subsubsection Printing options @@ -680,7 +681,8 @@ the maximum stack size, use @code{debug-set!}, for example: @lisp (debug-set! stack 200000) @result{} -(show-file-name #t stack 200000 debug backtrace depth 20 maxdepth 1000 frames 3 indent 10 width 79 procnames cheap) +(show-file-name #t stack 200000 debug backtrace depth 20 + maxdepth 1000 frames 3 indent 10 width 79 procnames cheap) (non-tail-recursive-factorial 500) @result{} @@ -717,7 +719,6 @@ backtrace. Need to give a better example, possibly putting debugging option examples in a separate session.] @end enumerate - @smalllisp guile> (define abc "hello") guile> abc diff --git a/doc/ref/api-procedures.texi b/doc/ref/api-procedures.texi index 7fd0f4fa4..8098b4ffb 100644 --- a/doc/ref/api-procedures.texi +++ b/doc/ref/api-procedures.texi @@ -11,6 +11,7 @@ @menu * Lambda:: Basic procedure creation using lambda. * Primitive Procedures:: Procedures defined in C. +* Compiled Procedures:: Scheme procedures can be compiled. * Optional Arguments:: Handling keyword, optional and rest arguments. * Procedure Properties:: Procedure properties and meta-information. * Procedures with Setters:: Procedures with setters. @@ -131,6 +132,156 @@ use @code{scm_c_make_subr} and also @code{scm_makcclo} if necessary. It is advisable to use the gsubr variants since they provide a slightly higher-level abstraction of the Guile implementation. +@node Compiled Procedures +@subsection Compiled Procedures + +Procedures that were created when loading a compiled file are +themselves compiled. (In contrast, procedures that are defined by +loading a Scheme source file are interpreted, and often not as fast as +compiled procedures.) + +Loading compiled files is the normal way that compiled procedures come +to being, though procedures can be compiled at runtime as well. +@xref{Read/Load/Eval/Compile}, for more information on runtime +compilation. + +Compiled procedures, also known as @dfn{programs}, respond all +procedures that operate on procedures. In addition, there are a few +more accessors for low-level details on programs. + +Most people won't need to use the routines described in this section, +but it's good to have them documented. You'll have to include the +appropriate module first, though: + +@example +(use-modules (system vm program)) +@end example + +@deffn {Scheme Procedure} program? obj +@deffnx {C Function} scm_program_p (obj) +Returns @code{#t} iff @var{obj} is a compiled procedure. +@end deffn + +@deffn {Scheme Procedure} program-objcode program +@deffnx {C Function} scm_program_objcode (program) +Returns the object code associated with this program. @xref{Bytecode +and Objcode}, for more information. +@end deffn + +@deffn {Scheme Procedure} program-objects program +@deffnx {C Function} scm_program_objects (program) +Returns the ``object table'' associated with this program, as a +vector. @xref{VM Programs}, for more information. +@end deffn + +@deffn {Scheme Procedure} program-module program +@deffnx {C Function} scm_program_module (program) +Returns the module that was current when this program was created. Can +return @code{#f} if the compiler could determine that this information +was unnecessary. +@end deffn + +@deffn {Scheme Procedure} program-external program +@deffnx {C Function} scm_program_external (program) +Returns the set of heap-allocated variables that this program captures +in its closure, as a list. If a closure is code with data, you can get +the code from @code{program-bytecode}, and the data via +@code{program-external}. + +Users must not modify the returned value unless they think they're +really clever. +@end deffn + +@deffn {Scheme Procedure} program-external-set! program external +@deffnx {C Function} scm_program_external_set_x (program, external) +Set @var{external} as the set of closure variables on @var{program}. + +The Guile maintainers will not be held responsible for side effects of +calling this function, including but not limited to replacement of +shampoo with hair dye, and a slight salty taste in tomorrow's dinner. +@end deffn + +@deffn {Scheme Procedure} program-arity program +@deffnx {C Function} scm_program_arity (program) +@deffnx {Scheme Procedure} arity:nargs arity +@deffnx {Scheme Procedure} arity:nrest arity +@deffnx {Scheme Procedure} arity:nlocs arity +@deffnx {Scheme Procedure} arity:nexts arity +Accessors for a representation of the ``arity'' of a program. + +@code{nargs} is the number of arguments to the procedure, and +@code{nrest} will be non-zero if the last argument is a rest argument. + +The other two accessors determine the number of local and external +(heap-allocated) variables that this procedure will need to have +allocated. +@end deffn + +@deffn {Scheme Procedure} program-meta program +@deffnx scm_program_meta (program) +Return the metadata thunk of @var{program}, or @code{#f} if it has no +metadata. + +When called, a metadata thunk returns a list of the following form: +@code{(@var{bindings} @var{sources} . @var{properties})}. The format +of each of these elements is discussed below. +@end deffn + +@deffn {Scheme Procedure} program-bindings program +@deffnx {Scheme Procedure} make-binding name extp index start end +@deffnx {Scheme Procedure} binding:name binding +@deffnx {Scheme Procedure} binding:extp binding +@deffnx {Scheme Procedure} binding:index binding +@deffnx {Scheme Procedure} binding:start binding +@deffnx {Scheme Procedure} binding:end binding +Bindings annotations for programs, along with their accessors. + +Bindings declare names and liveness extents for block-local variables. +The best way to see what these are is to play around with them at a +REPL. The only tricky bit is that @var{extp} is a boolean, declaring +whether the binding is heap-allocated or not. @xref{VM Concepts}, for +more information. + +Note that bindings information is stored in a program as part of its +metadata thunk, so including it in the generated object code does not +impose a runtime performance penalty. +@end deffn + +@deffn {Scheme Procedure} program-sources program +@deffnx {Scheme Procedure} source:addr source +@deffnx {Scheme Procedure} source:line source +@deffnx {Scheme Procedure} source:column source +@deffnx {Scheme Procedure} source:file source +Source location annotations for programs, along with their accessors. + +Source location information propagates through the compiler and ends +up being serialized to the program's metadata. This information is +keyed by the offset of the instruction pointer within the object code +of the program. Specifically, it is keyed on the @code{ip} @emph{just +following} an instruction, so that backtraces can find the source +location of a call that is in progress. +@end deffn + +@deffn {Scheme Procedure} program-properties program +Return the properties of a @code{program} as an association list, +keyed by property name (a symbol). + +Some interesting properties include: +@itemize +@item @code{name}, the name of the procedure +@item @code{documentation}, the procedure's docstring +@end itemize +@end deffn + +@deffn {Scheme Procedure} program-property program name +Access a program's property by name, returning @code{#f} if not found. +@end deffn + +@deffn {Scheme Procedure} program-documentation program +@deffnx {Scheme Procedure} program-name program +Accessors for specific properties. +@end deffn + @node Optional Arguments @subsection Optional Arguments diff --git a/doc/ref/api-scheduling.texi b/doc/ref/api-scheduling.texi index 3b622868c..521369619 100644 --- a/doc/ref/api-scheduling.texi +++ b/doc/ref/api-scheduling.texi @@ -8,14 +8,9 @@ @node Scheduling @section Threads, Mutexes, Asyncs and Dynamic Roots -[FIXME: This is pasted in from Tom Lord's original guile.texi chapter -plus the Cygnus programmer's manual; it should be *very* carefully -reviewed and largely reorganized.] - @menu * Arbiters:: Synchronization primitives. * Asyncs:: Asynchronous procedure invocation. -* Continuation Barriers:: Protection from non-local control flow. * Threads:: Multiple threads of execution. * Mutexes and Condition Variables:: Synchronization primitives. * Blocking:: How to block properly in guile mode. @@ -47,7 +42,6 @@ process synchronization. @deffn {Scheme Procedure} try-arbiter arb @deffnx {C Function} scm_try_arbiter (arb) -@deffnx {C Function} scm_try_arbiter (arb) If @var{arb} is unlocked, then lock it and return @code{#t}. If @var{arb} is already locked, then do nothing and return @code{#f}. @@ -70,7 +64,7 @@ release it, but that's not required, any thread can release it. @cindex user asyncs @cindex system asyncs -Asyncs are a means of deferring the excution of Scheme code until it is +Asyncs are a means of deferring the execution of Scheme code until it is safe to do so. Guile provides two kinds of asyncs that share the basic concept but are @@ -132,43 +126,42 @@ This procedure is not safe to be called from signal handlers. Use signal handlers. @end deffn -@c FIXME: The use of @deffnx for scm_c_call_with_blocked_asyncs and -@c scm_c_call_with_unblocked_asyncs puts "void" into the function -@c index. Would prefer to use @deftypefnx if makeinfo allowed that, -@c or a @deftypefn with an empty return type argument if it didn't -@c introduce an extra space. - @deffn {Scheme Procedure} call-with-blocked-asyncs proc @deffnx {C Function} scm_call_with_blocked_asyncs (proc) -@deffnx {C Function} {void *} scm_c_call_with_blocked_asyncs (void * (*proc) (void *data), void *data) -@findex scm_c_call_with_blocked_asyncs Call @var{proc} and block the execution of system asyncs by one level for the current thread while it is running. Return the value returned by @var{proc}. For the first two variants, call @var{proc} with no arguments; for the third, call it with @var{data}. @end deffn +@deftypefn {C Function} {void *} scm_c_call_with_blocked_asyncs (void * (*proc) (void *data), void *data) +The same but with a C function @var{proc} instead of a Scheme thunk. +@end deftypefn + @deffn {Scheme Procedure} call-with-unblocked-asyncs proc @deffnx {C Function} scm_call_with_unblocked_asyncs (proc) -@deffnx {C Function} {void *} scm_c_call_with_unblocked_asyncs (void *(*p) (void *d), void *d) -@findex scm_c_call_with_unblocked_asyncs Call @var{proc} and unblock the execution of system asyncs by one level for the current thread while it is running. Return the value returned by @var{proc}. For the first two variants, call @var{proc} with no arguments; for the third, call it with @var{data}. @end deffn +@deftypefn {C Function} {void *} scm_c_call_with_unblocked_asyncs (void *(*proc) (void *data), void *data) +The same but with a C function @var{proc} instead of a Scheme thunk. +@end deftypefn + @deftypefn {C Function} void scm_dynwind_block_asyncs () -This function must be used inside a pair of calls to +During the current dynwind context, increase the blocking of asyncs by +one level. This function must be used inside a pair of calls to @code{scm_dynwind_begin} and @code{scm_dynwind_end} (@pxref{Dynamic -Wind}). During the dynwind context, asyncs are blocked by one level. +Wind}). @end deftypefn @deftypefn {C Function} void scm_dynwind_unblock_asyncs () -This function must be used inside a pair of calls to +During the current dynwind context, decrease the blocking of asyncs by +one level. This function must be used inside a pair of calls to @code{scm_dynwind_begin} and @code{scm_dynwind_end} (@pxref{Dynamic -Wind}). During the dynwind context, asyncs are unblocked by one -level. +Wind}). @end deftypefn @node User asyncs @@ -197,32 +190,6 @@ Mark the user async @var{a} for future execution. Execute all thunks from the marked asyncs of the list @var{list_of_a}. @end deffn -@node Continuation Barriers -@subsection Continuation Barriers - -The non-local flow of control caused by continuations might sometimes -not be wanted. You can use @code{with-continuation-barrier} etc to -errect fences that continuations can not pass. - -@deffn {Scheme Procedure} with-continuation-barrier proc -@deffnx {C Function} scm_with_continuation_barrier (proc) -Call @var{proc} and return its result. Do not allow the invocation of -continuations that would leave or enter the dynamic extent of the call -to @code{with-continuation-barrier}. Such an attempt causes an error -to be signaled. - -Throws (such as errors) that are not caught from within @var{proc} are -caught by @code{with-continuation-barrier}. In that case, a short -message is printed to the current error port and @code{#f} is returned. - -Thus, @code{with-continuation-barrier} returns exactly once. -@end deffn - -@deftypefn {C Function} {void *} scm_c_with_continuation_barrier (void *(*func) (void *), void *data) -Like @code{scm_with_continuation_barrier} but call @var{func} on -@var{data}. When an error is caught, @code{NULL} is returned. -@end deftypefn - @node Threads @subsection Threads @cindex threads diff --git a/doc/ref/api-undocumented.texi b/doc/ref/api-undocumented.texi index 826b4d38b..ef1df19c5 100644 --- a/doc/ref/api-undocumented.texi +++ b/doc/ref/api-undocumented.texi @@ -257,7 +257,7 @@ otherwise return the first argument. @deffn {Scheme Procedure} system-async thunk @deffnx {C Function} scm_system_async (thunk) This function is deprecated. You can use @var{thunk} directly -instead of explicitely creating an async object. +instead of explicitly creating an async object. @end deffn diff --git a/doc/ref/autoconf.texi b/doc/ref/autoconf.texi index 83686dada..ae807c276 100644 --- a/doc/ref/autoconf.texi +++ b/doc/ref/autoconf.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -48,19 +48,18 @@ checks. @cindex pkg-config @cindex autoconf -GNU Guile provides a @dfn{pkg-config} description file, installed as -@file{@var{prefix}/lib/pkgconfig/guile-1.8.pc}, which contains all the -information necessary to compile and link C applications that use Guile. -The @code{pkg-config} program is able to read this file and provide this -information to application programmers; it can be obtained at -@url{http://pkg-config.freedesktop.org/}. +GNU Guile provides a @dfn{pkg-config} description file, which contains +all the information necessary to compile and link C applications that +use Guile. The @code{pkg-config} program is able to read this file +and provide this information to application programmers; it can be +obtained at @url{http://pkg-config.freedesktop.org/}. The following command lines give respectively the C compilation and link flags needed to build Guile-using programs: @example -pkg-config guile-1.8 --cflags -pkg-config guile-1.8 --libs +pkg-config guile-@value{EFFECTIVE-VERSION} --cflags +pkg-config guile-@value{EFFECTIVE-VERSION} --libs @end example To ease use of pkg-config with Autoconf, pkg-config comes with a @@ -71,7 +70,7 @@ accordingly, or prints an error and exits if Guile was not found: @findex PKG_CHECK_MODULES @example -PKG_CHECK_MODULES([GUILE], [guile-1.8]) +PKG_CHECK_MODULES([GUILE], [guile-@value{EFFECTIVE-VERSION}]) @end example Guile comes with additional Autoconf macros providing more information, diff --git a/doc/ref/compiler.texi b/doc/ref/compiler.texi new file mode 100644 index 000000000..d749fc1f3 --- /dev/null +++ b/doc/ref/compiler.texi @@ -0,0 +1,785 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 2008, 2009 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@node Compiling to the Virtual Machine +@section Compiling to the Virtual Machine + +Compilers have a mystique about them that is attractive and +off-putting at the same time. They are attractive because they are +magical -- they transform inert text into live results, like throwing +the switch on Frankenstein's monster. However, this magic is perceived +by many to be impenetrable. + +This section aims to pay attention to the small man behind the +curtain. + +@xref{Read/Load/Eval/Compile}, if you're lost and you just wanted to +know how to compile your @code{.scm} file. + +@menu +* Compiler Tower:: +* The Scheme Compiler:: +* Tree-IL:: +* GLIL:: +* Assembly:: +* Bytecode and Objcode:: +* Writing New High-Level Languages:: +* Extending the Compiler:: +@end menu + +@node Compiler Tower +@subsection Compiler Tower + +Guile's compiler is quite simple, actually -- its @emph{compilers}, to +put it more accurately. Guile defines a tower of languages, starting +at Scheme and progressively simplifying down to languages that +resemble the VM instruction set (@pxref{Instruction Set}). + +Each language knows how to compile to the next, so each step is simple +and understandable. Furthermore, this set of languages is not +hardcoded into Guile, so it is possible for the user to add new +high-level languages, new passes, or even different compilation +targets. + +Languages are registered in the module, @code{(system base language)}: + +@example +(use-modules (system base language)) +@end example + +They are registered with the @code{define-language} form. + +@deffn {Scheme Syntax} define-language @ +name title version reader printer @ +[parser=#f] [compilers='()] [decompilers='()] [evaluator=#f] +Define a language. + +This syntax defines a @code{#<language>} object, bound to @var{name} +in the current environment. In addition, the language will be added to +the global language set. For example, this is the language definition +for Scheme: + +@example +(define-language scheme + #:title "Guile Scheme" + #:version "0.5" + #:reader read + #:compilers `((tree-il . ,compile-tree-il)) + #:decompilers `((tree-il . ,decompile-tree-il)) + #:evaluator (lambda (x module) (primitive-eval x)) + #:printer write) +@end example +@end deffn + +The interesting thing about having languages defined this way is that +they present a uniform interface to the read-eval-print loop. This +allows the user to change the current language of the REPL: + +@example +$ guile +Guile Scheme interpreter 0.5 on Guile 1.9.0 +Copyright (C) 2001-2008 Free Software Foundation, Inc. + +Enter `,help' for help. +scheme@@(guile-user)> ,language tree-il +Tree Intermediate Language interpreter 1.0 on Guile 1.9.0 +Copyright (C) 2001-2008 Free Software Foundation, Inc. + +Enter `,help' for help. +tree-il@@(guile-user)> +@end example + +Languages can be looked up by name, as they were above. + +@deffn {Scheme Procedure} lookup-language name +Looks up a language named @var{name}, autoloading it if necessary. + +Languages are autoloaded by looking for a variable named @var{name} in +a module named @code{(language @var{name} spec)}. + +The language object will be returned, or @code{#f} if there does not +exist a language with that name. +@end deffn + +Defining languages this way allows us to programmatically determine +the necessary steps for compiling code from one language to another. + +@deffn {Scheme Procedure} lookup-compilation-order from to +Recursively traverses the set of languages to which @var{from} can +compile, depth-first, and return the first path that can transform +@var{from} to @var{to}. Returns @code{#f} if no path is found. + +This function memoizes its results in a cache that is invalidated by +subsequent calls to @code{define-language}, so it should be quite +fast. +@end deffn + +There is a notion of a ``current language'', which is maintained in +the @code{*current-language*} fluid. This language is normally Scheme, +and may be rebound by the user. The run-time compilation interfaces +(@pxref{Read/Load/Eval/Compile}) also allow you to choose other source +and target languages. + +The normal tower of languages when compiling Scheme goes like this: + +@itemize +@item Scheme, which we know and love +@item Tree Intermediate Language (Tree-IL) +@item Guile Low Intermediate Language (GLIL) +@item Assembly +@item Bytecode +@item Objcode +@end itemize + +Object code may be serialized to disk directly, though it has a cookie +and version prepended to the front. But when compiling Scheme at run +time, you want a Scheme value: for example, a compiled procedure. For +this reason, so as not to break the abstraction, Guile defines a fake +language at the bottom of the tower: + +@itemize +@item Value +@end itemize + +Compiling to @code{value} loads the object code into a procedure, and +wakes the sleeping giant. + +Perhaps this strangeness can be explained by example: +@code{compile-file} defaults to compiling to object code, because it +produces object code that has to live in the barren world outside the +Guile runtime; but @code{compile} defaults to compiling to +@code{value}, as its product re-enters the Guile world. + +Indeed, the process of compilation can circulate through these +different worlds indefinitely, as shown by the following quine: + +@example +((lambda (x) ((compile x) x)) '(lambda (x) ((compile x) x))) +@end example + +@node The Scheme Compiler +@subsection The Scheme Compiler + +The job of the Scheme compiler is to expand all macros and all of +Scheme to its most primitive expressions. The definition of +``primitive'' is given by the inventory of constructs provided by +Tree-IL, the target language of the Scheme compiler: procedure +applications, conditionals, lexical references, etc. This is described +more fully in the next section. + +The tricky and amusing thing about the Scheme-to-Tree-IL compiler is +that it is completely implemented by the macro expander. Since the +macro expander has to run over all of the source code already in order +to expand macros, it might as well do the analysis at the same time, +producing Tree-IL expressions directly. + +Because this compiler is actually the macro expander, it is +extensible. Any macro which the user writes becomes part of the +compiler. + +The Scheme-to-Tree-IL expander may be invoked using the generic +@code{compile} procedure: + +@lisp +(compile '(+ 1 2) #:from 'scheme #:to 'tree-il) +@result{} + #<<application> src: #f + proc: #<<toplevel-ref> src: #f name: +> + args: (#<<const> src: #f exp: 1> + #<<const> src: #f exp: 2>)> +@end lisp + +Or, since Tree-IL is so close to Scheme, it is often useful to expand +Scheme to Tree-IL, then translate back to Scheme. For that reason the +expander provides two interfaces. The former is equivalent to calling +@code{(sc-expand '(+ 1 2) 'c)}, where the @code{'c} is for +``compile''. With @code{'e} (the default), the result is translated +back to Scheme: + +@lisp +(sc-expand '(+ 1 2)) +@result{} (+ 1 2) +(sc-expand '(let ((x 10)) (* x x))) +@result{} (let ((x84 10)) (* x84 x84)) +@end lisp + +The second example shows that as part of its job, the macro expander +renames lexically-bound variables. The original names are preserved +when compiling to Tree-IL, but can't be represented in Scheme: a +lexical binding only has one name. It is for this reason that the +@emph{native} output of the expander is @emph{not} Scheme. There's too +much information we would lose if we translated to Scheme directly: +lexical variable names, source locations, and module hygiene. + +Note however that @code{sc-expand} does not have the same signature as +@code{compile-tree-il}. @code{compile-tree-il} is a small wrapper +around @code{sc-expand}, to make it conform to the general form of +compiler procedures in Guile's language tower. + +Compiler procedures take three arguments: an expression, an +environment, and a keyword list of options. They return three values: +the compiled expression, the corresponding environment for the target +language, and a ``continuation environment''. The compiled expression +and environment will serve as input to the next language's compiler. +The ``continuation environment'' can be used to compile another +expression from the same source language within the same module. + +For example, you might compile the expression, @code{(define-module +(foo))}. This will result in a Tree-IL expression and environment. But +if you compiled a second expression, you would want to take into +account the compile-time effect of compiling the previous expression, +which puts the user in the @code{(foo)} module. That is purpose of the +``continuation environment''; you would pass it as the environment +when compiling the subsequent expression. + +For Scheme, an environment may be one of two things: +@itemize +@item @code{#f}, in which case compilation is performed in the context +of the current module; or +@item a module, which specifies the context of the compilation. +@end itemize + +@node Tree-IL +@subsection Tree-IL + +Tree Intermediate Language (Tree-IL) is a structured intermediate +language that is close in expressive power to Scheme. It is an +expanded, pre-analyzed Scheme. + +Tree-IL is ``structured'' in the sense that its representation is +based on records, not S-expressions. This gives a rigidity to the +language that ensures that compiling to a lower-level language only +requires a limited set of transformations. Practically speaking, +consider the Tree-IL type, @code{<const>}, which has two fields, +@code{src} and @code{exp}. Instances of this type are records created +via @code{make-const}, and whose fields are accessed as +@code{const-src}, and @code{const-exp}. There is also a predicate, +@code{const?}. @xref{Records}, for more information on records. + +@c alpha renaming + +All Tree-IL types have a @code{src} slot, which holds source location +information for the expression. This information, if present, will be +residualized into the compiled object code, allowing backtraces to +show source information. The format of @code{src} is the same as that +returned by Guile's @code{source-properties} function. @xref{Source +Properties}, for more information. + +Although Tree-IL objects are represented internally using records, +there is also an equivalent S-expression external representation for +each kind of Tree-IL. For example, an the S-expression representation +of @code{#<const src: #f exp: 3>} expression would be: + +@example +(const 3) +@end example + +Users may program with this format directly at the REPL: + +@example +scheme@@(guile-user)> ,language tree-il +Tree Intermediate Language interpreter 1.0 on Guile 1.9.0 +Copyright (C) 2001-2008 Free Software Foundation, Inc. + +Enter `,help' for help. +tree-il@@(guile-user)> (apply (primitive +) (const 32) (const 10)) +@result{} 42 +@end example + +The @code{src} fields are left out of the external representation. + +One may create Tree-IL objects from their external representations via +calling @code{parse-tree-il}, the reader for Tree-IL. If any source +information is attached to the input S-expression, it will be +propagated to the resulting Tree-IL expressions. This is probably the +easiest way to compile to Tree-IL: just make the appropriate external +representations in S-expression format, and let @code{parse-tree-il} +take care of the rest. + +@deftp {Scheme Variable} <void> src +@deftpx {External Representation} (void) +An empty expression. In practice, equivalent to Scheme's @code{(if #f +#f)}. +@end deftp +@deftp {Scheme Variable} <const> src exp +@deftpx {External Representation} (const @var{exp}) +A constant. +@end deftp +@deftp {Scheme Variable} <primitive-ref> src name +@deftpx {External Representation} (primitive @var{name}) +A reference to a ``primitive''. A primitive is a procedure that, when +compiled, may be open-coded. For example, @code{cons} is usually +recognized as a primitive, so that it compiles down to a single +instruction. + +Compilation of Tree-IL usually begins with a pass that resolves some +@code{<module-ref>} and @code{<toplevel-ref>} expressions to +@code{<primitive-ref>} expressions. The actual compilation pass +has special cases for applications of certain primitives, like +@code{apply} or @code{cons}. +@end deftp +@deftp {Scheme Variable} <lexical-ref> src name gensym +@deftpx {External Representation} (lexical @var{name} @var{gensym}) +A reference to a lexically-bound variable. The @var{name} is the +original name of the variable in the source program. @var{gensym} is a +unique identifier for this variable. +@end deftp +@deftp {Scheme Variable} <lexical-set> src name gensym exp +@deftpx {External Representation} (set! (lexical @var{name} @var{gensym}) @var{exp}) +Sets a lexically-bound variable. +@end deftp +@deftp {Scheme Variable} <module-ref> src mod name public? +@deftpx {External Representation} (@@ @var{mod} @var{name}) +@deftpx {External Representation} (@@@@ @var{mod} @var{name}) +A reference to a variable in a specific module. @var{mod} should be +the name of the module, e.g. @code{(guile-user)}. + +If @var{public?} is true, the variable named @var{name} will be looked +up in @var{mod}'s public interface, and serialized with @code{@@}; +otherwise it will be looked up among the module's private bindings, +and is serialized with @code{@@@@}. +@end deftp +@deftp {Scheme Variable} <module-set> src mod name public? exp +@deftpx {External Representation} (set! (@@ @var{mod} @var{name}) @var{exp}) +@deftpx {External Representation} (set! (@@@@ @var{mod} @var{name}) @var{exp}) +Sets a variable in a specific module. +@end deftp +@deftp {Scheme Variable} <toplevel-ref> src name +@deftpx {External Representation} (toplevel @var{name}) +References a variable from the current procedure's module. +@end deftp +@deftp {Scheme Variable} <toplevel-set> src name exp +@deftpx {External Representation} (set! (toplevel @var{name}) @var{exp}) +Sets a variable in the current procedure's module. +@end deftp +@deftp {Scheme Variable} <toplevel-define> src name exp +@deftpx {External Representation} (define (toplevel @var{name}) @var{exp}) +Defines a new top-level variable in the current procedure's module. +@end deftp +@deftp {Scheme Variable} <conditional> src test then else +@deftpx {External Representation} (if @var{test} @var{then} @var{else}) +A conditional. Note that @var{else} is not optional. +@end deftp +@deftp {Scheme Variable} <application> src proc args +@deftpx {External Representation} (apply @var{proc} . @var{args}) +A procedure call. +@end deftp +@deftp {Scheme Variable} <sequence> src exps +@deftpx {External Representation} (begin . @var{exps}) +Like Scheme's @code{begin}. +@end deftp +@deftp {Scheme Variable} <lambda> src names vars meta body +@deftpx {External Representation} (lambda @var{names} @var{vars} @var{meta} @var{body}) +A closure. @var{names} is original binding form, as given in the +source code, which may be an improper list. @var{vars} are gensyms +corresponding to the @var{names}. @var{meta} is an association list of +properties. The actual @var{body} is a single Tree-IL expression. +@end deftp +@deftp {Scheme Variable} <let> src names vars vals exp +@deftpx {External Representation} (let @var{names} @var{vars} @var{vals} @var{exp}) +Lexical binding, like Scheme's @code{let}. @var{names} are the +original binding names, @var{vars} are gensyms corresponding to the +@var{names}, and @var{vals} are Tree-IL expressions for the values. +@var{exp} is a single Tree-IL expression. +@end deftp +@deftp {Scheme Variable} <letrec> src names vars vals exp +@deftpx {External Representation} (letrec @var{names} @var{vars} @var{vals} @var{exp}) +A version of @code{<let>} that creates recursive bindings, like +Scheme's @code{letrec}. +@end deftp + +There are two Tree-IL constructs that are not normally produced by +higher-level compilers, but instead are generated during the +source-to-source optimization and analysis passes that the Tree-IL +compiler does. Users should not generate these expressions directly, +unless they feel very clever, as the default analysis pass will +generate them as necessary. + +@deftp {Scheme Variable} <let-values> src names vars exp body +@deftpx {External Representation} (let-values @var{names} @var{vars} @var{exp} @var{body}) +Like Scheme's @code{receive} -- binds the values returned by +evaluating @code{exp} to the @code{lambda}-like bindings described by +@var{vars}. That is to say, @var{vars} may be an improper list. + +@code{<let-values>} is an optimization of @code{<application>} of the +primitive, @code{call-with-values}. +@end deftp +@deftp {Scheme Variable} <fix> src names vars vals body +@deftpx {External Representation} (fix @var{names} @var{vars} @var{vals} @var{body}) +Like @code{<letrec>}, but only for @var{vals} that are unset +@code{lambda} expressions. + +@code{fix} is an optimization of @code{letrec} (and @code{let}). +@end deftp + +Tree-IL implements a compiler to GLIL that recursively traverses +Tree-IL expressions, writing out GLIL expressions into a linear list. +The compiler also keeps some state as to whether the current +expression is in tail context, and whether its value will be used in +future computations. This state allows the compiler not to emit code +for constant expressions that will not be used (e.g. docstrings), and +to perform tail calls when in tail position. + +Most optimization, such as it currently is, is performed on Tree-IL +expressions as source-to-source transformations. There will be more +optimizations added in the future. + +Interested readers are encouraged to read the implementation in +@code{(language tree-il compile-glil)} for more details. + +@node GLIL +@subsection GLIL + +Guile Low Intermediate Language (GLIL) is a structured intermediate +language whose expressions more closely approximate Guile's VM +instruction set. Its expression types are defined in @code{(language +glil)}. + +@deftp {Scheme Variable} <glil-program> nargs nrest nlocs meta . body +A unit of code that at run-time will correspond to a compiled +procedure. @var{nargs} @var{nrest} and @var{nlocs} collectively define +the program's arity; see @ref{Compiled Procedures}, for more +information. @var{meta} should be an alist of properties, as in +Tree-IL's @code{<lambda>}. @var{body} is an ordered list of GLIL +expressions. +@end deftp +@deftp {Scheme Variable} <glil-bind> . vars +An advisory expression that notes a liveness extent for a set of +variables. @var{vars} is a list of @code{(@var{name} @var{type} +@var{index})}, where @var{type} should be either @code{argument}, +@code{local}, or @code{external}. + +@code{<glil-bind>} expressions end up being serialized as part of a +program's metadata and do not form part of a program's code path. +@end deftp +@deftp {Scheme Variable} <glil-mv-bind> vars rest +A multiple-value binding of the values on the stack to @var{vars}. Iff +@var{rest} is true, the last element of @var{vars} will be treated as +a rest argument. + +In addition to pushing a binding annotation on the stack, like +@code{<glil-bind>}, an expression is emitted at compilation time to +make sure that there are enough values available to bind. See the +notes on @code{truncate-values} in @ref{Procedural Instructions}, for +more information. +@end deftp +@deftp {Scheme Variable} <glil-unbind> +Closes the liveness extent of the most recently encountered +@code{<glil-bind>} or @code{<glil-mv-bind>} expression. As GLIL +expressions are compiled, a parallel stack of live bindings is +maintained; this expression pops off the top element from that stack. + +Bindings are written into the program's metadata so that debuggers and +other tools can determine the set of live local variables at a given +offset within a VM program. +@end deftp +@deftp {Scheme Variable} <glil-source> loc +Records source information for the preceding expression. @var{loc} +should be an association list of containing @code{line} @code{column}, +and @code{filename} keys, e.g. as returned by +@code{source-properties}. +@end deftp +@deftp {Scheme Variable} <glil-void> +Pushes ``the unspecified value'' on the stack. +@end deftp +@deftp {Scheme Variable} <glil-const> obj +Pushes a constant value onto the stack. @var{obj} must be a number, +string, symbol, keyword, boolean, character, uniform array, the empty +list, or a pair or vector of constants. +@end deftp +@deftp {Scheme Variable} <glil-lexical> local? boxed? op index +Accesses a lexically bound variable. If the variable is not +@var{local?} it is free. All variables may have @code{ref} and +@code{set} as their @var{op}. Boxed variables may also have the +@var{op}s @code{box}, @code{empty-box}, and @code{fix}, which +correspond in semantics to the VM instructions @code{box}, +@code{empty-box}, and @code{fix-closure}. @xref{Stack Layout}, for +more information. +@end deftp +@deftp {Scheme Variable} <glil-toplevel> op name +Accesses a toplevel variable. @var{op} may be @code{ref}, @code{set}, +or @code{define}. +@end deftp +@deftp {Scheme Variable} <glil-module> op mod name public? +Accesses a variable within a specific module. See Tree-IL's +@code{<module-ref>}, for more information. +@end deftp +@deftp {Scheme Variable} <glil-label> label +Creates a new label. @var{label} can be any Scheme value, and should +be unique. +@end deftp +@deftp {Scheme Variable} <glil-branch> inst label +Branch to a label. @var{label} should be a @code{<ghil-label>}. +@code{inst} is a branching instruction: @code{br-if}, @code{br}, etc. +@end deftp +@deftp {Scheme Variable} <glil-call> inst nargs +This expression is probably misnamed, as it does not correspond to +function calls. @code{<glil-call>} invokes the VM instruction named +@var{inst}, noting that it is called with @var{nargs} stack arguments. +The arguments should be pushed on the stack already. What happens to +the stack afterwards depends on the instruction. +@end deftp +@deftp {Scheme Variable} <glil-mv-call> nargs ra +Performs a multiple-value call. @var{ra} is a @code{<glil-label>} +corresponding to the multiple-value return address for the call. See +the notes on @code{mv-call} in @ref{Procedural Instructions}, for more +information. +@end deftp + +Users may enter in GLIL at the REPL as well, though there is a bit +more bookkeeping to do. Since GLIL needs the set of variables to be +declared explicitly in a @code{<glil-program>}, GLIL expressions must +be wrapped in a thunk that declares the arity of the expression: + +@example +scheme@@(guile-user)> ,language glil +Guile Lowlevel Intermediate Language (GLIL) interpreter 0.3 on + Guile 1.9.0 +Copyright (C) 2001-2008 Free Software Foundation, Inc. + +Enter `,help' for help. +glil@@(guile-user)> (program 0 0 0 () (const 3) (call return 1)) +@result{} 3 +@end example + +Just as in all of Guile's compilers, an environment is passed to the +GLIL-to-object code compiler, and one is returned as well, along with +the object code. + +@node Assembly +@subsection Assembly + +Assembly is an S-expression-based, human-readable representation of +the actual bytecodes that will be emitted for the VM. As such, it is a +useful intermediate language both for compilation and for +decompilation. + +Besides the fact that it is not a record-based language, assembly +differs from GLIL in four main ways: + +@itemize +@item Labels have been resolved to byte offsets in the program. +@item Constants inside procedures have either been expressed as inline +instructions or cached in object arrays. +@item Procedures with metadata (source location information, liveness +extents, procedure names, generic properties, etc) have had their +metadata serialized out to thunks. +@item All expressions correspond directly to VM instructions -- i.e., +there is no @code{<glil-lexical>} which can be a ref or a set. +@end itemize + +Assembly is isomorphic to the bytecode that it compiles to. You can +compile to bytecode, then decompile back to assembly, and you have the +same assembly code. + +The general form of assembly instructions is the following: + +@lisp +(@var{inst} @var{arg} ...) +@end lisp + +The @var{inst} names a VM instruction, and its @var{arg}s will be +embedded in the instruction stream. The easiest way to see assembly is +to play around with it at the REPL, as can be seen in this annotated +example: + +@example +scheme@@(guile-user)> (compile '(lambda (x) (+ x x)) #:to 'assembly) +(load-program 0 0 0 + () ; Labels + 70 ; Length + #f ; Metadata + (make-false) + (make-false) ; object table for the returned lambda + (nop) + (nop) ; Alignment. Since assembly has already resolved its labels + (nop) ; to offsets, and programs must be 8-byte aligned since their + (nop) ; object code is mmap'd directly to structures, assembly + (nop) ; has to have the alignment embedded in it. + (nop) + (load-program + 1 + 0 + () + 8 + (load-program 0 0 0 () 21 #f + (load-symbol "x") ; Name and liveness extent for @code{x}. + (make-false) + (make-int8:0) ; Some instruction+arg combinations + (make-int8:0) ; have abbreviations. + (make-int8 6) + (list 0 5) + (list 0 1) + (make-eol) + (list 0 2) + (return)) + ; And here, the actual code. + (local-ref 0) + (local-ref 0) + (add) + (return) + (nop) + (nop)) + ; Return our new procedure. + (return)) +@end example + +Of course you can switch the REPL to assembly and enter in assembly +S-expressions directly, like with other languages, though it is more +difficult, given that the length fields have to be correct. + +@node Bytecode and Objcode +@subsection Bytecode and Objcode + +Finally, the raw bytes. There are actually two different ``languages'' +here, corresponding to two different ways to represent the bytes. + +``Bytecode'' represents code as uniform byte vectors, useful for +structuring and destructuring code on the Scheme level. Bytecode is +the next step down from assembly: + +@example +scheme@@(guile-user)> (compile '(+ 32 10) #:to 'assembly) +@result{} (load-program 0 0 0 () 6 #f + (make-int8 32) (make-int8 10) (add) (return)) +scheme@@(guile-user)> (compile '(+ 32 10) #:to 'bytecode) +@result{} #u8(0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 10 32 10 10 120 52) +@end example + +``Objcode'' is bytecode, but mapped directly to a C structure, +@code{struct scm_objcode}: + +@example +struct scm_objcode @{ + scm_t_uint8 nargs; + scm_t_uint8 nrest; + scm_t_uint16 nlocs; + scm_t_uint32 len; + scm_t_uint32 metalen; + scm_t_uint8 base[0]; +@}; +@end example + +As one might imagine, objcode imposes a minimum length on the +bytecode. Also, the multibyte fields are in native endianness, which +makes objcode (and bytecode) system-dependent. Indeed, in the short +example above, all but the last 6 bytes were the program's header. + +Objcode also has a couple of important efficiency hacks. First, +objcode may be mapped directly from disk, allowing compiled code to be +loaded quickly, often from the system's disk cache, and shared among +multiple processes. Secondly, objcode may be embedded in other +objcode, allowing procedures to have the text of other procedures +inlined into their bodies, without the need for separate allocation of +the code. Of course, the objcode object itself does need to be +allocated. + +Procedures related to objcode are defined in the @code{(system vm +objcode)} module. + +@deffn {Scheme Procedure} objcode? obj +@deffnx {C Function} scm_objcode_p (obj) +Returns @code{#f} iff @var{obj} is object code, @code{#f} otherwise. +@end deffn + +@deffn {Scheme Procedure} bytecode->objcode bytecode +@deffnx {C Function} scm_bytecode_to_objcode (bytecode,) +Makes a bytecode object from @var{bytecode}, which should be a +@code{u8vector}. +@end deffn + +@deffn {Scheme Variable} load-objcode file +@deffnx {C Function} scm_load_objcode (file) +Load object code from a file named @var{file}. The file will be mapped +into memory via @code{mmap}, so this is a very fast operation. + +On disk, object code has an sixteen-byte cookie prepended to it, to +prevent accidental loading of arbitrary garbage. +@end deffn + +@deffn {Scheme Variable} write-objcode objcode file +@deffnx {C Function} scm_write_objcode (objcode) +Write object code out to a file, prepending the eight-byte cookie. +@end deffn + +@deffn {Scheme Variable} objcode->u8vector objcode +@deffnx {C Function} scm_objcode_to_u8vector (objcode) +Copy object code out to a @code{u8vector} for analysis by Scheme. +@end deffn + +The following procedure is actually in @code{(system vm program)}, but +we'll mention it here: + +@deffn {Scheme Variable} make-program objcode objtable [free-vars=#f] +@deffnx {C Function} scm_make_program (objcode, objtable, free_vars) +Load up object code into a Scheme program. The resulting program will +have @var{objtable} as its object table, which should be a vector or +@code{#f}, and will capture the free variables from @var{free-vars}. +@end deffn + +Object code from a file may be disassembled at the REPL via the +meta-command @code{,disassemble-file}, abbreviated as @code{,xx}. +Programs may be disassembled via @code{,disassemble}, abbreviated as +@code{,x}. + +Compiling object code to the fake language, @code{value}, is performed +via loading objcode into a program, then executing that thunk with +respect to the compilation environment. Normally the environment +propagates through the compiler transparently, but users may specify +the compilation environment manually as well: + +@deffn {Scheme Procedure} make-objcode-env module free-vars +Make an object code environment. @var{module} should be a Scheme +module, and @var{free-vars} should be a vector of free variables. +@code{#f} is also a valid object code environment. +@end deffn + +@node Writing New High-Level Languages +@subsection Writing New High-Level Languages + +In order to integrate a new language @var{lang} into Guile's compiler +system, one has to create the module @code{(language @var{lang} spec)} +containing the language definition and referencing the parser, +compiler and other routines processing it. The module hierarchy in +@code{(language brainfuck)} defines a very basic Brainfuck +implementation meant to serve as easy-to-understand example on how to +do this. See for instance @url{http://en.wikipedia.org/wiki/Brainfuck} +for more information about the Brainfuck language itself. + + +@node Extending the Compiler +@subsection Extending the Compiler + +At this point, we break with the impersonal tone of the rest of the +manual, and make an intervention. Admit it: if you've read this far +into the compiler internals manual, you are a junkie. Perhaps a course +at your university left you unsated, or perhaps you've always harbored +a sublimated desire to hack the holy of computer science holies: a +compiler. Well you're in good company, and in a good position. Guile's +compiler needs your help. + +There are many possible avenues for improving Guile's compiler. +Probably the most important improvement, speed-wise, will be some form +of native compilation, both just-in-time and ahead-of-time. This could +be done in many ways. Probably the easiest strategy would be to extend +the compiled procedure structure to include a pointer to a native code +vector, and compile from bytecode to native code at run-time after a +procedure is called a certain number of times. + +The name of the game is a profiling-based harvest of the low-hanging +fruit, running programs of interest under a system-level profiler and +determining which improvements would give the most bang for the buck. +It's really getting to the point though that native compilation is the +next step. + +The compiler also needs help at the top end, enhancing the Scheme that +it knows to also understand R6RS, and adding new high-level compilers. +We have JavaScript and Emacs Lisp mostly complete, but they could use +some love; Lua would be nice as well, butq whatever language it is +that strikes your fancy would be welcome too. + +Compilers are for hacking, not for admiring or for complaining about. +Get to it! diff --git a/doc/ref/data-rep.texi b/doc/ref/data-rep.texi index 5b76263b3..5f2a22b07 100644 --- a/doc/ref/data-rep.texi +++ b/doc/ref/data-rep.texi @@ -4,135 +4,6 @@ @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. -@c essay \input texinfo -@c essay @c -*-texinfo-*- -@c essay @c %**start of header -@c essay @setfilename data-rep.info -@c essay @settitle Data Representation in Guile -@c essay @c %**end of header - -@c essay @include version.texi - -@c essay @dircategory The Algorithmic Language Scheme -@c essay @direntry -@c essay * data-rep: (data-rep). Data Representation in Guile --- how to use -@c essay Guile objects in your C code. -@c essay @end direntry - -@c essay @setchapternewpage off - -@c essay @ifinfo -@c essay Data Representation in Guile - -@c essay Copyright (C) 1998, 1999, 2000, 2003, 2006 Free Software Foundation - -@c essay Permission is granted to make and distribute verbatim copies of -@c essay this manual provided the copyright notice and this permission notice -@c essay are preserved on all copies. - -@c essay @ignore -@c essay Permission is granted to process this file through TeX and print the -@c essay results, provided the printed document carries copying permission -@c essay notice identical to this one except for the removal of this paragraph -@c essay (this paragraph not being relevant to the printed manual). -@c essay @end ignore - -@c essay Permission is granted to copy and distribute modified versions of this -@c essay manual under the conditions for verbatim copying, provided that the entire -@c essay resulting derived work is distributed under the terms of a permission -@c essay notice identical to this one. - -@c essay Permission is granted to copy and distribute translations of this manual -@c essay into another language, under the above conditions for modified versions, -@c essay except that this permission notice may be stated in a translation approved -@c essay by the Free Software Foundation. -@c essay @end ifinfo - -@c essay @titlepage -@c essay @sp 10 -@c essay @comment The title is printed in a large font. -@c essay @title Data Representation in Guile -@c essay @subtitle $Id: data-rep.texi,v 1.20 2006-04-16 23:11:15 kryde Exp $ -@c essay @subtitle For use with Guile @value{VERSION} -@c essay @author Jim Blandy -@c essay @author Free Software Foundation -@c essay @author @email{jimb@@red-bean.com} -@c essay @c The following two commands start the copyright page. -@c essay @page -@c essay @vskip 0pt plus 1filll -@c essay @vskip 0pt plus 1filll -@c essay Copyright @copyright{} 1998, 2006 Free Software Foundation - -@c essay Permission is granted to make and distribute verbatim copies of -@c essay this manual provided the copyright notice and this permission notice -@c essay are preserved on all copies. - -@c essay Permission is granted to copy and distribute modified versions of this -@c essay manual under the conditions for verbatim copying, provided that the entire -@c essay resulting derived work is distributed under the terms of a permission -@c essay notice identical to this one. - -@c essay Permission is granted to copy and distribute translations of this manual -@c essay into another language, under the above conditions for modified versions, -@c essay except that this permission notice may be stated in a translation approved -@c essay by Free Software Foundation. -@c essay @end titlepage - -@c essay @c @smallbook -@c essay @c @finalout -@c essay @headings double - - -@c essay @node Top, Data Representation in Scheme, (dir), (dir) -@c essay @top Data Representation in Guile - -@c essay @ifinfo -@c essay This essay is meant to provide the background necessary to read and -@c essay write C code that manipulates Scheme values in a way that conforms to -@c essay libguile's interface. If you would like to write or maintain a -@c essay Guile-based application in C or C++, this is the first information you -@c essay need. - -@c essay In order to make sense of Guile's @code{SCM_} functions, or read -@c essay libguile's source code, it's essential to have a good grasp of how Guile -@c essay actually represents Scheme values. Otherwise, a lot of the code, and -@c essay the conventions it follows, won't make very much sense. - -@c essay We assume you know both C and Scheme, but we do not assume you are -@c essay familiar with Guile's C interface. -@c essay @end ifinfo - - -@node Data Representation -@appendix Data Representation in Guile - -@strong{by Jim Blandy} - -[Due to the rather non-orthogonal and performance-oriented nature of the -SCM interface, you need to understand SCM internals *before* you can use -the SCM API. That's why this chapter comes first.] - -[NOTE: this is Jim Blandy's essay almost entirely unmodified. It has to -be adapted to fit this manual smoothly.] - -In order to make sense of Guile's SCM_ functions, or read libguile's -source code, it's essential to have a good grasp of how Guile actually -represents Scheme values. Otherwise, a lot of the code, and the -conventions it follows, won't make very much sense. This essay is meant -to provide the background necessary to read and write C code that -manipulates Scheme values in a way that is compatible with libguile. - -We assume you know both C and Scheme, but we do not assume you are -familiar with Guile's implementation. - -@menu -* Data Representation in Scheme:: Why things aren't just totally - straightforward, in general terms. -* How Guile does it:: How to write C code that manipulates - Guile values, with an explanation - of Guile's garbage collector. -@end menu - @node Data Representation in Scheme @section Data Representation in Scheme @@ -159,8 +30,8 @@ The following sections will present a simple typing system, and then make some refinements to correct its major weaknesses. However, this is not a description of the system Guile actually uses. It is only an illustration of the issues Guile's system must address. We provide all -the information one needs to work with Guile's data in @ref{How Guile -does it}. +the information one needs to work with Guile's data in @ref{The +Libguile Runtime Environment}. @menu @@ -423,22 +294,21 @@ significant loss of efficiency, but the simplified system would still be more complex than what we've presented above. -@node How Guile does it -@section How Guile does it +@node The Libguile Runtime Environment +@section The Libguile Runtime Environment Here we present the specifics of how Guile represents its data. We don't go into complete detail; an exhaustive description of Guile's system would be boring, and we do not wish to encourage people to write code which depends on its details anyway. We do, however, present -everything one need know to use Guile's data. - -This section is in limbo. It used to document the 'low-level' C API -of Guile that was used both by clients of libguile and by libguile -itself. +everything one need know to use Guile's data. It is assumed that the +reader understands the concepts laid out in @ref{Data Representation +in Scheme}. -In the future, clients should only need to look into the sections -@ref{Programming in C} and @ref{API Reference}. This section will in -the end only contain stuff about the internals of Guile. +FIXME: much of this is outdated as of 1.8, we don't provide many of +these macros any more. Also here we're missing sections about the +evaluator implementation, which is interesting, and notes about tail +recursion between scheme and c. @menu * General Rules:: @@ -1127,7 +997,7 @@ This reference can be decoded to a C pointer to a heap cell using the @code{SCM} value is done using the @code{PTR2SCM} macro. @c (FIXME:: this name should be changed) -@deftypefn Macro (scm_t_cell *) SCM2PTR (SCM @var{x}) +@deftypefn Macro {scm_t_cell *} SCM2PTR (SCM @var{x}) Extract and return the heap cell pointer from a non-immediate @code{SCM} object @var{x}. @end deftypefn diff --git a/doc/ref/effective-version.texi.in b/doc/ref/effective-version.texi.in new file mode 100644 index 000000000..80b56b751 --- /dev/null +++ b/doc/ref/effective-version.texi.in @@ -0,0 +1 @@ +@set EFFECTIVE-VERSION @GUILE_EFFECTIVE_VERSION@ diff --git a/doc/ref/expect.texi b/doc/ref/expect.texi index 05c766999..71e9a385b 100644 --- a/doc/ref/expect.texi +++ b/doc/ref/expect.texi @@ -10,9 +10,9 @@ The macros in this section are made available with: -@smalllisp +@lisp (use-modules (ice-9 expect)) -@end smalllisp +@end lisp @code{expect} is a macro for selecting actions based on the output from a port. The name comes from a tool of similar functionality by Don Libes. @@ -30,14 +30,14 @@ which is matched against each of the patterns. When a pattern matches, the remaining expression(s) in the clause are evaluated and the value of the last is returned. For example: -@smalllisp +@lisp (with-input-from-file "/etc/passwd" (lambda () (expect-strings ("^nobody" (display "Got a nobody user.\n") (display "That's no problem.\n")) ("^daemon" (display "Got a daemon user.\n"))))) -@end smalllisp +@end lisp The regular expression is compiled with the @code{REG_NEWLINE} flag, so that the ^ and $ anchors will match at any newline, not just at the start @@ -54,13 +54,13 @@ The symbol @code{=>} can be used to indicate that the expression is a procedure which will accept the result of a successful regular expression match. E.g., -@smalllisp +@lisp ("^daemon" => write) ("^d(aemon)" => (lambda args (for-each write args))) ("^da(em)on" => (lambda (all sub) (write all) (newline) (write sub) (newline))) -@end smalllisp +@end lisp The order of the substrings corresponds to the order in which the opening brackets occur. @@ -135,12 +135,12 @@ expression. In the following example, a string will only be matched at the beginning of the file: -@smalllisp +@lisp (let ((expect-port (open-input-file "/etc/passwd"))) (expect ((lambda (s eof?) (string=? s "fnord!")) (display "Got a nobody user!\n")))) -@end smalllisp +@end lisp The control variables described for @code{expect-strings} also influence the behaviour of @code{expect}, with the exception of diff --git a/doc/ref/goops-tutorial.texi b/doc/ref/goops-tutorial.texi new file mode 100644 index 000000000..600be7730 --- /dev/null +++ b/doc/ref/goops-tutorial.texi @@ -0,0 +1,819 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 2008, 2009 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@c Original attribution: + +@c +@c STk Reference manual (Appendix: An Introduction to STklos) +@c +@c Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr> +@c Permission to use, copy, modify, distribute,and license this +@c software and its documentation for any purpose is hereby granted, +@c provided that existing copyright notices are retained in all +@c copies and that this notice is included verbatim in any +@c distributions. No written agreement, license, or royalty fee is +@c required for any of the authorized uses. +@c This software is provided ``AS IS'' without express or implied +@c warranty. +@c + +@c Adapted for use in Guile with the authors permission + +@c @macro goops @c was {\stklos} +@c GOOPS +@c @end macro + +@c @macro guile @c was {\stk} +@c Guile +@c @end macro + +This section introduces the @goops{} package in more detail. It was +originally written by Erick Gallesio as an appendix for the STk +reference manual, and subsequently adapted to @goops{}. + +The procedures and syntax described in this tutorial are provided by +Guile modules that may need to be imported before being available. +The main @goops{} module is imported by evaluating: + +@lisp +(use-modules (oop goops)) +@end lisp +@findex (oop goops) +@cindex main module +@cindex loading +@cindex preparing + +@menu +* Copyright:: +* Class definition:: +* Instance creation and slot access:: +* Slot description:: +* Inheritance:: +* Generic functions:: +@end menu + +@node Copyright +@subsection Copyright + +Original attribution: + +STk Reference manual (Appendix: An Introduction to STklos) + +Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@@unice.fr> +Permission to use, copy, modify, distribute,and license this +software and its documentation for any purpose is hereby granted, +provided that existing copyright notices are retained in all +copies and that this notice is included verbatim in any +distributions. No written agreement, license, or royalty fee is +required for any of the authorized uses. +This software is provided ``AS IS'' without express or implied +warranty. + +Adapted for use in Guile with the author's permission + +@node Class definition +@subsection Class definition + +A new class is defined with the @code{define-class} macro. The syntax +of @code{define-class} is close to CLOS @code{defclass}: + +@findex define-class +@cindex class +@lisp +(define-class @var{class} (@var{superclass} @dots{}) + @var{slot-description} @dots{} + @var{class-option} @dots{}) +@end lisp + +@var{class} is the class being defined. The list of +@var{superclass}es specifies which existing classes, if any, to +inherit slots and properties from. Each @var{slot-description} gives +the name of a slot and optionally some ``properties'' of this slot; +for example its initial value, the name of a function which will +access its value, and so on. Slot descriptions and inheritance are +discussed more below. For class options, see @ref{Class Options}. +@cindex slot + +As an example, let us define a type for representing a complex number +in terms of two real numbers.@footnote{Of course Guile already +provides complex numbers, and @code{<complex>} is in fact a predefined +class in GOOPS; but the definition here is still useful as an +example.} This can be done with the following class definition: + +@lisp +(define-class <my-complex> (<number>) + r i) +@end lisp + +This binds the variable @code{<my-complex>} to a new class whose +instances will contain two slots. These slots are called @code{r} and +@code{i} and will hold the real and imaginary parts of a complex +number. Note that this class inherits from @code{<number>}, which is a +predefined class.@footnote{@code{<number>} is the direct superclass of +the predefined class @code{<complex>}; @code{<complex>} is the +superclass of @code{<real>}, and @code{<real>} is the superclass of +@code{<integer>}.} + +@node Instance creation and slot access +@subsection Instance creation and slot access + +Creation of an instance of a previously defined +class can be done with the @code{make} procedure. This +procedure takes one mandatory parameter which is the class of the +instance which must be created and a list of optional +arguments. Optional arguments are generally used to initialize some +slots of the newly created instance. For instance, the following form + +@findex make +@cindex instance +@lisp +(define c (make <my-complex>)) +@end lisp + +@noindent +will create a new @code{<my-complex>} object and will bind it to the @code{c} +Scheme variable. + +Accessing the slots of the new complex number can be done with the +@code{slot-ref} and the @code{slot-set!} primitives. @code{slot-set!} +sets the value of an object slot and @code{slot-ref} retrieves it. + +@findex slot-set! +@findex slot-ref +@lisp +@group +(slot-set! c 'r 10) +(slot-set! c 'i 3) +(slot-ref c 'r) @result{} 10 +(slot-ref c 'i) @result{} 3 +@end group +@end lisp + +Using the @code{describe} function is a simple way to see all the +slots of an object at one time: this function prints all the slots of an +object on the standard output. + +First load the module @code{(oop goops describe)}: + +@example +@code{(use-modules (oop goops describe))} +@end example + +@noindent +Then the expression + +@lisp +(describe c) +@end lisp + +@noindent +will print the following information on the standard output: + +@smalllisp +#<<my-complex> 401d8638> is an instance of class <my-complex> +Slots are: + r = 10 + i = 3 +@end smalllisp + +@node Slot description +@subsection Slot description +@c \label{slot-description} + +When specifying a slot (in a @code{(define-class @dots{})} form), +various options can be specified in addition to the slot's name. Each +option is specified by a keyword. The list of authorized keywords is +given below: + +@cindex keyword +@itemize @bullet +@item +@code{#:init-value} permits to supply a constant default value for the +slot. The value is obtained by evaluating the form given after the +@code{#:init-value} at class definition time. +@cindex default slot value +@findex #:init-value + +@item +@code{#:init-form} specifies a form that, when evaluated, will return +an initial value for the slot. The form is evaluated each time that +an instance of the class is created, in the lexical environment of the +containing @code{define-class} expression. +@cindex default slot value +@findex #:init-form + +@item +@code{#:init-thunk} permits to supply a thunk that will provide a +default value for the slot. The value is obtained by invoking the +thunk at instance creation time. +@findex default slot value +@findex #:init-thunk + +@item +@code{#:init-keyword} permits to specify a keyword for initializing the +slot. The init-keyword may be provided during instance creation (i.e. in +the @code{make} optional parameter list). Specifying such a keyword +during instance initialization will supersede the default slot +initialization possibly given with @code{#:init-form}. +@findex #:init-keyword + +@item +@code{#:getter} permits to supply the name for the +slot getter. The name binding is done in the +environment of the @code{define-class} macro. +@findex #:getter +@cindex top level environment +@cindex getter + +@item +@code{#:setter} permits to supply the name for the +slot setter. The name binding is done in the +environment of the @code{define-class} macro. +@findex #:setter +@cindex top level environment +@cindex setter + +@item +@code{#:accessor} permits to supply the name for the +slot accessor. The name binding is done in the global +environment. An accessor permits to get and +set the value of a slot. Setting the value of a slot is done with the extended +version of @code{set!}. +@findex set! +@findex #:accessor +@cindex top level environment +@cindex accessor + +@item +@code{#:allocation} permits to specify how storage for +the slot is allocated. Three kinds of allocation are provided. +They are described below: + +@itemize @minus +@item +@code{#:instance} indicates that each instance gets its own storage for +the slot. This is the default. +@item +@code{#:class} indicates that there is one storage location used by all +the direct and indirect instances of the class. This permits to define a +kind of global variable which can be accessed only by (in)direct +instances of the class which defines this slot. +@item +@code{#:each-subclass} indicates that there is one storage location used +by all the direct instances of the class. In other words, if two classes +are not siblings in the class hierarchy, they will not see the same +value. +@item +@code{#:virtual} indicates that no storage will be allocated for this +slot. It is up to the user to define a getter and a setter function for +this slot. Those functions must be defined with the @code{#:slot-ref} +and @code{#:slot-set!} options. See the example below. +@findex #:slot-set! +@findex #:slot-ref +@findex #:virtual +@findex #:class +@findex #:each-subclass +@findex #:instance +@findex #:allocation +@end itemize +@end itemize + +To illustrate slot description, we shall redefine the @code{<my-complex>} class +seen before. A definition could be: + +@lisp +(define-class <my-complex> (<number>) + (r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r) + (i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i)) +@end lisp + +With this definition, the @code{r} and @code{i} slot are set to 0 by +default. Value of a slot can also be specified by calling @code{make} +with the @code{#:r} and @code{#:i} keywords. Furthermore, the generic +functions @code{get-r} and @code{set-r!} (resp. @code{get-i} and +@code{set-i!}) are automatically defined by the system to read and write +the @code{r} (resp. @code{i}) slot. + +@lisp +(define c1 (make <my-complex> #:r 1 #:i 2)) +(get-r c1) @result{} 1 +(set-r! c1 12) +(get-r c1) @result{} 12 +(define c2 (make <my-complex> #:r 2)) +(get-r c2) @result{} 2 +(get-i c2) @result{} 0 +@end lisp + +Accessors provide an uniform access for reading and writing an object +slot. Writing a slot is done with an extended form of @code{set!} +which is close to the Common Lisp @code{setf} macro. So, another +definition of the previous @code{<my-complex>} class, using the +@code{#:accessor} option, could be: + +@findex set! +@lisp +(define-class <my-complex> (<number>) + (r #:init-value 0 #:accessor real-part #:init-keyword #:r) + (i #:init-value 0 #:accessor imag-part #:init-keyword #:i)) +@end lisp + +Using this class definition, reading the real part of the @code{c} +complex can be done with: +@lisp +(real-part c) +@end lisp +and setting it to the value contained in the @code{new-value} variable +can be done using the extended form of @code{set!}. +@lisp +(set! (real-part c) new-value) +@end lisp + +Suppose now that we have to manipulate complex numbers with rectangular +coordinates as well as with polar coordinates. One solution could be to +have a definition of complex numbers which uses one particular +representation and some conversion functions to pass from one +representation to the other. A better solution uses virtual slots. A +complete definition of the @code{<my-complex>} class using virtual slots is +given in Figure@ 2. + +@example +@group +@lisp +(define-class <my-complex> (<number>) + ;; True slots use rectangular coordinates + (r #:init-value 0 #:accessor real-part #:init-keyword #:r) + (i #:init-value 0 #:accessor imag-part #:init-keyword #:i) + ;; Virtual slots access do the conversion + (m #:accessor magnitude #:init-keyword #:magn + #:allocation #:virtual + #:slot-ref (lambda (o) + (let ((r (slot-ref o 'r)) (i (slot-ref o 'i))) + (sqrt (+ (* r r) (* i i))))) + #:slot-set! (lambda (o m) + (let ((a (slot-ref o 'a))) + (slot-set! o 'r (* m (cos a))) + (slot-set! o 'i (* m (sin a)))))) + (a #:accessor angle #:init-keyword #:angle + #:allocation #:virtual + #:slot-ref (lambda (o) + (atan (slot-ref o 'i) (slot-ref o 'r))) + #:slot-set! (lambda(o a) + (let ((m (slot-ref o 'm))) + (slot-set! o 'r (* m (cos a))) + (slot-set! o 'i (* m (sin a))))))) + +@end lisp +@center @emph{Fig 2: A @code{<my-complex>} number class definition using virtual slots} +@end group +@end example + +@sp 3 +This class definition implements two real slots (@code{r} and +@code{i}). Values of the @code{m} and @code{a} virtual slots are +calculated from real slot values. Reading a virtual slot leads to the +application of the function defined in the @code{#:slot-ref} +option. Writing such a slot leads to the application of the function +defined in the @code{#:slot-set!} option. For instance, the following +expression + +@findex #:slot-set! +@findex #:slot-ref +@lisp +(slot-set! c 'a 3) +@end lisp + +permits to set the angle of the @code{c} complex number. This expression +conducts, in fact, to the evaluation of the following expression + +@lisp +((lambda o m) + (let ((m (slot-ref o 'm))) + (slot-set! o 'r (* m (cos a))) + (slot-set! o 'i (* m (sin a)))) + c 3) +@end lisp + +A more complete example is given below: + +@example +@group +@smalllisp +(define c (make <my-complex> #:r 12 #:i 20)) +(real-part c) @result{} 12 +(angle c) @result{} 1.03037682652431 +(slot-set! c 'i 10) +(set! (real-part c) 1) +(describe c) +@print{} +#<<my-complex> 401e9b58> is an instance of class <my-complex> +Slots are: + r = 1 + i = 10 + m = 10.0498756211209 + a = 1.47112767430373 +@end smalllisp +@end group +@end example + +Since initialization keywords have been defined for the four slots, we +can now define the @code{make-rectangular} and @code{make-polar} standard +Scheme primitives. + +@lisp +(define make-rectangular + (lambda (x y) (make <my-complex> #:r x #:i y))) + +(define make-polar + (lambda (x y) (make <my-complex> #:magn x #:angle y))) +@end lisp + +@node Inheritance +@subsection Inheritance +@c \label{inheritance} + +@menu +* Class hierarchy and inheritance of slots:: +* Class precedence list:: +@end menu + +@node Class hierarchy and inheritance of slots +@subsubsection Class hierarchy and inheritance of slots +Inheritance is specified upon class definition. As said in the +introduction, @goops{} supports multiple inheritance. Here are some +class definitions: + +@lisp +(define-class A () a) +(define-class B () b) +(define-class C () c) +(define-class D (A B) d a) +(define-class E (A C) e c) +(define-class F (D E) f) +@end lisp + +@code{A}, @code{B}, @code{C} have a null list of super classes. In this +case, the system will replace it by the list which only contains +@code{<object>}, the root of all the classes defined by +@code{define-class}. @code{D}, @code{E}, @code{F} use multiple +inheritance: each class inherits from two previously defined classes. +Those class definitions define a hierarchy which is shown in Figure@ 1. +In this figure, the class @code{<top>} is also shown; this class is the +super class of all Scheme objects. In particular, @code{<top>} is the +super class of all standard Scheme types. + +@example +@group +@image{hierarchy} +@center @emph{Fig 1: A class hierarchy} +@iftex +@emph{(@code{<complex>} which is the direct subclass of @code{<number>} +and the direct superclass of @code{<real>} has been omitted in this +figure.)} +@end iftex +@end group +@end example + +The set of slots of a given class is calculated by taking the union of the +slots of all its super class. For instance, each instance of the class +D, defined before will have three slots (@code{a}, @code{b} and +@code{d}). The slots of a class can be obtained by the @code{class-slots} +primitive. For instance, + +@lisp +(class-slots A) @result{} ((a)) +(class-slots E) @result{} ((a) (e) (c)) +(class-slots F) @result{} ((e) (c) (b) (d) (a) (f)) +@c used to be ((d) (a) (b) (c) (f)) +@end lisp + +@emph{Note: } The order of slots is not significant. + +@node Class precedence list +@subsubsection Class precedence list + +A class may have more than one superclass. @footnote{This section is an +adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief +introduction to CLOS}} With single inheritance (one superclass), it is +easy to order the super classes from most to least specific. This is the +rule: + +@display +@cartouche +Rule 1: Each class is more specific than its superclasses.@c was \bf +@end cartouche +@end display + +With multiple inheritance, ordering is harder. Suppose we have + +@lisp +(define-class X () + (x #:init-value 1)) + +(define-class Y () + (x #:init-value 2)) + +(define-class Z (X Y) + (@dots{})) +@end lisp + +In this case, the @code{Z} class is more specific than the @code{X} or +@code{Y} class for instances of @code{Z}. However, the @code{#:init-value} +specified in @code{X} and @code{Y} leads to a problem: which one +overrides the other? The rule in @goops{}, as in CLOS, is that the +superclasses listed earlier are more specific than those listed later. +So: + +@display +@cartouche +Rule 2: For a given class, superclasses listed earlier are more + specific than those listed later. +@end cartouche +@end display + +These rules are used to compute a linear order for a class and all its +superclasses, from most specific to least specific. This order is +called the ``class precedence list'' of the class. Given these two +rules, we can claim that the initial form for the @code{x} slot of +previous example is 1 since the class @code{X} is placed before @code{Y} +in class precedence list of @code{Z}. + +These two rules are not always enough to determine a unique order, +however, but they give an idea of how things work. Taking the @code{F} +class shown in Figure@ 1, the class precedence list is + +@example +(f d e a c b <object> <top>) +@end example + +However, it is usually considered a bad idea for programmers to rely on +exactly what the order is. If the order for some superclasses is important, +it can be expressed directly in the class definition. + +The precedence list of a class can be obtained by the function +@code{class-precedence-list}. This function returns a ordered +list whose first element is the most specific class. For instance, + +@lisp +(class-precedence-list B) @result{} (#<<class> B 401b97c8> + #<<class> <object> 401e4a10> + #<<class> <top> 4026a9d8>) +@end lisp + +However, this result is not too much readable; using the function +@code{class-name} yields a clearer result: + +@lisp +(map class-name (class-precedence-list B)) @result{} (B <object> <top>) +@end lisp + +@node Generic functions +@subsection Generic functions + +@menu +* Generic functions and methods:: +* Next-method:: +* Example:: +@end menu + +@node Generic functions and methods +@subsubsection Generic functions and methods + +@c \label{gf-n-methods} +Neither @goops{} nor CLOS use the message mechanism for methods as most +Object Oriented language do. Instead, they use the notion of +@dfn{generic functions}. A generic function can be seen as a methods +``tanker''. When the evaluator requested the application of a generic +function, all the methods of this generic function will be grabbed and +the most specific among them will be applied. We say that a method +@var{M} is @emph{more specific} than a method @var{M'} if the class of +its parameters are more specific than the @var{M'} ones. To be more +precise, when a generic function must be ``called'' the system will: + +@cindex generic function +@enumerate +@item +search among all the generic function those which are applicable +@item +sort the list of applicable methods in the ``most specific'' order +@item +call the most specific method of this list (i.e. the first method of +the sorted methods list). +@end enumerate + +The definition of a generic function is done with the +@code{define-generic} macro. Definition of a new method is done with the +@code{define-method} macro. Note that @code{define-method} automatically +defines the generic function if it has not been defined +before. Consequently, most of the time, the @code{define-generic} needs +not be used. +@findex define-generic +@findex define-method +Consider the following definitions: + +@lisp +(define-generic G) +(define-method (G (a <integer>) b) 'integer) +(define-method (G (a <real>) b) 'real) +(define-method (G a b) 'top) +@end lisp + +The @code{define-generic} call defines @var{G} as a generic +function. Note that the signature of the generic function is not given +upon definition, contrarily to CLOS. This will permit methods with +different signatures for a given generic function, as we shall see +later. The three next lines define methods for the @var{G} generic +function. Each method uses a sequence of @dfn{parameter specializers} +that specify when the given method is applicable. A specializer permits +to indicate the class a parameter must belong to (directly or +indirectly) to be applicable. If no specializer is given, the system +defaults it to @code{<top>}. Thus, the first method definition is +equivalent to + +@cindex parameter specializers +@lisp +(define-method (G (a <integer>) (b <top>)) 'integer) +@end lisp + +Now, let us look at some possible calls to generic function @var{G}: + +@lisp +(G 2 3) @result{} integer +(G 2 #t) @result{} integer +(G 1.2 'a) @result{} real +@c (G #3 'a) @result{} real @c was {\sharpsign} +(G #t #f) @result{} top +(G 1 2 3) @result{} error (since no method exists for 3 parameters) +@end lisp + +The preceding methods use only one specializer per parameter list. Of +course, each parameter can use a specializer. In this case, the +parameter list is scanned from left to right to determine the +applicability of a method. Suppose we declare now + +@lisp +(define-method (G (a <integer>) (b <number>)) 'integer-number) +(define-method (G (a <integer>) (b <real>)) 'integer-real) +(define-method (G (a <integer>) (b <integer>)) 'integer-integer) +(define-method (G a (b <number>)) 'top-number) +@end lisp + +In this case, + +@lisp +(G 1 2) @result{} integer-integer +(G 1 1.0) @result{} integer-real +(G 1 #t) @result{} integer +(G 'a 1) @result{} top-number +@end lisp + +@node Next-method +@subsubsection Next-method + +When you call a generic function, with a particular set of arguments, +GOOPS builds a list of all the methods that are applicable to those +arguments and orders them by how closely the method definitions match +the actual argument types. It then calls the method at the top of this +list. If the selected method's code wants to call on to the next method +in this list, it can do so by using @code{next-method}. + +@lisp +(define-method (Test (a <integer>)) (cons 'integer (next-method))) +(define-method (Test (a <number>)) (cons 'number (next-method))) +(define-method (Test a) (list 'top)) +@end lisp + +With these definitions, + +@lisp +(Test 1) @result{} (integer number top) +(Test 1.0) @result{} (number top) +(Test #t) @result{} (top) +@end lisp + +@code{next-method} is always called as just @code{(next-method)}. The +arguments for the next method call are always implicit, and always the +same as for the original method call. + +If you want to call on to a method with the same name but with a +different set of arguments (as you might with overloaded methods in C++, +for example), you do not use @code{next-method}, but instead simply +write the new call as usual: + +@lisp +(define-method (Test (a <number>) min max) + (if (and (>= a min) (<= a max)) + (display "Number is in range\n")) + (Test a)) + +(Test 2 1 10) +@print{} +Number is in range +@result{} +(integer number top) +@end lisp + +(You should be careful in this case that the @code{Test} calls do not +lead to an infinite recursion, but this consideration is just the same +as in Scheme code in general.) + +@node Example +@subsubsection Example + +In this section we shall continue to define operations on the @code{<my-complex>} +class defined in Figure@ 2. Suppose that we want to use it to implement +complex numbers completely. For instance a definition for the addition of +two complexes could be + +@lisp +(define-method (new-+ (a <my-complex>) (b <my-complex>)) + (make-rectangular (+ (real-part a) (real-part b)) + (+ (imag-part a) (imag-part b)))) +@end lisp + +To be sure that the @code{+} used in the method @code{new-+} is the standard +addition we can do: + +@lisp +(define-generic new-+) + +(let ((+ +)) + (define-method (new-+ (a <my-complex>) (b <my-complex>)) + (make-rectangular (+ (real-part a) (real-part b)) + (+ (imag-part a) (imag-part b))))) +@end lisp + +The @code{define-generic} ensures here that @code{new-+} will be defined +in the global environment. Once this is done, we can add methods to the +generic function @code{new-+} which make a closure on the @code{+} +symbol. A complete writing of the @code{new-+} methods is shown in +Figure@ 3. + +@example +@group +@lisp +(define-generic new-+) + +(let ((+ +)) + + (define-method (new-+ (a <real>) (b <real>)) (+ a b)) + + (define-method (new-+ (a <real>) (b <my-complex>)) + (make-rectangular (+ a (real-part b)) (imag-part b))) + + (define-method (new-+ (a <my-complex>) (b <real>)) + (make-rectangular (+ (real-part a) b) (imag-part a))) + + (define-method (new-+ (a <my-complex>) (b <my-complex>)) + (make-rectangular (+ (real-part a) (real-part b)) + (+ (imag-part a) (imag-part b)))) + + (define-method (new-+ (a <number>)) a) + + (define-method (new-+) 0) + + (define-method (new-+ . args) + (new-+ (car args) + (apply new-+ (cdr args))))) + +(set! + new-+) +@end lisp + +@center @emph{Fig 3: Extending @code{+} for dealing with complex numbers} +@end group +@end example + +@sp 3 +We use here the fact that generic function are not obliged to have the +same number of parameters, contrarily to CLOS. The four first methods +implement the dyadic addition. The fifth method says that the addition +of a single element is this element itself. The sixth method says that +using the addition with no parameter always return 0. The last method +takes an arbitrary number of parameters@footnote{The parameter list for +a @code{define-method} follows the conventions used for Scheme +procedures. In particular it can use the dot notation or a symbol to +denote an arbitrary number of parameters}. This method acts as a kind +of @code{reduce}: it calls the dyadic addition on the @emph{car} of the +list and on the result of applying it on its rest. To finish, the +@code{set!} permits to redefine the @code{+} symbol to our extended +addition. + +@sp 3 +To terminate our implementation (integration?) of complex numbers, we can +redefine standard Scheme predicates in the following manner: + +@lisp +(define-method (complex? c <my-complex>) #t) +(define-method (complex? c) #f) + +(define-method (number? n <number>) #t) +(define-method (number? n) #f) +@dots{} +@dots{} +@end lisp + +Standard primitives in which complex numbers are involved could also be +redefined in the same manner. + diff --git a/doc/ref/goops.texi b/doc/ref/goops.texi new file mode 100644 index 000000000..c0a828f71 --- /dev/null +++ b/doc/ref/goops.texi @@ -0,0 +1,2790 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 2008, 2009 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@macro goops +GOOPS +@end macro + +@macro guile +Guile +@end macro + +@node GOOPS +@chapter GOOPS + +@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}). + +@menu +* Quick Start:: +* Tutorial:: +* Reference Manual:: +* MOP Specification:: +@end menu + +@node Quick Start +@section Quick Start + +To give an immediate flavour of what GOOPS can do, here is a very +brief introduction to its main operations. + +To start using GOOPS, load the @code{(oop goops)} module: + +@lisp +(use-modules (oop goops)) +@end lisp + +We're now ready to try some basic GOOPS functionality. + +@menu +* Methods:: +* User-defined types:: +* Asking for the type of an object:: +@end menu + +@node Methods +@subsection Methods + +A GOOPS method is like a Scheme procedure except that it is +specialized for a particular set of argument types. + +@lisp +(define-method (+ (x <string>) (y <string>)) + (string-append x y)) + +(+ "abc" "de") @result{} "abcde" +@end lisp + +If @code{+} is used with arguments that do not match the method's +types, Guile falls back to using the normal Scheme @code{+} procedure. + +@lisp +(+ 1 2) @result{} 3 +@end lisp + + +@node User-defined types +@subsection User-defined types + +@lisp +(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) + (format port "<~S, ~S>" (x-component obj) (y-component obj))) + +(define v (make <2D-vector> #:x 3 #:y 4)) + +v @result{} <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) @result{} <6, 8> +@end group +@end lisp + +@node Asking for the type of an object +@subsection Types + +@example +(class-of v) @result{} #<<class> <2D-vector> 40241ac0> +<2D-vector> @result{} #<<class> <2D-vector> 40241ac0> +(class-of 1) @result{} #<<class> <integer> 401b2a98> +<integer> @result{} #<<class> <integer> 401b2a98> + +(is-a? v <2D-vector>) @result{} #t +@end example + +@node Tutorial +@section Tutorial +@include goops-tutorial.texi + +@node Reference Manual +@section 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 +@subsection 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 +subsubsections 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 subsubsection on a first reading, +and should correspondingly skip subsequent subsubsections 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 are less well known, so the Terminology subsubsection +provides definitions for these terms. + +@menu +* Metaobjects and the Metaobject Protocol:: +* Terminology:: +@end menu + +@node Metaobjects and the Metaobject Protocol +@subsubsection 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{<class>}, 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{<class>}, 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{<class>}, 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{<class>}. + +It is possible to create a new class that inherits from @code{<class>}, +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{<class>}, 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{<generic>}, 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 subsubsection 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{<class>} or @code{<generic>}. (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 +@subsubsection 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. + +@subsubheading 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{<class>} and, by default, +any new class that is created using @code{define-class} has the +metaclass @code{<class>}. + +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 <my-class> (<object>) . slots) +@end example + +GOOPS actually expands the @code{define-class} form to something like +this + +@example +(define <my-class> (class (<object>) . slots)) +@end example + +and thence to + +@example +(define <my-class> + (make <class> #:supers (list <object>) #:slots slots)) +@end example + +In other words, the value of @code{<my-class>} is in fact an instance of +the class @code{<class>} with slot values specifying the superclasses +and slot definitions for the class @code{<my-class>}. (@code{#:supers} +and @code{#:slots} are initialization keywords for the @code{dsupers} +and @code{dslots} slots of the @code{<class>} 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{<class>}. This is done by writing: + +@example +(define-class <my-class2> (<object>) + slot @dots{} + #:metaclass <my-metaclass>) +@end example + +GOOPS expands this to something like: + +@example +(define <my-class2> + (make <my-metaclass> #:supers (list <object>) #:slots slots)) +@end example + +In this case, the value of @code{<my-class2>} is an instance of the more +specialized class @code{<my-metaclass>}. Note that +@code{<my-metaclass>} itself must previously have been defined as a +subclass of @code{<class>}. 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{<my-class2>}: + +@example +(define my-object (make <my-class2> ...)) +@end example + +All of the following statements are correct expressions of the +relationships between @code{my-object}, @code{<my-class2>}, +@code{<my-metaclass>} and @code{<class>}. + +@itemize @bullet +@item +@code{my-object} is an instance of the class @code{<my-class2>}. + +@item +@code{<my-class2>} is an instance of the class @code{<my-metaclass>}. + +@item +@code{<my-metaclass>} is an instance of the class @code{<class>}. + +@item +The class of @code{my-object} is @code{<my-class2>}. + +@item +The metaclass of @code{my-object} is @code{<my-metaclass>}. + +@item +The class of @code{<my-class2>} is @code{<my-metaclass>}. + +@item +The metaclass of @code{<my-class2>} is @code{<class>}. + +@item +The class of @code{<my-metaclass>} is @code{<class>}. + +@item +The metaclass of @code{<my-metaclass>} is @code{<class>}. + +@item +@code{<my-class2>} is not a metaclass, since it is does not inherit from +@code{<class>}. + +@item +@code{<my-metaclass>} is a metaclass, since it inherits from +@code{<class>}. +@end itemize + +@subsubheading 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{<top>}. + +For example, given this inheritance hierarchy: + +@example +(define-class <invertebrate> (<object>) @dots{}) +(define-class <echinoderm> (<invertebrate>) @dots{}) +(define-class <starfish> (<echinoderm>) @dots{}) +@end example + +the class precedence list of <starfish> would be + +@example +(<starfish> <echinoderm> <invertebrate> <object> <top>) +@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}. + +@subsubheading 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 <square>)) + (* 4 (side-length s))) +@end example + +Setter methods for an accessor are defined by specifying ``(setter +<accessor-name>)'' as the first parameter of the @code{define-method} +call. + +@example +(define-method ((setter perimeter) (s <square>) (n <number>)) + (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 +@subsection 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 +@subsubsection 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 +subsubsections: 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 <combined> (<tree> <bicycle>)) +@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 <regular-polygon> () + (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 <tcpip-fsm> () + (s #:init-value #f #:accessor state) + ... + #:metaclass <finite-state-class>) +@end example + +@node Class Options +@subsubsection 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{<class>}. For an introduction to the use of metaclasses, see +@ref{Metaobjects and the Metaobject Protocol} and @ref{Terminology}. + +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 +@subsubsection 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 (shared across all new instances of the class). +@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. + +Note that, since an @code{init-value} value is shared across all +instances of a class, you should only use it when the initial value is +an immutable value, like a constant. If you want to initialize a slot +with a fresh, independently mutable value, you should use +@code{init-thunk} or @code{init-form} instead. Consider the following +example. + +@example +(define-class <chbouib> () + (hashtab #:init-value (make-hash-table))) +@end example + +@noindent +Here only one hash table is created and all instances of +@code{<chbouib>} have their @code{hashtab} slot refer to it. In order +to have each instance of @code{<chbouib>} refer to a new hash table, you +should instead write: + +@example +(define-class <chbouib> () + (hashtab #:init-thunk make-hash-table)) +@end example + +@noindent +or: + +@example +(define-class <chbouib> () + (hashtab #:init-form (make-hash-table))) +@end example + +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 <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 +@subsubsection 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{<object>} to the @var{supers} list if @var{supers} is empty +or if none of the classes in @var{supers} have @code{<object>} 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{<class>}, the returned metaclass is just +@code{<class>}. + +For a more complex example, suppose that @var{supers} contained one +class with metaclass @code{<operator-class>} and one with metaclass +@code{<foreign-object-class>}. Then the returned metaclass would be a +class that inherits from both @code{<operator-class>} and +@code{<foreign-object-class>}. + +If @var{supers} is the empty list, @code{ensure-metaclass} returns the +default GOOPS metaclass @code{<class>}. + +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 +@subsubsection 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{<class>} 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{<class>}, then the type of @var{class} in the calls above +is more specialized than @code{<class>}, 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{<class>}, 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 <batched-allocation-metaclass> (<class>)) + +(let ((batch-allocation-count 0) + (batch-get-n-set #f)) + (define-method (compute-get-n-set + (class <batched-allocation-metaclass>) 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 <class-using-batched-slot> () + ... + (c #:allocation #:batched) + ... + #:metaclass <batched-allocation-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{<class>}. 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 +@subsubsection 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 +@subsection Creating Instances + +@menu +* Basic Instance Creation:: +* Customizing Instance Creation:: +@end menu + +@node Basic Instance Creation +@subsubsection 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 <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 <class>) . initargs +@code{make-instance} is an alias for @code{make}. +@end deffn + +@node Customizing Instance Creation +@subsubsection 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{<class>}, by +defining a @code{make} method that is specialized to that metaclass. + +Normally, however, the method for classes with metaclass @code{<class>} +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{<object>} 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{<class>} 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 +@subsection 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 +subsubsections. For example, + +@example +(define-class <my-class> () ;; Define a class with slots + (count #:init-value 0) ;; named "count" and "cache". + (cache #:init-value '()) + @dots{}) + +(define inst (make <my-class>)) ;; 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 <adv-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 <adv-class>)) ;; 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 +@subsubsection 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 +@subsubsection 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 +@subsubsection 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 <class>) slot-name +@deffnx method slot-missing (class <class>) (object <object>) slot-name +@deffnx method slot-missing (class <class>) (object <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 <object>) +@deffnx method slot-unbound (class <class>) slot-name +@deffnx method slot-unbound (class <class>) (object <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 +@subsection 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{<generic>} (or one of its subclasses). + +@menu +* Basic Generic Function Creation:: +* Generic Function Internals:: +* Extending Guiles Primitives:: +@end menu + +@node Basic Generic Function Creation +@subsubsection 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 + +It is sometimes tempting to use GOOPS accessors with short names. For +example, it is tempting to use the name @code{x} for the x-coordinate +in vector packages. + +Assume that we work with a graphical package which needs to use two +independent vector packages for 2D and 3D vectors respectively. If +both packages export @code{x} we will encounter a name collision. + +This can be resolved automagically with the duplicates handler +@code{merge-generics} which gives the module system license to merge +all generic functions sharing a common name: + +@lisp +(define-module (math 2D-vectors) + #:use-module (oop goops) + #:export (x y ...)) + +(define-module (math 3D-vectors) + #:use-module (oop goops) + #:export (x y z ...)) + +(define-module (my-module) + #:use-module (math 2D-vectors) + #:use-module (math 3D-vectors) + #:duplicates merge-generics) +@end lisp + +The generic function @code{x} in @code{(my-module)} will now share +methods with @code{x} in both imported modules. + +There will, in fact, now be three distinct generic functions named +@code{x}: @code{x} in @code{(2D-vectors)}, @code{x} in +@code{(3D-vectors)}, and @code{x} in @code{(my-module)}. The last +function will be an @code{<extended-generic>}, extending the previous +two functions. + +Let's call the imported generic functions the "ancestor functions". +The generic function @code{x} in @code{(my-module)} is, in turn, a +"descendant function" of the imported functions, extending its +ancestors. + +For any generic function G, the applicable methods are selected from +the union of the methods of the descendant functions, the methods of G +itself and the methods of the ancestor functions. + +This, ancestor functions share methods with their descendants and vice +versa. This implies that @code{x} in @code{(math 2D-vectors)} will +share the methods of @code{x} in @code{(my-module)} and vice versa, +while @code{x} in @code{(math 2D-vectors)} doesn't share the methods +of @code{x} in @code{(math 3D-vectors)}, thus preserving modularity. + +Sharing is dynamic, so that adding new methods to a descendant implies +adding it to the ancestor. + +If duplicates checking is desired in the above example, the following +form of the @code{#:duplicates} option can be used instead: + +@lisp + #:duplicates (merge-generics check) +@end lisp + +@node Generic Function Internals +@subsubsection Generic Function Internals + +@code{define-generic} calls @code{ensure-generic} to upgrade a +pre-existing procedure value, or @code{make} with metaclass +@code{<generic>} 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{<generic>} and @code{<generic-with-setter>}, 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{<generic>}. + +@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{<generic-with-setter>}, 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{<generic>} to create a generic function for the +setter, then with metaclass @code{<generic-with-setter>} to create the +accessor, passing the setter generic function as the value of the +@code{#:setter} keyword. + +@node Extending Guiles Primitives +@subsubsection 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 +@subsection Adding Methods to Generic Functions + +@menu +* Basic Method Definition:: +* Method Definition Internals:: +@end menu + +@node Basic Method Definition +@subsubsection 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{<top>}, 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 <square>) (n <number>))}, 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{<square>} 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 +@subsubsection 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{<top>} + +@item +creates a closure using the formals and the @var{body} forms + +@item +calls @code{make} with metaclass @code{<method>} 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{<method>}. + +@deffn generic add-method! target method +Generic function for adding method @var{method} to @var{target}. +@end deffn + +@deffn method add-method! (generic <generic>) (method <method>) +Add method @var{method} to the generic function @var{generic}. +@end deffn + +@deffn method add-method! (proc <procedure>) (method <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 <primitive-generic>) (method <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 <top>) (method <method>) +Raise an error indicating that @var{whatever} is not a valid generic +function. +@end deffn + +@node Invoking Generic Functions +@subsection 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 +@subsubsection 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 <generic>) args +@end deffn + +@deffn generic compute-applicable-methods +@deffnx method compute-applicable-methods (gf <generic>) args +@end deffn + +@deffn generic sort-applicable-methods +@deffnx method sort-applicable-methods (gf <generic>) methods args +@end deffn + +@deffn generic method-more-specific? +@deffnx method method-more-specific? (m1 <method>) (m2 <method>) args +@end deffn + +@deffn generic apply-method +@deffnx method apply-method (gf <generic>) methods build-next args +@end deffn + +@deffn generic apply-methods +@deffnx method apply-methods (gf <generic>) (l <list>) args +@end deffn + +@node Handling Invocation Errors +@subsubsection Handling Invocation Errors + +@deffn generic no-method +@deffnx method no-method (gf <generic>) 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 <generic>) 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 <generic>) 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 +@subsection Redefining a Class + +Suppose that a class @code{<my-class>} 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{<my-class>} using @code{make} (@pxref{Basic Instance Creation,, +make}). What then happens if @code{<my-class>} is redefined by calling +@code{define-class} again? + +@menu +* Default Class Redefinition Behaviour:: +* Customizing Class Redefinition:: +@end menu + +@node Default Class Redefinition Behaviour +@subsubsection Default Class Redefinition Behaviour + +GOOPS' default answer to this question is as follows. + +@itemize @bullet +@item +All existing direct instances of @code{<my-class>} 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{<my-class>} are redefined, as though +the @code{define-class} expressions that defined them were re-evaluated +following the redefinition of @code{<my-class>}, 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{<my-class>} 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{<my-class>} metaobject +as one of its formal parameter specializers must be updated to refer to +the new @code{<my-class>} 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 +@subsubsection 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>}, 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 <class>) (new-class <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 <can-be-nameless> (<class>)) + +(define-method (class-redefinition (old <can-be-nameless>) + (new <class>)) + 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 +@subsection 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 <object>) (new <class>) +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 +@subsection 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 +@subsubsection 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 +@subsubsection 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 +@subsubsection 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 +@subsubsection 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 +@subsubsection 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 <method>) +Return an expression that prints to show the definition of method +@var{m}. + +@example +(define-generic cube) + +(define-method (cube (n <number>)) + (* n n n)) + +(map method-source (generic-function-methods cube)) +@result{} +((method ((n <number>)) (* n n n))) +@end example +@end deffn + +@node Miscellaneous Functions +@subsection Miscellaneous Functions + +@menu +* Administrative Functions:: +* GOOPS Error Handling:: +* Object Comparisons:: +* Cloning Objects:: +* Write and Display:: +@end menu + +@node Administrative Functions +@subsubsection 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 GOOPS Error Handling +@subsubsection 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 +@subsubsection Object Comparisons + +@deffn generic eqv? +@deffnx method eqv? ((x <top>) (y <top>)) +@deffnx generic equal? +@deffnx method equal? ((x <top>) (y <top>)) +@deffnx generic = +@deffnx method = ((x <number>) (y <number>)) +Generic functions and default (unspecialized) methods for comparing two +GOOPS objects. + +The default method for @code{eqv?} returns @code{#t} for all values +that are equal in the sense defined by R5RS and the Guile reference +manual, otherwise @code{#f}. The default method for @code{equal?} +returns @code{#t} or @code{#f} in the sense defined by R5RS and the +Guile reference manual. If no such comparison is defined, +@code{equal?} returns the result of a call to @code{eqv?}. The +default method for = returns @code{#t} if @var{x} and @var{y} are +numerically equal, otherwise @code{#f}. + +Application class authors may wish to define specialized methods for +@code{eqv?}, @code{equal?} and @code{=} that compare instances of the +same class for equality in whatever sense is useful to the +application. Such methods will only be called if the arguments have +the same class and the result of the comparison isn't defined by R5RS +and the Guile reference manual. +@end deffn + +@node Cloning Objects +@subsubsection Cloning Objects + +@deffn generic shallow-clone +@deffnx method shallow-clone (self <object>) +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 <object>) +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 +@subsubsection 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{<object>} + +@item +foreign objects - instances of the class @code{<foreign-object>} + +@item +classes - instances of the class @code{<class>} + +@item +generic functions - instances of the class @code{<generic>} + +@item +methods - instances of the class @code{<method>}. +@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 +@section 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 <generic> #: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 +@subsection 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{<class>}. + +@code{initialize <class> @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 +@subsection Instance Creation + +@code{make <class> . @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 +@subsection Class Redefinition + +The default @code{class-redefinition} method, specialized for classes +with the default metaclass @code{<class>}, has the following internal +protocol. + +@code{class-redefinition (@var{old <class>}) (@var{new <class>})} +(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 + +This protocol cleans up things that the definition of the old class +once changed and modifies things to work with the new class. + +The default @code{remove-class-accessors!} method removes the +accessor methods of the old class from all classes which they +specialize. + +The default @code{update-direct-method!} method substitutes the new +class for the old in all methods specialized to the old class. + +The default @code{update-direct-subclass!} method invokes +@code{class-redefinition} recursively to handle the redefinition of +subclasses. + +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}. + +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 <object>}) (@var{new <class>})} (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 +@subsection 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 +@subsection 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 diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi index 2ae3d6332..332be361b 100644 --- a/doc/ref/guile.texi +++ b/doc/ref/guile.texi @@ -4,22 +4,21 @@ @setfilename guile.info @settitle Guile Reference Manual @set guile -@set MANUAL-EDITION 1.1 +@set MANUAL-REVISION 1 @c %**end of header @include version.texi @include lib-version.texi +@include effective-version.texi @copying -This reference manual documents Guile, GNU's Ubiquitous Intelligent -Language for Extensions. This is edition @value{MANUAL-EDITION} -corresponding to Guile @value{VERSION}. +This manual documents Guile version @value{VERSION}. -Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005 Free +Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2009 Free Software Foundation. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or -any later version published by the Free Software Foundation; with the +any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' and with the Back-Cover Text ``You are free to copy and modify this GNU Manual.''. A copy of the license is included in the @@ -137,7 +136,7 @@ x @sp 10 @comment The title is printed in a large font. @title Guile Reference Manual -@subtitle Edition @value{MANUAL-EDITION}, for use with Guile @value{VERSION} +@subtitle Edition @value{EDITION}, revision @value{MANUAL-REVISION}, for use with Guile @value{VERSION} @c @subtitle $Id: guile.texi,v 1.49 2008-03-19 22:51:23 ossau Exp $ @c See preface.texi for the list of authors @@ -177,11 +176,14 @@ x * Guile Modules:: +* GOOPS:: + +* Guile Implementation:: + * Autoconf Support:: Appendices -* Data Representation:: All the details. * GNU Free Documentation License:: The license of this manual. Indices @@ -252,7 +254,9 @@ different ways to design a program around Guile, or how to embed Guile into existing programs. There is also a pedagogical yet detailed explanation of how the data -representation of Guile is implemented, @xref{Data Representation}. +representation of Guile is implemented, see @ref{Data Representation in +Scheme} and @ref{The Libguile Runtime Environment}. + You don't need to know the details given there to use Guile from C, but they are useful when you want to modify Guile itself or when you are just curious about how it is all done. @@ -298,7 +302,7 @@ available through both Scheme and C interfaces. * Binding Constructs:: Definitions and variable bindings. * Control Mechanisms:: Controlling the flow of program execution. * Input and Output:: Ports, reading and writing. -* Read/Load/Eval:: Reading and evaluating Scheme code. +* Read/Load/Eval/Compile:: Reading and evaluating Scheme code. * Memory Management:: Memory management and garbage collection. * Objects:: Low level object orientation support. * Modules:: Designing reusable code libraries. @@ -362,9 +366,47 @@ available through both Scheme and C interfaces. @include scsh.texi @include scheme-debugging.texi -@include autoconf.texi +@include goops.texi + +@node Guile Implementation +@chapter Guile Implementation + +At some point, after one has been programming in Scheme for some time, +another level of Scheme comes into view: its implementation. Knowledge +of how Scheme can be implemented turns out to be necessary to become +an expert hacker. As Peter Norvig notes in his retrospective on +PAIP@footnote{PAIP is the common abbreviation for @cite{Paradigms of +Artificial Intelligence Programming}, an old but still useful text on +Lisp. Norvig's retrospective sums up the lessons of PAIP, and can be +found at @uref{http://norvig.com/Lisp-retro.html}.}, ``The expert Lisp +programmer eventually develops a good `efficiency model'.'' + +By this Norvig means that over time, the Lisp hacker eventually +develops an understanding of how much her code ``costs'' in terms of +space and time. +This chapter describes Guile as an implementation of Scheme: its +history, how it represents and evaluates its data, and its compiler. +This knowledge can help you to make that step from being one who is +merely familiar with Scheme to being a real hacker. + +@menu +* History:: A brief history of Guile. +* Data Representation in Scheme:: Why things aren't just totally + straightforward, in general terms. +* The Libguile Runtime Environment:: Low-level details on Guile's C + runtime library. +* A Virtual Machine for Guile:: How compiled procedures work. +* Compiling to the Virtual Machine:: Not as hard as you might think. +@end menu + +@include history.texi @include data-rep.texi +@include vm.texi +@include compiler.texi + +@include autoconf.texi + @include fdl.texi @iftex diff --git a/doc/ref/hierarchy.eps b/doc/ref/hierarchy.eps new file mode 100644 index 000000000..7b1a98605 --- /dev/null +++ b/doc/ref/hierarchy.eps @@ -0,0 +1,127 @@ +%!PS-Adobe-2.0 EPSF +%%Title: /tmp/xfig-fig016295 +%%Creator: fig2dev +%%CreationDate: Fri Jun 10 23:18:16 1994 +%%For: eg@kaolin (Erick Gallesio) +%%BoundingBox: 0 0 361 217 +%%Pages: 0 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/l {lineto} bind def +/m {moveto} bind def +/s {stroke} bind def +/n {newpath} bind def +/gs {gsave} bind def +/gr {grestore} bind def +/clp {closepath} bind def +/graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul +4 -2 roll mul setrgbcolor} bind def +/col-1 {} def +/col0 {0 0 0 setrgbcolor} bind def +/col1 {0 0 1 setrgbcolor} bind def +/col2 {0 1 0 setrgbcolor} bind def +/col3 {0 1 1 setrgbcolor} bind def +/col4 {1 0 0 setrgbcolor} bind def +/col5 {1 0 1 setrgbcolor} bind def +/col6 {1 1 0 setrgbcolor} bind def +/col7 {1 1 1 setrgbcolor} bind def + end +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +0 setlinecap 0 setlinejoin +-216.0 288.0 translate 0.900 -0.900 scale +0.500 setlinewidth +n 309 159 m 309 159 l gs col-1 s gr +n 246.401 216.889 m 244.000 209.000 l 249.831 214.831 l gs 2 setlinejoin col-1 s gr +% Polyline +n 244 209 m 274 259 l gs col-1 s gr +n 298.169 214.831 m 304.000 209.000 l 301.599 216.889 l gs 2 setlinejoin col-1 s gr +% Polyline +n 304 209 m 274 259 l gs col-1 s gr +n 255.721 213.778 m 249.000 209.000 l 257.179 210.053 l gs 2 setlinejoin col-1 s gr +% Polyline +n 249 209 m 364 254 l gs col-1 s gr +n 370.312 216.376 m 374.000 209.000 l 374.217 217.243 l gs 2 setlinejoin col-1 s gr +% Polyline +n 374 209 m 364 254 l gs col-1 s gr +n 283.772 280.725 m 279.000 274.000 l 286.376 277.688 l gs 2 setlinejoin col-1 s gr +% Polyline +n 279 274 m 314 304 l gs col-1 s gr +n 351.457 272.333 m 359.000 269.000 l 353.913 275.490 l gs 2 setlinejoin col-1 s gr +% Polyline +n 359 269 m 314 304 l gs col-1 s gr +n 300.950 165.789 m 309.000 164.000 l 302.739 169.367 l gs 2 setlinejoin col-1 s gr +% Polyline +n 309 164 m 249 194 l gs col-1 s gr +n 307.000 172.000 m 309.000 164.000 l 311.000 172.000 l gs 2 setlinejoin col-1 s gr +% Polyline +n 309 164 m 309 199 l gs col-1 s gr +n 315.261 169.367 m 309.000 164.000 l 317.050 165.789 l gs 2 setlinejoin col-1 s gr +% Polyline +n 309 164 m 379 199 l gs col-1 s gr +n 406.949 101.701 m 404.000 94.000 l 410.226 99.407 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 439 144 l gs col-1 s gr +n 410.363 99.245 m 404.000 94.000 l 412.083 95.634 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 509 144 l gs col-1 s gr +n 411.173 98.068 m 404.000 94.000 l 412.243 94.214 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 584 144 l gs col-1 s gr +n 396.075 96.277 m 404.000 94.000 l 398.079 99.739 l gs 2 setlinejoin col-1 s gr +% Polyline +n 404 94 m 309 149 l gs col-1 s gr +% Polyline +n 584 229 m 584 204 l gs col-1 s gr +n 582.000 212.000 m 584.000 204.000 l 586.000 212.000 l gs 2 setlinejoin col-1 s gr +% Polyline +n 584 189 m 584 159 l gs col-1 s gr +n 582.000 167.000 m 584.000 159.000 l 586.000 167.000 l gs 2 setlinejoin col-1 s gr +/Times-Bold findfont 12.00 scalefont setfont +239 209 m +gs 1 -1 scale (A) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +274 274 m +gs 1 -1 scale (D) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +359 269 m +gs 1 -1 scale (E) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +304 209 m +gs 1 -1 scale (B) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +374 209 m +gs 1 -1 scale (C) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +314 319 m +gs 1 -1 scale (F) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +289 159 m +gs 1 -1 scale (<object>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +389 89 m +gs 1 -1 scale (<top>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +424 154 m +gs 1 -1 scale (<pair>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +474 154 m +gs 1 -1 scale (<procedure>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +559 154 m +gs 1 -1 scale (<number>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +629 154 m +gs 1 -1 scale (...) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +569 199 m +gs 1 -1 scale (<real>) col-1 show gr +/Times-Bold findfont 12.00 scalefont setfont +559 239 m +gs 1 -1 scale (<integer>) col-1 show gr +$F2psEnd diff --git a/doc/ref/hierarchy.pdf b/doc/ref/hierarchy.pdf new file mode 100644 index 000000000..3a19ba4eb --- /dev/null +++ b/doc/ref/hierarchy.pdf @@ -0,0 +1,74 @@ +%PDF-1.3 +%Çì¢ +5 0 obj +<</Length 6 0 R/Filter /FlateDecode>> +stream +xœm”Ën1E÷ú +-íŰ¢(êš6-Ð][ï‚.Ç
Äy¸)úû½Ò¼ÛÀ‘wŽ(Šä«uÄÖÕgø_o͇ÉÞý1Ôþ3lï³_Môl9„b·óë£ùi¼}0š(:U[|†[¢-¥:s¦"V!’zirù €ÒE«û/Nú-À#K5n[ŒœÑ{âÀr¶E#¼™]±%—w
‚af€J˜Aœ<#ž"§ªðn ¯‰J=u ŒïFÚ$9Á“"T‚ZQAn*P”mજH²XÉŽ²+sºd"ñstÎ 1¼¾sUÁ.a©-<ç•pSÁ9Chá’cž†L’eÉ8ÙtÓ®*4"w!çJi¢MŠ–ff™iÑ Ôâßs¢”Þz‚Ð^]žï1&¤dÞô=©¬E8{Ç^x¬Îã„–K=M»!T¨õ®…ÍŠk®A—¬${›4Ð'!kÞ»!ŸêW‘ò)MŠ%’“Dü1àÊÄ‚ãG©èÕ\—ˆ6dŠ+ñ€‰”PL5ô2ƒ÷„²À<‰žd¶ÄªôÉld.Ó^n¯ŒÄ%´LòNaq5O…ÝœÈè$Ü*ÂÒ7Éž·aš½çÜ™WÔt›]Ãßzk/V˜bødW¿M?ÚØv•R +~V[³ø¸\aƘë…oW·fñ¹Úæ
ƒå²Zº€‰S-W‹‹e§#‰,>-¾™b;ô{UijdS[gUÓÙóÍÃfýv^=ÅÙ(½õíùåü8€«ÅÙËõýî|Ù±GéÄ„õîy½¹ý»ÛT£¢°íÙÓßíͦɵP°®¼ZAý>»ÍõcÛ¨C”½Íxÿô¶¹«ßÃ~¹2ßñü(8endstream +endobj +6 0 obj +660 +endobj +4 0 obj +<</Type/Page/MediaBox [0 0 361 217] +/Parent 3 0 R +/Resources<</ProcSet[/PDF /Text] +/ExtGState 9 0 R +/Font 10 0 R +>> +/Contents 5 0 R +>> +endobj +3 0 obj +<< /Type /Pages /Kids [ +4 0 R +] /Count 1 +>> +endobj +1 0 obj +<</Type /Catalog /Pages 3 0 R +>> +endobj +7 0 obj +<</Type/ExtGState +/OPM 1>>endobj +9 0 obj +<</R7 +7 0 R>> +endobj +10 0 obj +<</R8 +8 0 R>> +endobj +8 0 obj +<</BaseFont/Times-Bold/Type/Font +/Subtype/Type1>> +endobj +2 0 obj +<</Producer(GPL Ghostscript 8.15) +/CreationDate(D:20060418115825) +/ModDate(D:20060418115825) +/Title(/tmp/xfig-fig016295) +/Creator(fig2dev) +/Author(eg@kaolin \(Erick Gallesio\))>>endobj +xref +0 11 +0000000000 65535 f +0000000973 00000 n +0000001186 00000 n +0000000914 00000 n +0000000764 00000 n +0000000015 00000 n +0000000745 00000 n +0000001021 00000 n +0000001121 00000 n +0000001062 00000 n +0000001091 00000 n +trailer +<< /Size 11 /Root 1 0 R /Info 2 0 R +/ID [(¿Ccežò3f¾q\\[)(¿Ccežò3f¾q\\[)] +>> +startxref +1379 +%%EOF diff --git a/doc/ref/hierarchy.png b/doc/ref/hierarchy.png Binary files differnew file mode 100644 index 000000000..46f58b051 --- /dev/null +++ b/doc/ref/hierarchy.png diff --git a/doc/ref/hierarchy.txt b/doc/ref/hierarchy.txt new file mode 100644 index 000000000..c7992df7b --- /dev/null +++ b/doc/ref/hierarchy.txt @@ -0,0 +1,14 @@ + <top> + / \\\_____________________ + / \\___________ \ + / \ \ \ + <object> <pair> <procedure> <number> + / | \ | + / | \ | + A B C <complex> + |\__/__ | | + \ / \ / | + D E <real> + \ / | + F | + <integer> diff --git a/doc/ref/history.texi b/doc/ref/history.texi new file mode 100644 index 000000000..b14b44923 --- /dev/null +++ b/doc/ref/history.texi @@ -0,0 +1,285 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 2008 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@node History +@section A Brief History of Guile + +Guile is an artifact of historical processes, both as code and as a +community of hackers. It is sometimes useful to know this history when +hacking the source code, to know about past decisions and future +directions. + +Of course, the real history of Guile is written by the hackers hacking +and not the writers writing, so we round up the section with a note on +current status and future directions. + +@menu +* The Emacs Thesis:: +* Early Days:: +* A Scheme of Many Maintainers:: +* A Timeline of Selected Guile Releases:: +* Status:: +@end menu + +@node The Emacs Thesis +@subsection The Emacs Thesis + +The story of Guile is the story of bringing the development experience +of Emacs to the mass of programs on a GNU system. + +Emacs, when it was first created in its GNU form in 1984, was a new +take on the problem of ``how to make a program''. The Emacs thesis is +that it is delightful to create composite programs based on an +orthogonal kernel written in a low-level language together with a +powerful, high-level extension language. + +Extension languages foster extensible programs, programs which adapt +readily to different users and to changing times. Proof of this can be +seen in Emacs' current and continued existence, spanning more than a +quarter-century. + +Besides providing for modification of a program by others, extension +languages are good for @emph{intension} as well. Programs built in +``the Emacs way'' are pleasurable and easy for their authors to flesh +out with the features that they need. + +After the Emacs experience was appreciated more widely, a number of +hackers started to consider how to spread this experience to the rest +of the GNU system. It was clear that the easiest way to Emacsify a +program would be to embed a shared language implementation into it. + +@node Early Days +@subsection Early Days + +Tom Lord was the first to fully concentrate his efforts on an +embeddable language runtime, which he named ``GEL'', the GNU Extension +Language. + +GEL was the product of converting SCM, Aubrey Jaffer's implementation +of Scheme, into something more appropriate to embedding as a library. +(SCM was itself based on an implementation by George Carrette, SIOD.) + +Lord managed to convince Richard Stallman to dub GEL the official +extension language for the GNU project. It was a natural fit, given +that Scheme was a cleaner, more modern Lisp than Emacs Lisp. Part of +the argument was that eventually when GEL became more capable, it +could gain the ability to execute other languages, especially Emacs +Lisp. + +Due to a naming conflict with another programming language, Jim Blandy +suggested a new name for GEL: ``Guile''. Besides being a recursive +acroymn, ``Guile'' craftily follows the naming of its ancestors, +``Planner'', ``Conniver'', and ``Schemer''. (The latter was truncated +to ``Scheme'' due to a 6-character file name limit on an old operating +system.) Finally, ``Guile'' suggests ``guy-ell'', or ``Guy L. +Steele'', who, together with Gerald Sussman, originally discovered +Scheme. + +Around the same time that Guile (then GEL) was readying itself for +public release, another extension language was gaining in popularity, +Tcl. Many developers found advantages in Tcl because of its shell-like +syntax and its well-developed graphical widgets library, Tk. Also, at +the time there was a large marketing push promoting Tcl as a +``universal extension language''. + +Richard Stallman, as the primary author of GNU Emacs, had a particular +vision of what extension languages should be, and Tcl did not seem to +him to be as capable as Emacs Lisp. He posted a criticism to the +comp.lang.tcl newsgroup, sparking one of the internet's legendary +flamewars. As part of these discussions, retrospectively dubbed the +``Tcl Wars'', he announced the Free Software Foundation's intent to +promote Guile as the extension language for the GNU project. + +It is a common misconception that Guile was created as a reaction to +Tcl. While it is true that the public announcement of Guile happened +at the same time as the ``Tcl wars'', Guile was created out of a +condition that existed outside the polemic. Indeed, the need for a +powerful language to bridge the gap between extension of existing +applications and a more fully dynamic programming environment is still +with us today. + +@node A Scheme of Many Maintainers +@subsection A Scheme of Many Mantainers + +Surveying the field, it seems that Scheme implementations correspond +with their maintainers on an N-to-1 relationship. That is to say, that +those people that implement Schemes might do so on a number of +occasions, but that the lifetime of a given Scheme is tied to the +maintainership of one individual. + +Guile is atypical in this regard. + +Tom Lord maintaned Guile for its first year and a half or so, +corresponding to the end of 1994 through the middle of 1996. The +releases made in this time constitute an arc from SCM as a standalone +program to Guile as a reusable, embeddable library, but passing +through a explosion of features: embedded Tcl and Tk, a toolchain for +compiling and disassembling Java, addition of a C-like syntax, +creation of a module system, and a start at a rich POSIX interface. + +Only some of those features remain in Guile. There were ongoing +tensions between providing a small, embeddable language, and one which +had all of the features (e.g. a graphical toolkit) that a modern Emacs +might need. In the end, as Guile gained in uptake, the development +team decided to focus on depth, documentation and orthogonality rather +than on breadth. This has been the focus of Guile ever since, although +there is a wide range of third-party libraries for Guile. + +Jim Blandy presided over that period of stabilization, in the three +years until the end of 1999, when he too moved on to other projects. +Since then, Guile has had a group maintainership. The first group was +Maciej Stachowiak, Mikael Djurfeldt, and Marius Vollmer, with Vollmer +staying on the longest. By late 2007, Vollmer had mostly moved on to +other things, so Neil Jerram and Ludovic Courtès stepped up to take on +the primary maintenance responsibility. + +Of course, a large part of the actual work on Guile has come from +other contributors too numerous to mention, but without whom the world +would be a poorer place. + +@node A Timeline of Selected Guile Releases +@subsection A Timeline of Selected Guile Releases + +@table @asis +@item guile-i --- 4 February 1995 +SCM, turned into a library. + +@item guile-ii --- 6 April 1995 +A low-level module system was added. Tcl/Tk support was added, +allowing extension of Scheme by Tcl or vice versa. POSIX support was +improved, and there was an experimental stab at Java integration. + +@item guile-iii --- 18 August 1995 +The C-like syntax, ctax, was improved, but mostly this release +featured a start at the task of breaking Guile into pieces. + +@item 1.0 --- 5 January 1997 +@code{#f} was distinguished from @code{'()}. User-level, cooperative +multi-threading was added. Source-level debugging became more useful, +and programmer's and user's manuals were begun. The module system +gained a high-level interface, which is still used today in more or +less the same form. + +@item 1.1 --- 16 May 1997 +@itemx 1.2 --- 24 June 1997 +Support for Tcl/Tk and ctax were split off as separate packages, and +have remained there since. Guile became more compatible with SCSH, and +more useful as a UNIX scripting language. Libguile can now be built as +a shared library, and third-party extensions written in C became +loadable via dynamic linking. + +@item 1.3.0 --- 19 October 1998 +Command-line editing became much more pleasant through the use of the +readline library. The initial support for internationalization via +multi-byte strings was removed, and has yet to be added back, though +UTF-8 hacks are common. Modules gained the ability to have custom +expanders, which is still used for syntax-case macros. Initial Emacs +Lisp support landed, ports gained better support for file descriptors, +and fluids were added. + +@item 1.3.2 --- 20 August 1999 +@itemx 1.3.4 --- 25 September 1999 +@itemx 1.4 --- 21 June 2000 +A long list of lispy features were added: hooks, Common Lisp's +@code{format}, optional and keyword procedure arguments, +@code{getopt-long}, sorting, random numbers, and many other fixes and +enhancements. Guile now has an interactive debugger, interactive help, +and gives better backtraces. + +@item 1.6 --- 6 September 2002 +Guile gained support for the R5RS standard, and added a number of SRFI +modules. The module system was expanded with programmatic support for +identifier selection and renaming. The GOOPS object system was merged +into Guile core. + +@item 1.8 --- 20 February 2006 +Guile's arbitrary-precision arithmetic switched to use the GMP +library, and added support for exact rationals. Guile's embedded +user-space threading was removed in favor of POSIX pre-emptive +threads, providing true multiprocessing. Gettext support was added, +and Guile's C API was cleaned up and orthogonalized in a massive way. + +@item 2.0 --- thus far, only unstable snapshots available +A virtual machine was added to Guile, along with the associated +compiler and toolchain. Support for internationalization was added. +Running Guile instances became controllable and debuggable from within +Emacs, via GDS, which was also backported to 1.8.5. An SRFI-18 +interface to multithreading was added, including thread cancellation. +@end table + +@node Status +@subsection Status, or: Your Help Needed + +Guile has achieved much of what it set out to achieve, but there is +much remaining to do. + +There is still the old problem of bringing existing applications into +a more Emacs-like experience. Guile has had some successes in this +respect, but still most applications in the GNU system are without +Guile integration. + +Getting Guile to those applications takes an investment, the +``hacktivation energy'' needed to wire Guile into a program that only +pays off once it is good enough to enable new kinds of behavior. This +would be a great way for new hackers to contribute: take an +application that you use and that you know well, think of something +that it can't yet do, and figure out a way to integrate Guile and +implement that task in Guile. + +With time, perhaps this exposure can reverse itself, whereby programs +can run under Guile instead of vice versa, eventually resulting in the +Emacsification of the entire GNU system. Indeed, this is the reason +for the naming of the many Guile modules that live in the @code{ice-9} +namespace, a nod to the fictional substance in Kurt Vonnegut's +novel, Cat's Cradle, capable of acting as a seed crystal to +crystallize the mass of software. + +Implicit to this whole discussion is the idea that dynamic languages +are somehow better than languages like C. While languages like C have +their place, Guile's take on this question is that yes, Scheme is more +expressive than C, and more fun to write. This realization carries an +imperative with it to write as much code in Scheme as possible rather +than in other languages. + +These days it is possible to write extensible applications almost +entirely from high-level languages, through byte-code and native +compilation, speed gains in the underlying hardware, and foreign call +interfaces in the high-level language. Smalltalk systems are like +this, as are Common Lisp-based systems. While there already are a +number of pure-Guile applications out there, users still need to drop +down to C for some tasks: interfacing to system libraries that don't +have prebuilt Guile interfaces, and for some tasks requiring high +performance. + +The addition of the virtual machine in Guile 2.0, together with the +compiler infrastructure, should go a long way to addressing the speed +issues. But there is much optimization to be done. Interested +contributors will find lots of delightful low-hanging fruit, from +simple profile-driven optimization to hacking a just-in-time compiler +from VM bytecode to native code. + +Still, even with an all-Guile application, sometimes you want to +provide an opportunity for users to extend your program from a +language with a syntax that is closer to C, or to Python. Another +interesting idea to consider is compiling e.g. Python to Guile. It's +not that far-fetched of an idea: see for example IronPython or JRuby. + +And then there's Emacs itself. Though there is a somewhat-working +Emacs Lisp translator for Guile, it cannot yet execute all of Emacs +Lisp. A serious integration of Guile with Emacs would replace the +Elisp virtual machine with Guile, and provide the necessary C shims so +that Guile could emulate Emacs' C API. This would give lots of +exciting things to Emacs: native threads, a real object system, more +sophisticated types, cleaner syntax, and access to all of the Guile +extensions. + +Finally, there is another axis of crystallization, the axis between +different Scheme implementations. Guile does not yet support the +latest Scheme standard, R6RS, and should do so. Like all standards, +R6RS is imperfect, but supporting it will allow more code to run on +Guile without modification, and will allow Guile hackers to produce +code compatible with other schemes. Help in this regard would be much +appreciated. diff --git a/doc/ref/intro.texi b/doc/ref/intro.texi index a31fe30f8..7e248e0e8 100644 --- a/doc/ref/intro.texi +++ b/doc/ref/intro.texi @@ -80,6 +80,7 @@ To unbundle Guile use the instruction zcat guile-@value{VERSION}.tar.gz | tar xvf - @end example +@noindent which will create a directory called @file{guile-@value{VERSION}} with all the sources. You can look at the file @file{INSTALL} for detailed instructions on how to build and install Guile, but you should be able @@ -93,7 +94,7 @@ make install @end example This will install the Guile executable @file{guile}, the Guile library -@file{-lguile} and various associated header files and support +@file{libguile} and various associated header files and support libraries. It will also install the Guile tutorial and reference manual. @@ -101,14 +102,14 @@ manual. Since this manual frequently refers to the Scheme ``standard'', also known as R5RS, or the -@iftex +@tex ``Revised$^5$ Report on the Algorithmic Language Scheme'', -@end iftex +@end tex @ifnottex ``Revised^5 Report on the Algorithmic Language Scheme'', @end ifnottex -we have included the report in the Guile distribution; -@xref{Top, , Introduction, r5rs, Revised(5) Report on the Algorithmic +we have included the report in the Guile distribution; see +@ref{Top, , Introduction, r5rs, Revised(5) Report on the Algorithmic Language Scheme}. This will also be installed in your info directory. @@ -470,12 +471,13 @@ You can get the version number by invoking the command @example $ guile --version -Guile 1.4.1 -Copyright (c) 1995, 1996, 1997, 2000, 2006 Free Software Foundation -Guile may be distributed under the terms of the GNU General Public License; -certain other uses are permitted as well. For details, see the file -`COPYING', which is included in the Guile distribution. -There is no warranty, to the extent permitted by law. +Guile 1.9.0 +Copyright (c) 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004, +2005, 2006, 2007, 2008, 2009 Free Software Foundation +Guile may be distributed under the terms of the GNU Lesser General +Public Licence. For details, see the files `COPYING.LESSER' and +`COPYING', which are included in the Guile distribution. There is +no warranty, to the extent permitted by law. @end example @item diff --git a/doc/ref/libguile-concepts.texi b/doc/ref/libguile-concepts.texi index 20c0f72ca..15d54f531 100644 --- a/doc/ref/libguile-concepts.texi +++ b/doc/ref/libguile-concepts.texi @@ -153,8 +153,8 @@ that have been added to Guile by third-party libraries. Also, computing with @code{SCM} is not necessarily inefficient. Small integers will be encoded directly in the @code{SCM} value, for example, -and do not need any additional memory on the heap. See @ref{Data -Representation} to find out the details. +and do not need any additional memory on the heap. See @ref{The +Libguile Runtime Environment} to find out the details. Some special @code{SCM} values are available to C code without needing to convert them from C values: @@ -170,8 +170,8 @@ In addition to @code{SCM}, Guile also defines the related type @code{scm_t_bits}. This is an unsigned integral type of sufficient size to hold all information that is directly contained in a @code{SCM} value. The @code{scm_t_bits} type is used internally by -Guile to do all the bit twiddling explained in @ref{Data -Representation}, but you will encounter it occasionally in low-level +Guile to do all the bit twiddling explained in @ref{The Libguile +Runtime Environment}, but you will encounter it occasionally in low-level user code as well. @@ -182,7 +182,7 @@ As explained above, the @code{SCM} type can represent all Scheme values. Some values fit entirely into a @code{SCM} value (such as small integers), but other values require additional storage in the heap (such as strings and vectors). This additional storage is managed -automatically by Guile. You don't need to explicitely deallocate it +automatically by Guile. You don't need to explicitly deallocate it when a @code{SCM} value is no longer used. Two things must be guaranteed so that Guile is able to manage the diff --git a/doc/ref/libguile-extensions.texi b/doc/ref/libguile-extensions.texi index 77762b5c5..78871c6ca 100644 --- a/doc/ref/libguile-extensions.texi +++ b/doc/ref/libguile-extensions.texi @@ -94,11 +94,11 @@ we are going to call the function @code{init_bessel} which will make @file{.so} when invoking @code{load-extension}. The right extension for the host platform will be provided automatically. -@smalllisp +@lisp (load-extension "libguile-bessel" "init_bessel") (j0 2) @result{} 0.223890779141236 -@end smalllisp +@end lisp For this to work, @code{load-extension} must be able to find @file{libguile-bessel}, of course. It will look in the places that diff --git a/doc/ref/libguile-linking.texi b/doc/ref/libguile-linking.texi index 8869c46d5..72b59bbba 100644 --- a/doc/ref/libguile-linking.texi +++ b/doc/ref/libguile-linking.texi @@ -173,7 +173,8 @@ creating ./config.status creating Makefile $ make gcc -c -I/usr/local/include simple-guile.c -gcc simple-guile.o -L/usr/local/lib -lguile -lqthreads -lpthread -lm -o simple-guile +gcc simple-guile.o -L/usr/local/lib -lguile -lqthreads -lpthread -lm + -o simple-guile $ ./simple-guile guile> (+ 1 2 3) 6 diff --git a/doc/ref/libguile-smobs.texi b/doc/ref/libguile-smobs.texi index 59bb98ffb..738809d7a 100644 --- a/doc/ref/libguile-smobs.texi +++ b/doc/ref/libguile-smobs.texi @@ -28,7 +28,7 @@ datatypes described here.) @menu * Describing a New Type:: -* Creating Instances:: +* Creating Smob Instances:: * Type checking:: * Garbage Collecting Smobs:: * Garbage Collecting Simple Smobs:: @@ -132,8 +132,8 @@ init_image_type (void) @end example -@node Creating Instances -@subsection Creating Instances +@node Creating Smob Instances +@subsection Creating Smob Instances Normally, smobs can have one @emph{immediate} word of data. This word stores either a pointer to an additional memory block that holds the @@ -211,7 +211,8 @@ make_image (SCM name, SCM s_width, SCM s_height) /* Step 1: Allocate the memory block. */ - image = (struct image *) scm_gc_malloc (sizeof (struct image), "image"); + image = (struct image *) + scm_gc_malloc (sizeof (struct image), "image"); /* Step 2: Initialize it with straight code. */ @@ -228,7 +229,8 @@ make_image (SCM name, SCM s_width, SCM s_height) /* Step 4: Finish the initialization. */ image->name = name; - image->pixels = scm_gc_malloc (width * height, "image pixels"); + image->pixels = + scm_gc_malloc (width * height, "image pixels"); return smob; @} @@ -404,7 +406,9 @@ free_image (SCM image_smob) @{ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); - scm_gc_free (image->pixels, image->width * image->height, "image pixels"); + scm_gc_free (image->pixels, + image->width * image->height, + "image pixels"); scm_gc_free (image, sizeof (struct image), "image"); return 0; @@ -517,10 +521,10 @@ Smobs are called smob because they are small: they normally have only room for one @code{void*} or @code{SCM} value plus 16 bits. The reason for this is that smobs are directly implemented by using the low-level, two-word cells of Guile that are also used to implement -pairs, for example. (@pxref{Data Representation} for the details.) -One word of the two-word cells is used for @code{SCM_SMOB_DATA} (or -@code{SCM_SMOB_OBJECT}), the other contains the 16-bit type tag and -the 16 extra bits. +pairs, for example. (@pxref{The Libguile Runtime Environment} for the +details.) One word of the two-word cells is used for +@code{SCM_SMOB_DATA} (or @code{SCM_SMOB_OBJECT}), the other contains +the 16-bit type tag and the 16 extra bits. In addition to the fundamental two-word cells, Guile also has four-word cells, which are appropriately called @dfn{double cells}. @@ -583,7 +587,8 @@ make_image (SCM name, SCM s_width, SCM s_height) /* Step 1: Allocate the memory block. */ - image = (struct image *) scm_gc_malloc (sizeof (struct image), "image"); + image = (struct image *) + scm_gc_malloc (sizeof (struct image), "image"); /* Step 2: Initialize it with straight code. */ @@ -600,7 +605,8 @@ make_image (SCM name, SCM s_width, SCM s_height) /* Step 4: Finish the initialization. */ image->name = name; - image->pixels = scm_gc_malloc (width * height, "image pixels"); + image->pixels = + scm_gc_malloc (width * height, "image pixels"); return smob; @} @@ -642,7 +648,9 @@ free_image (SCM image_smob) @{ struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); - scm_gc_free (image->pixels, image->width * image->height, "image pixels"); + scm_gc_free (image->pixels, + image->width * image->height, + "image pixels"); scm_gc_free (image, sizeof (struct image), "image"); return 0; diff --git a/doc/ref/mop.text b/doc/ref/mop.text new file mode 100644 index 000000000..0180f2c1e --- /dev/null +++ b/doc/ref/mop.text @@ -0,0 +1,66 @@ +*** NOTE: This information needs updating! *** + +P - procedure +L - local procedure +S - syntax +G - generic +M - method + +define-class (S) + make-class (S) + ensure-metaclass (P) + ensure-metaclass-with-supers (P) + make (G) + ensure-class (P) + make (G) + class-redefinition (G) + remove-class-accessors (G) + update-direct-method (G) + update-direct-subclass (G) + +define-generic (S) + make-generic-function (S) + ensure-generic-function (P) + make (G) + +define-method (S) + ensure-method (P) + ensure-generic-function (P) + make (G) + make (G) + add-method (P) + +method (S) + ensure-method (P) + +initialize (class) (M) + compute-cpl (P) + compute-slots (G) + compute-getters-n-setters (P) + compute-slot-init-function (L) + compute-get-n-set (G) + compute-slot-accessors (P) + ensure-method (P) + %inherit-magic! (P) + %prep-layout! (P) + +initialize (generic) (M) + make (G) + +change-class (G) + change-object-class (P) + update-instance-for-different-class (G) + +make = make-instance (G) + allocate-instance (G) + %allocate-instance (P) + initialize (G) + %initialize-object (P) + +apply-generic (G) + compute-applicable-methods (G) + find-method (P) + sort-applicable-methods (G) + sort (P) + apply-methods (G) + apply-method (G) diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi index cb19a7af8..d568af23d 100644 --- a/doc/ref/posix.texi +++ b/doc/ref/posix.texi @@ -1909,10 +1909,6 @@ for termination, not stopping. If a signal occurs while in a system call, deliver the signal then restart the system call (as opposed to returning an @code{EINTR} error from that call). - -Guile always enables this flag where available, no matter what -@var{flags} are specified. This avoids spurious error returns in low -level operations. @end defvar The return value is a pair with information about the old handler as @@ -2076,9 +2072,9 @@ The following procedures are similar to the @code{popen} and @code{pclose} system routines. The code is in a separate ``popen'' module: -@smalllisp +@lisp (use-modules (ice-9 popen)) -@end smalllisp +@end lisp @findex popen @deffn {Scheme Procedure} open-pipe command mode diff --git a/doc/ref/preface.texi b/doc/ref/preface.texi index d6de77440..8552d388b 100644 --- a/doc/ref/preface.texi +++ b/doc/ref/preface.texi @@ -7,12 +7,9 @@ @node Preface @chapter Preface -This reference manual documents Guile, GNU's Ubiquitous Intelligent -Language for Extensions. It describes how to use Guile in many useful -and interesting ways. - -This is edition @value{MANUAL-EDITION} of the reference manual, and -corresponds to Guile version @value{VERSION}. +This manual documents version @value{VERSION} of Guile, GNU's +Ubiquitous Intelligent Language for Extensions. It describes how to +use Guile in many useful and interesting ways. @menu * Manual Layout:: @@ -25,7 +22,7 @@ corresponds to Guile version @value{VERSION}. @node Manual Layout @section Layout of this Manual -The manual is divided into five chapters. +The manual is divided into the following chapters. @table @strong @item Chapter 1: Introduction to Guile @@ -38,7 +35,7 @@ the later parts of the manual. This part also explains how to obtain and install new versions of Guile, and how to report bugs effectively. @item Chapter 2: Programming in Scheme -This part provides an overview over programming in Scheme with Guile. +This part provides an overview of programming in Scheme with Guile. It covers how to invoke the @code{guile} program from the command-line and how to write scripts in Scheme. It also gives an introduction into the basic ideas of Scheme itself and to the various extensions @@ -61,6 +58,10 @@ Describes some important modules, distributed as part of the Guile distribution, that extend the functionality provided by the Guile Scheme core. +@item Chapter 6: GOOPS +Describes GOOPS, an object oriented extension to Guile that provides +classes, multiple inheritance and generic functions. + @end table @@ -72,7 +73,7 @@ We use some conventions in this manual. @itemize @bullet @item -For some procedures, notably type predicates, we use @dfn{iff} to mean +For some procedures, notably type predicates, we use ``iff'' to mean ``if and only if''. The construct is usually something like: `Return @var{val} iff @var{condition}', where @var{val} is usually ``@nicode{#t}'' or ``non-@nicode{#f}''. This typically means that @@ -144,6 +145,9 @@ filling out a lot of the documentation of Scheme data types, control mechanisms and procedures. In addition, he wrote the documentation for Guile's SRFI modules and modules associated with the Guile REPL. +The chapter on GOOPS was written by Christian Lynbech, Mikael +Djurfeldt and Neil Jerram. + @node Guile License @section The Guile License @cindex copying @@ -159,12 +163,12 @@ person would want to do. @itemize @bullet @item The Guile library (libguile) and supporting files are published under -the terms of the GNU Lesser General Public License version 2.1. See -the file @file{COPYING.LIB}. +the terms of the GNU Lesser General Public License version 3 or later. +See the files @file{COPYING.LESSER} and @file{COPYING}. @item The Guile readline module is published under the terms of the GNU -General Public License version 2. See the file @file{COPYING}. +General Public License version 3 or later. See the file @file{COPYING}. @item The manual you're now reading is published under the terms of the GNU @@ -179,7 +183,7 @@ C code linking to the Guile readline module is subject to the terms of that module. Basically such code must be published on Free terms. Scheme level code written to be run by Guile (but not derived from -Guile itself) is not resticted in any way, and may be published on any +Guile itself) is not restricted in any way, and may be published on any terms. We encourage authors to publish on Free terms. You must be aware there is no warranty whatsoever for Guile. This is diff --git a/doc/ref/scheme-debugging.texi b/doc/ref/scheme-debugging.texi index 07511263b..bcd9f2df3 100644 --- a/doc/ref/scheme-debugging.texi +++ b/doc/ref/scheme-debugging.texi @@ -14,9 +14,9 @@ call to that procedure is reported to the user during a program run. The idea is that you can mark a collection of procedures for tracing, and Guile will subsequently print out a line of the form -@smalllisp +@lisp | | [@var{procedure} @var{args} @dots{}] -@end smalllisp +@end lisp whenever a marked procedure is about to be applied to its arguments. This can help a programmer determine whether a function is being called @@ -27,7 +27,7 @@ how the traced applications are or are not tail recursive with respect to each other. Thus, a trace of a non-tail recursive factorial implementation looks like this: -@smalllisp +@lisp [fact1 4] | [fact1 3] | | [fact1 2] @@ -38,11 +38,11 @@ implementation looks like this: | | 2 | 6 24 -@end smalllisp +@end lisp While a typical tail recursive implementation would look more like this: -@smalllisp +@lisp [fact2 4] [facti 1 4] [facti 4 3] @@ -50,7 +50,7 @@ While a typical tail recursive implementation would look more like this: [facti 24 1] [facti 24 0] 24 -@end smalllisp +@end lisp @deffn {Scheme Procedure} trace procedure Enable tracing for @code{procedure}. While a program is being run, diff --git a/doc/ref/scheme-ideas.texi b/doc/ref/scheme-ideas.texi index 38b105b94..55093cf92 100644 --- a/doc/ref/scheme-ideas.texi +++ b/doc/ref/scheme-ideas.texi @@ -390,7 +390,11 @@ this: @noindent This is a valid procedure invocation expression, and its result is the -string @code{"Name=FSF:Address=Cambridge"}. +string: + +@lisp +"Name=FSF:Address=Cambridge" +@end lisp It is more common, though, to store the procedure value in a variable --- diff --git a/doc/ref/scsh.texi b/doc/ref/scsh.texi index 0f869ecd7..b1af1a443 100644 --- a/doc/ref/scsh.texi +++ b/doc/ref/scsh.texi @@ -19,8 +19,8 @@ For information about scsh see The closest emulation of scsh can be obtained by running: -@smalllisp +@lisp (load-from-path "scsh/init") -@end smalllisp +@end lisp See the USAGE file supplied with guile-scsh for more details. diff --git a/doc/ref/slib.texi b/doc/ref/slib.texi index fc8f91933..d3357c97f 100644 --- a/doc/ref/slib.texi +++ b/doc/ref/slib.texi @@ -4,7 +4,6 @@ @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. -@page @node SLIB @section SLIB @cindex SLIB @@ -12,9 +11,9 @@ Before the SLIB facilities can be used, the following Scheme expression must be executed: -@smalllisp +@lisp (use-modules (ice-9 slib)) -@end smalllisp +@end lisp @findex require @code{require} can then be used in the usual way (@pxref{Require,,, @@ -64,7 +63,7 @@ Alternatively, you can create a symlink in the Guile directory to SLIB, e.g.: @example -ln -s /usr/local/lib/slib /usr/local/share/guile/1.8/slib +ln -s /usr/local/lib/slib /usr/local/share/guile/@value{EFFECTIVE-VERSION}/slib @end example @item @@ -78,7 +77,7 @@ guile> (quit) @end example The catalog data should now be in -@file{/usr/local/share/guile/1.8/slibcat}. +@file{/usr/local/share/guile/@value{EFFECTIVE-VERSION}/slibcat}. If instead you get an error such as: @@ -104,11 +103,11 @@ It is usually installed as an extra package in SLIB. You can use Guile's interface to SLIB to invoke Jacal: -@smalllisp +@lisp (use-modules (ice-9 slib)) (slib:load "math") (math) -@end smalllisp +@end lisp @noindent For complete documentation on Jacal, please read the Jacal manual. If diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index 1fa50b209..7c107e710 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -47,6 +47,7 @@ get the relevant SRFI documents from the SRFI home page * SRFI-61:: A more general `cond' clause * SRFI-69:: Basic hash tables. * SRFI-88:: Keyword objects. +* SRFI-98:: Accessing environment variables. @end menu @@ -3608,6 +3609,25 @@ Return the keyword object whose name is @var{str}. @end example @end deffn +@node SRFI-98 +@subsection SRFI-98 Accessing environment variables. +@cindex SRFI-98 +@cindex environment variables + +This is a portable wrapper around Guile's built-in support for +interacting with the current environment, @xref{Runtime Environment}. + +@deffn {Scheme Procedure} get-environment-variable name +Returns a string containing the value of the environment variable +given by the string @code{name}, or @code{#f} if the named +environment variable is not found. This is equivalent to +@code{(getenv name)}. +@end deffn + +@deffn {Scheme Procedure} get-environment-variables +Returns the names and values of all the environment variables as an +association list in which both the keys and the values are strings. +@end deffn @c srfi-modules.texi ends here diff --git a/doc/ref/tools.texi b/doc/ref/tools.texi index f2116dd71..8b0d3a3bb 100644 --- a/doc/ref/tools.texi +++ b/doc/ref/tools.texi @@ -232,8 +232,8 @@ is a expression suitable for initializing a new variable. For procedures, you can use @code{SCM_DEFINE} for most purposes. Use @code{SCM_PROC} along with @code{SCM_REGISTER_PROC} when you don't want to be bothered with docstrings. Use @code{SCM_GPROC} for generic -functions (@pxref{Creating Generic Functions,,, goops, GOOPS}). All -procedures are declared with return type @code{SCM}. +functions (@pxref{Creating Generic Functions}). All procedures are +declared with return type @code{SCM}. For everything else, use the appropriate macro (@code{SCM_SYMBOL} for symbols, and so on). Without "_GLOBAL_", the declarations are @@ -364,7 +364,7 @@ of the form: @example (define-module (scripts PROGRAM) - :export (PROGRAM)) + #:export (PROGRAM)) @end example Feel free to export other definitions useful in the module context. diff --git a/doc/ref/vm.texi b/doc/ref/vm.texi new file mode 100644 index 000000000..43b265596 --- /dev/null +++ b/doc/ref/vm.texi @@ -0,0 +1,1019 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 2008,2009 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@node A Virtual Machine for Guile +@section A Virtual Machine for Guile + +Guile has both an interpreter and a compiler. To a user, the +difference is largely transparent---interpreted and compiled +procedures can call each other as they please. + +The difference is that the compiler creates and interprets bytecode +for a custom virtual machine, instead of interpreting the +S-expressions directly. Loading and running compiled code is faster +than loading and running source code. + +The virtual machine that does the bytecode interpretation is a part of +Guile itself. This section describes the nature of Guile's virtual +machine. + +@menu +* Why a VM?:: +* VM Concepts:: +* Stack Layout:: +* Variables and the VM:: +* VM Programs:: +* Instruction Set:: +@end menu + +@node Why a VM? +@subsection Why a VM? + +@cindex interpreter +@cindex evaluator +For a long time, Guile only had an interpreter, called the +@dfn{evaluator}. Guile's evaluator operates directly on the +S-expression representation of Scheme source code. + +But while the evaluator is highly optimized and hand-tuned, and +contains some extensive speed trickery (@pxref{Memoization}), it still +performs many needless computations during the course of evaluating an +expression. For example, application of a function to arguments +needlessly conses up the arguments in a list. Evaluation of an +expression always has to figure out what the car of the expression is +-- a procedure, a memoized form, or something else. All values have to +be allocated on the heap. Et cetera. + +The solution to this problem is to compile the higher-level language, +Scheme, into a lower-level language for which all of the checks and +dispatching have already been done---the code is instead stripped to +the bare minimum needed to ``do the job''. + +The question becomes then, what low-level language to choose? There +are many options. We could compile to native code directly, but that +poses portability problems for Guile, as it is a highly cross-platform +project. + +So we want the performance gains that compilation provides, but we +also want to maintain the portability benefits of a single code path. +The obvious solution is to compile to a virtual machine that is +present on all Guile installations. + +The easiest (and most fun) way to depend on a virtual machine is to +implement the virtual machine within Guile itself. This way the +virtual machine provides what Scheme needs (tail calls, multiple +values, @code{call/cc}) and can provide optimized inline instructions +for Guile (@code{cons}, @code{struct-ref}, etc.). + +So this is what Guile does. The rest of this section describes that VM +that Guile implements, and the compiled procedures that run on it. + +Note that this decision to implement a bytecode compiler does not +preclude native compilation. We can compile from bytecode to native +code at runtime, or even do ahead of time compilation. More +possibilities are discussed in @ref{Extending the Compiler}. + +@node VM Concepts +@subsection VM Concepts + +A virtual machine (VM) is a Scheme object. Users may create virtual +machines using the standard procedures described later in this manual, +but that is usually unnecessary, as Guile ensures that there is one +virtual machine per thread. When a VM-compiled procedure is run, Guile +looks up the virtual machine for the current thread and executes the +procedure using that VM. + +Guile's virtual machine is a stack machine---that is, it has few +registers, and the instructions defined in the VM operate by pushing +and popping values from a stack. + +Stack memory is exclusive to the virtual machine that owns it. In +addition to their stacks, virtual machines also have access to the +global memory (modules, global bindings, etc) that is shared among +other parts of Guile, including other VMs. + +A VM has generic instructions, such as those to reference local +variables, and instructions designed to support Guile's languages -- +mathematical instructions that support the entire numerical tower, an +inlined implementation of @code{cons}, etc. + +The registers that a VM has are as follows: + +@itemize +@item ip - Instruction pointer +@item sp - Stack pointer +@item fp - Frame pointer +@end itemize + +In other architectures, the instruction pointer is sometimes called +the ``program counter'' (pc). This set of registers is pretty typical +for stack machines; their exact meanings in the context of Guile's VM +are described in the next section. + +A virtual machine executes by loading a compiled procedure, and +executing the object code associated with that procedure. Of course, +that procedure may call other procedures, tail-call others, ad +infinitum---indeed, within a guile whose modules have all been +compiled to object code, one might never leave the virtual machine. + +@c wingo: The following is true, but I don't know in what context to +@c describe it. A documentation FIXME. + +@c A VM may have one of three engines: reckless, regular, or debugging. +@c Reckless engine is fastest but dangerous. Regular engine is normally +@c fail-safe and reasonably fast. Debugging engine is safest and +@c functional but very slow. + +@c (Actually we have just a regular and a debugging engine; normally +@c we use the latter, it's almost as fast as the ``regular'' engine.) + +@node Stack Layout +@subsection Stack Layout + +While not strictly necessary to understand how to work with the VM, it +is instructive and sometimes entertaining to consider the structure of +the VM stack. + +Logically speaking, a VM stack is composed of ``frames''. Each frame +corresponds to the application of one compiled procedure, and contains +storage space for arguments, local variables, intermediate values, and +some bookkeeping information (such as what to do after the frame +computes its value). + +While the compiler is free to do whatever it wants to, as long as the +semantics of a computation are preserved, in practice every time you +call a function, a new frame is created. (The notable exception of +course is the tail call case, @pxref{Tail Calls}.) + +Within a frame, you have the data associated with the function +application itself, which is of a fixed size, and the stack space for +intermediate values. Sometimes only the former is referred to as the +``frame'', and the latter is the ``stack'', although all pending +application frames can have some intermediate computations interleaved +on the stack. + +The structure of the fixed part of an application frame is as follows: + +@example + Stack + | ... | + | Intermed. val. 0 | <- fp + bp->nargs + bp->nlocs = SCM_FRAME_UPPER_ADDRESS (fp) + +==================+ + | Local variable 1 | + | Local variable 0 | <- fp + bp->nargs + | Argument 1 | + | Argument 0 | <- fp + | Program | <- fp - 1 + +------------------+ + | Return address | + | MV return address| + | Dynamic link | <- fp - 4 = SCM_FRAME_DATA_ADDRESS (fp) = SCM_FRAME_LOWER_ADDRESS (fp) + +==================+ + | | +@end example + +In the above drawing, the stack grows upward. The intermediate values +stored in the application of this frame are stored above +@code{SCM_FRAME_UPPER_ADDRESS (fp)}. @code{bp} refers to the +@code{struct scm_objcode} data associated with the program at +@code{fp - 1}. @code{nargs} and @code{nlocs} are properties of the +compiled procedure, which will be discussed later. + +The individual fields of the frame are as follows: + +@table @asis +@item Return address +The @code{ip} that was in effect before this program was applied. When +we return from this activation frame, we will jump back to this +@code{ip}. + +@item MV return address +The @code{ip} to return to if this application returns multiple +values. For continuations that only accept one value, this value will +be @code{NULL}; for others, it will be an @code{ip} that points to a +multiple-value return address in the calling code. That code will +expect the top value on the stack to be an integer---the number of +values being returned---and that below that integer there are the +values being returned. + +@item Dynamic link +This is the @code{fp} in effect before this program was applied. In +effect, this and the return address are the registers that are always +``saved''. The dynamic link links the current frame to the previous +frame; computing a stack trace involves traversing these frames. + +@item Local variable @var{n} +Lambda-local variables that are all allocated as part of the frame. +This makes access to variables very cheap. + +@item Argument @var{n} +The calling convention of the VM requires arguments of a function +application to be pushed on the stack, and here they are. References +to arguments dispatch to these locations on the stack. + +@item Program +This is the program being applied. For more information on how +programs are implemented, @xref{VM Programs}. +@end table + +@node Variables and the VM +@subsection Variables and the VM + +Consider the following Scheme code as an example: + +@example + (define (foo a) + (lambda (b) (list foo a b))) +@end example + +Within the lambda expression, @code{foo} is a top-level variable, @code{a} is a +lexically captured variable, and @code{b} is a local variable. + +Another way to refer to @code{a} and @code{b} is to say that @code{a} +is a ``free'' variable, since it is not defined within the lambda, and +@code{b} is a ``bound'' variable. These are the terms used in the +@dfn{lambda calculus}, a mathematical notation for describing +functions. The lambda calculus is useful because it allows one to +prove statements about functions. It is especially good at describing +scope relations, and it is for that reason that we mention it here. + +Guile allocates all variables on the stack. When a lexically enclosed +procedure with free variables---a @dfn{closure}---is created, it +copies those variables its free variable vector. References to free +variables are then redirected through the free variable vector. + +If a variable is ever @code{set!}, however, it will need to be +heap-allocated instead of stack-allocated, so that different closures +that capture the same variable can see the same value. Also, this +allows continuations to capture a reference to the variable, instead +of to its value at one point in time. For these reasons, @code{set!} +variables are allocated in ``boxes''---actually, in variable cells. +@xref{Variables}, for more information. References to @code{set!} +variables are indirected through the boxes. + +Thus perhaps counterintuitively, what would seem ``closer to the +metal'', viz @code{set!}, actually forces an extra memory allocation +and indirection. + +Going back to our example, @code{b} may be allocated on the stack, as +it is never mutated. + +@code{a} may also be allocated on the stack, as it too is never +mutated. Within the enclosed lambda, its value will be copied into +(and referenced from) the free variables vector. + +@code{foo} is a top-level variable, because @code{foo} is not +lexically bound in this example. + +@node VM Programs +@subsection Compiled Procedures are VM Programs + +By default, when you enter in expressions at Guile's REPL, they are +first compiled to VM object code, then that VM object code is executed +to produce a value. If the expression evaluates to a procedure, the +result of this process is a compiled procedure. + +A compiled procedure is a compound object, consisting of its bytecode, +a reference to any captured lexical variables, an object array, and +some metadata such as the procedure's arity, name, and documentation. +You can pick apart these pieces with the accessors in @code{(system vm +program)}. @xref{Compiled Procedures}, for a full API reference. + +@cindex object table +@cindex object array +The object array of a compiled procedure, also known as the +@dfn{object table}, holds all Scheme objects whose values are known +not to change across invocations of the procedure: constant strings, +symbols, etc. The object table of a program is initialized right +before a program is loaded with @code{load-program}. +@xref{Loading Instructions}, for more information. + +Variable objects are one such type of constant object: when a global +binding is defined, a variable object is associated to it and that +object will remain constant over time, even if the value bound to it +changes. Therefore, toplevel bindings only need to be looked up once. +Thereafter, references to the corresponding toplevel variables from +within the program are then performed via the @code{toplevel-ref} +instruction, which uses the object vector, and are almost as fast as +local variable references. + +We can see how these concepts tie together by disassembling the +@code{foo} function we defined earlier to see what is going on: + +@smallexample +scheme@@(guile-user)> (define (foo a) (lambda (b) (list foo a b))) +scheme@@(guile-user)> ,x foo +Disassembly of #<program foo (a)>: + + 0 (object-ref 1) ;; #<program b7e478b0 at <unknown port>:0:16 (b)> + 2 (local-ref 0) ;; `a' (arg) + 4 (vector 0 1) ;; 1 element + 7 (make-closure) + 8 (return) + +---------------------------------------- +Disassembly of #<program b7e478b0 at <unknown port>:0:16 (b)>: + + 0 (toplevel-ref 1) ;; `foo' + 2 (free-ref 0) ;; (closure variable) + 4 (local-ref 0) ;; `b' (arg) + 6 (list 0 3) ;; 3 elements at (unknown file):0:28 + 9 (return) +@end smallexample + +At @code{ip} 0, we load up the compiled lambda. @code{Ip} 2 and 4 +create the free variables vector, and @code{ip} 7 makes the +closure---binding code (from the compiled lambda) with data (the +free-variable vector). Finally we return the closure. + +The second stanza disassembles the compiled lambda. Toplevel variables +are resolved relative to the module that was current when the +procedure was created. This lookup occurs lazily, at the first time +the variable is actually referenced, and the location of the lookup is +cached so that future references are very cheap. @xref{Environment +Control Instructions}, for more details. + +Then we see a reference to an external variable, corresponding to +@code{a}. The disassembler doesn't have enough information to give a +name to that variable, so it just marks it as being a ``closure +variable''. Finally we see the reference to @code{b}, then the +@code{list} opcode, an inline implementation of the @code{list} scheme +routine. + +@node Instruction Set +@subsection Instruction Set + +There are about 150 instructions in Guile's virtual machine. These +instructions represent atomic units of a program's execution. Ideally, +they perform one task without conditional branches, then dispatch to +the next instruction in the stream. + +Instructions themselves are one byte long. Some instructions take +parameters, which follow the instruction byte in the instruction +stream. + +Sometimes the compiler can figure out that it is compiling a special +case that can be run more efficiently. So, for example, while Guile +offers a generic test-and-branch instruction, it also offers specific +instructions for special cases, so that the following cases all have +their own test-and-branch instructions: + +@example +(if pred then else) +(if (not pred) then else) +(if (null? l) then else) +(if (not (null? l)) then else) +@end example + +In addition, some Scheme primitives have their own inline +implementations, e.g. @code{cons}, and @code{list}, as we saw in the +previous section. + +So Guile's instruction set is a @emph{complete} instruction set, in +that it provides the instructions that are suited to the problem, and +is not concerned with making a minimal, orthogonal set of +instructions. More instructions may be added over time. + +@menu +* Environment Control Instructions:: +* Branch Instructions:: +* Loading Instructions:: +* Procedural Instructions:: +* Data Control Instructions:: +* Miscellaneous Instructions:: +* Inlined Scheme Instructions:: +* Inlined Mathematical Instructions:: +* Inlined Bytevector Instructions:: +@end menu + +@node Environment Control Instructions +@subsubsection Environment Control Instructions + +These instructions access and mutate the environment of a compiled +procedure---the local bindings, the free (captured) bindings, and the +toplevel bindings. + +Some of these instructions have @code{long-} variants, the difference +being that they take 16-bit arguments, encoded in big-endianness, +instead of the normal 8-bit range. + +@deffn Instruction local-ref index +@deffnx Instruction long-local-ref index +Push onto the stack the value of the local variable located at +@var{index} within the current stack frame. + +Note that arguments and local variables are all in one block. Thus the +first argument, if any, is at index 0, and local bindings follow the +arguments. +@end deffn + +@deffn Instruction local-set index +@deffnx Instruction long-local-ref index +Pop the Scheme object located on top of the stack and make it the new +value of the local variable located at @var{index} within the current +stack frame. +@end deffn + +@deffn Instruction free-ref index +Push the value of the captured variable located at position +@var{index} within the program's vector of captured variables. +@end deffn + +@deffn Instruction free-boxed-ref index +@deffnx Instruction free-boxed-set index +Get or set a boxed free variable. Note that there is no free-set +instruction, as variables that are @code{set!} must be boxed. + +These instructions assume that the value at position @var{index} in +the free variables vector is a variable. +@end deffn + +@deffn Instruction make-closure +Pop a vector and a program object off the stack, in that order, and +push a new program object with the given free variables vector. The +new program object shares state with the original program. + +At the time of this writing, the space overhead of closures is 4 words +per closure. +@end deffn + +@deffn Instruction fix-closure index +Pop a vector off the stack, and set it as the @var{index}th local +variable's free variable vector. The @var{index}th local variable is +assumed to be a procedure. + +This instruction is part of a hack for allocating mutually recursive +procedures. The hack is to first perform a @code{local-set} for all of +the recursive procedures, then fix up the procedures' free variable +bindings in place. This allows most @code{letrec}-bound procedures to +be allocated unboxed on the stack. + +One could of course do a @code{local-ref}, then @code{make-closure}, +then @code{local-set}, but this macroinstruction helps to speed up the +common case. +@end deffn + +@deffn Instruction box index +Pop a value off the stack, and set the @var{index}nth local variable +to a box containing that value. A shortcut for @code{make-variable} +then @code{local-set}, used when binding boxed variables. +@end deffn + +@deffn Instruction empty-box index +Set the @var{indext}h local variable to a box containing a variable +whose value is unbound. Used when compiling some @code{letrec} +expressions. +@end deffn + +@deffn Instruction toplevel-ref index +@deffnx Instruction long-toplevel-ref index +Push the value of the toplevel binding whose location is stored in at +position @var{index} in the object table. + +Initially, a cell in the object table that is used by +@code{toplevel-ref} is initialized to one of two forms. The normal +case is that the cell holds a symbol, whose binding will be looked up +relative to the module that was current when the current program was +created. + +Alternately, the lookup may be performed relative to a particular +module, determined at compile-time (e.g. via @code{@@} or +@code{@@@@}). In that case, the cell in the object table holds a list: +@code{(@var{modname} @var{sym} @var{public?})}. The symbol @var{sym} +will be looked up in the module named @var{modname} (a list of +symbols). The lookup will be performed against the module's public +interface, unless @var{public?} is @code{#f}, which it is for example +when compiling @code{@@@@}. + +In any case, if the symbol is unbound, an error is signalled. +Otherwise the initial form is replaced with the looked-up variable, an +in-place mutation of the object table. This mechanism provides for +lazy variable resolution, and an important cached fast-path once the +variable has been successfully resolved. + +This instruction pushes the value of the variable onto the stack. +@end deffn + +@deffn Instruction toplevel-set index +@deffnx Instruction long-toplevel-set index +Pop a value off the stack, and set it as the value of the toplevel +variable stored at @var{index} in the object table. If the variable +has not yet been looked up, we do the lookup as in +@code{toplevel-ref}. +@end deffn + +@deffn Instruction define +Pop a symbol and a value from the stack, in that order. Look up its +binding in the current toplevel environment, creating the binding if +necessary. Set the variable to the value. +@end deffn + +@deffn Instruction link-now +Pop a value, @var{x}, from the stack. Look up the binding for @var{x}, +according to the rules for @code{toplevel-ref}, and push that variable +on the stack. If the lookup fails, an error will be signalled. + +This instruction is mostly used when loading programs, because it can +do toplevel variable lookups without an object vector. +@end deffn + +@deffn Instruction variable-ref +Dereference the variable object which is on top of the stack and +replace it by the value of the variable it represents. +@end deffn + +@deffn Instruction variable-set +Pop off two objects from the stack, a variable and a value, and set +the variable to the value. +@end deffn + +@deffn Instruction make-variable +Replace the top object on the stack with a variable containing it. +Used in some circumstances when compiling @code{letrec} expressions. +@end deffn + +@deffn Instruction object-ref n +@deffnx Instruction long-object-ref n +Push @var{n}th value from the current program's object vector. The +``long'' variant has a 16-bit index instead of an 8-bit index. +@end deffn + +@node Branch Instructions +@subsubsection Branch Instructions + +All the conditional branch instructions described below work in the +same way: + +@itemize +@item They pop off the Scheme object located on the stack and use it as +the branch condition; +@item If the condition is true, then the instruction pointer is +increased by the offset passed as an argument to the branch +instruction; +@item Program execution proceeds with the next instruction (that is, +the one to which the instruction pointer points). +@end itemize + +Note that the offset passed to the instruction is encoded on two 8-bit +integers which are then combined by the VM as one 16-bit integer. Note +also that jump targets in Guile are aligned on 8-byte boundaries, and +that the offset refers to the @var{n}th 8-byte boundary, effectively +giving Guile a 19-bit relative address space. + +@deffn Instruction br offset +Jump to @var{offset}. +@end deffn + +@deffn Instruction br-if offset +Jump to @var{offset} if the condition on the stack is not false. +@end deffn + +@deffn Instruction br-if-not offset +Jump to @var{offset} if the condition on the stack is false. +@end deffn + +@deffn Instruction br-if-eq offset +Jump to @var{offset} if the two objects located on the stack are +equal in the sense of @var{eq?}. Note that, for this instruction, the +stack pointer is decremented by two Scheme objects instead of only +one. +@end deffn + +@deffn Instruction br-if-not-eq offset +Same as @var{br-if-eq} for non-@code{eq?} objects. +@end deffn + +@deffn Instruction br-if-null offset +Jump to @var{offset} if the object on the stack is @code{'()}. +@end deffn + +@deffn Instruction br-if-not-null offset +Jump to @var{offset} if the object on the stack is not @code{'()}. +@end deffn + + +@node Loading Instructions +@subsubsection Loading Instructions + +In addition to VM instructions, an instruction stream may contain +variable-length data embedded within it. This data is always preceded +by special loading instructions, which interpret the data and advance +the instruction pointer to the next VM instruction. + +All of these loading instructions have a @code{length} parameter, +indicating the size of the embedded data, in bytes. The length itself +is encoded in 3 bytes. + +@deffn Instruction load-number length +Load an arbitrary number from the instruction stream. The number is +embedded in the stream as a string. +@end deffn +@deffn Instruction load-string length +Load a string from the instruction stream. The string is assumed to be +encoded in the ``latin1'' locale. +@end deffn +@deffn Instruction load-wide-string length +Load a UTF-32 string from the instruction stream. @var{length} is the +length in bytes, not in codepoints +@end deffn +@deffn Instruction load-symbol length +Load a symbol from the instruction stream. The symbol is assumed to be +encoded in the ``latin1'' locale. Symbols backed by wide strings may +be loaded via @code{load-wide-string} then @code{make-symbol}. +@end deffn +@deffn Instruction load-array length +Load a uniform array from the instruction stream. The shape and type +of the array are popped off the stack, in that order. +@end deffn + +@deffn Instruction load-program +Load bytecode from the instruction stream, and push a compiled +procedure. + +This instruction pops one value from the stack: the program's object +table, as a vector, or @code{#f} in the case that the program has no +object table. A program that does not reference toplevel bindings and +does not use @code{object-ref} does not need an object table. + +This instruction is unlike the rest of the loading instructions, +because instead of parsing its data, it directly maps the instruction +stream onto a C structure, @code{struct scm_objcode}. @xref{Bytecode +and Objcode}, for more information. + +The resulting compiled procedure will not have any free variables +captured, so it may be loaded only once but used many times to create +closures. +@end deffn + +@node Procedural Instructions +@subsubsection Procedural Instructions + +@deffn Instructions new-frame +Push a new frame on the stack, reserving space for the dynamic link, +return address, and the multiple-values return address. The frame +pointer is not yet updated, because the frame is not yet active -- it +has to be patched by a @code{call} instruction to get the return +address. +@end deffn + +@deffn Instruction call nargs +Call the procedure located at @code{sp[-nargs]} with the @var{nargs} +arguments located from @code{sp[-nargs + 1]} to @code{sp[0]}. + +This instruction requires that a new frame be pushed on the stack +before the procedure, via @code{new-frame}. @xref{Stack Layout}, for +more information. It patches up that frame with the current @code{ip} +as the return address, then dispatches to the first instruction in the +called procedure, relying on the called procedure to return one value +to the newly-created continuation. Because the new frame pointer will +point to sp[-nargs + 1], the arguments don't have to be shuffled +around -- they are already in place. + +For non-compiled procedures (continuations, primitives, and +interpreted procedures), @code{call} will pop the frame, procedure, +and arguments off the stack, and push the result of calling +@code{scm_apply}. +@end deffn + +@deffn Instruction goto/args nargs +Like @code{call}, but reusing the current continuation. This +instruction implements tail calls as required by RnRS. + +For compiled procedures, that means that @code{goto/args} simply +shuffles down the procedure and arguments to the current stack frame. +The @code{goto/*} instruction family is named as it is because tail +calls are equivalent to @code{goto}, along with relabeled variables. + +For non-VM procedures, the result is the same, but the current VM +invocation remains on the C stack. True tail calls are not currently +possible between compiled and non-compiled procedures. +@end deffn + +@deffn Instruction apply nargs +@deffnx Instruction goto/apply nargs +Like @code{call} and @code{goto/args}, except that the top item on the +stack must be a list. The elements of that list are then pushed on the +stack and treated as additional arguments, replacing the list itself, +then the procedure is invoked as usual. +@end deffn + +@deffn Instruction call/nargs +@deffnx Instruction goto/nargs +These are like @code{call} and @code{goto/args}, except they take the +number of arguments from the stack instead of the instruction stream. +These instructions are used in the implementation of multiple value +returns, where the actual number of values is pushed on the stack. +@end deffn + +@deffn Instruction mv-call nargs offset +Like @code{call}, except that a multiple-value continuation is created +in addition to a single-value continuation. + +The offset (a two-byte value) is an offset within the instruction +stream; the multiple-value return address in the new frame +(@pxref{Stack Layout}) will be set to the normal return address plus +this offset. Instructions at that offset will expect the top value of +the stack to be the number of values, and below that values +themselves, pushed separately. +@end deffn + +@deffn Instruction return +Free the program's frame, returning the top value from the stack to +the current continuation. (The stack should have exactly one value on +it.) + +Specifically, the @code{sp} is decremented to one below the current +@code{fp}, the @code{ip} is reset to the current return address, the +@code{fp} is reset to the value of the current dynamic link, and then +the top item on the stack (formerly the procedure being applied) is +set to the returned value. +@end deffn + +@deffn Instruction return/values nvalues +Return the top @var{nvalues} to the current continuation. + +If the current continuation is a multiple-value continuation, +@code{return/values} pushes the number of values on the stack, then +returns as in @code{return}, but to the multiple-value return address. + +Otherwise if the current continuation accepts only one value, i.e. the +multiple-value return address is @code{NULL}, then we assume the user +only wants one value, and we give them the first one. If there are no +values, an error is signaled. +@end deffn + +@deffn Instruction return/values* nvalues +Like a combination of @code{apply} and @code{return/values}, in which +the top value on the stack is interpreted as a list of additional +values. This is an optimization for the common @code{(apply values +...)} case. +@end deffn + +@deffn Instruction truncate-values nbinds nrest +Used in multiple-value continuations, this instruction takes the +values that are on the stack (including the number-of-values marker) +and truncates them for a binding construct. + +For example, a call to @code{(receive (x y . z) (foo) ...)} would, +logically speaking, pop off the values returned from @code{(foo)} and +push them as three values, corresponding to @code{x}, @code{y}, and +@code{z}. In that case, @var{nbinds} would be 3, and @var{nrest} would +be 1 (to indicate that one of the bindings was a rest argument). + +Signals an error if there is an insufficient number of values. +@end deffn + +@deffn Instruction call/cc +@deffnx Instruction goto/cc +Capture the current continuation, and then call (or tail-call) the +procedure on the top of the stack, with the continuation as the +argument. + +@code{call/cc} does not require a @code{new-frame} to be pushed on the +stack, as @code{call} does, because it needs to capture the stack +before the frame is pushed. + +Both the VM continuation and the C continuation are captured. +@end deffn + +@node Data Control Instructions +@subsubsection Data Control Instructions + +These instructions push simple immediate values onto the stack, or +manipulate lists and vectors on the stack. + +@deffn Instruction make-int8 value +Push @var{value}, an 8-bit integer, onto the stack. +@end deffn + +@deffn Instruction make-int8:0 +Push the immediate value @code{0} onto the stack. +@end deffn + +@deffn Instruction make-int8:1 +Push the immediate value @code{1} onto the stack. +@end deffn + +@deffn Instruction make-int16 value +Push @var{value}, a 16-bit integer, onto the stack. +@end deffn + +@deffn Instruction make-uint64 value +Push @var{value}, an unsigned 64-bit integer, onto the stack. The +value is encoded in 8 bytes, most significant byte first (big-endian). +@end deffn + +@deffn Instruction make-int64 value +Push @var{value}, a signed 64-bit integer, onto the stack. The value +is encoded in 8 bytes, most significant byte first (big-endian), in +twos-complement arithmetic. +@end deffn + +@deffn Instruction make-false +Push @code{#f} onto the stack. +@end deffn + +@deffn Instruction make-true +Push @code{#t} onto the stack. +@end deffn + +@deffn Instruction make-eol +Push @code{'()} onto the stack. +@end deffn + +@deffn Instruction make-char8 value +Push @var{value}, an 8-bit character, onto the stack. +@end deffn + +@deffn Instruction make-char32 value +Push @var{value}, an 32-bit character, onto the stack. The value is +encoded in big-endian order. +@end deffn + +@deffn Instruction make-symbol +Pops a string off the stack, and pushes a symbol. +@end deffn + +@deffn Instruction make-keyword value +Pops a symbol off the stack, and pushes a keyword. +@end deffn + +@deffn Instruction list n +Pops off the top @var{n} values off of the stack, consing them up into +a list, then pushes that list on the stack. What was the topmost value +will be the last element in the list. @var{n} is a two-byte value, +most significant byte first. +@end deffn + +@deffn Instruction vector n +Create and fill a vector with the top @var{n} values from the stack, +popping off those values and pushing on the resulting vector. @var{n} +is a two-byte value, like in @code{vector}. +@end deffn + +@node Miscellaneous Instructions +@subsubsection Miscellaneous Instructions + +@deffn Instruction nop +Does nothing! Used for padding other instructions to certain +alignments. +@end deffn + +@deffn Instruction halt +Exits the VM, returning a SCM value. Normally, this instruction is +only part of the ``bootstrap program'', a program run when a virtual +machine is first entered; compiled Scheme procedures will not contain +this instruction. + +If multiple values have been returned, the SCM value will be a +multiple-values object (@pxref{Multiple Values}). +@end deffn + +@deffn Instruction break +Does nothing, but invokes the break hook. +@end deffn + +@deffn Instruction drop +Pops off the top value from the stack, throwing it away. +@end deffn + +@deffn Instruction dup +Re-pushes the top value onto the stack. +@end deffn + +@deffn Instruction void +Pushes ``the unspecified value'' onto the stack. +@end deffn + +@node Inlined Scheme Instructions +@subsubsection Inlined Scheme Instructions + +The Scheme compiler can recognize the application of standard Scheme +procedures. It tries to inline these small operations to avoid the +overhead of creating new stack frames. + +Since most of these operations are historically implemented as C +primitives, not inlining them would entail constantly calling out from +the VM to the interpreter, which has some costs---registers must be +saved, the interpreter has to dispatch, called procedures have to do +much typechecking, etc. It's much more efficient to inline these +operations in the virtual machine itself. + +All of these instructions pop their arguments from the stack and push +their results, and take no parameters from the instruction stream. +Thus, unlike in the previous sections, these instruction definitions +show stack parameters instead of parameters from the instruction +stream. + +@deffn Instruction not x +@deffnx Instruction not-not x +@deffnx Instruction eq? x y +@deffnx Instruction not-eq? x y +@deffnx Instruction null? +@deffnx Instruction not-null? +@deffnx Instruction eqv? x y +@deffnx Instruction equal? x y +@deffnx Instruction pair? x y +@deffnx Instruction list? x +@deffnx Instruction set-car! pair x +@deffnx Instruction set-cdr! pair x +@deffnx Instruction slot-ref struct n +@deffnx Instruction slot-set struct n x +@deffnx Instruction cons x y +@deffnx Instruction car x +@deffnx Instruction cdr x +@deffnx Instruction vector-ref x y +@deffnx Instruction vector-set x n y +Inlined implementations of their Scheme equivalents. +@end deffn + +Note that @code{caddr} and friends compile to a series of @code{car} +and @code{cdr} instructions. + +@node Inlined Mathematical Instructions +@subsubsection Inlined Mathematical Instructions + +Inlining mathematical operations has the obvious advantage of handling +fixnums without function calls or allocations. The trick, of course, +is knowing when the result of an operation will be a fixnum, and there +might be a couple bugs here. + +More instructions could be added here over time. + +As in the previous section, the definitions below show stack +parameters instead of instruction stream parameters. + +@deffn Instruction add x y +@deffnx Instruction add1 x +@deffnx Instruction sub x y +@deffnx Instruction sub1 x +@deffnx Instruction mul x y +@deffnx Instruction div x y +@deffnx Instruction quo x y +@deffnx Instruction rem x y +@deffnx Instruction mod x y +@deffnx Instruction ee? x y +@deffnx Instruction lt? x y +@deffnx Instruction gt? x y +@deffnx Instruction le? x y +@deffnx Instruction ge? x y +Inlined implementations of the corresponding mathematical operations. +@end deffn + +@node Inlined Bytevector Instructions +@subsubsection Inlined Bytevector Instructions + +Bytevector operations correspond closely to what the current hardware +can do, so it makes sense to inline them to VM instructions, providing +a clear path for eventual native compilation. Without this, Scheme +programs would need other primitives for accessing raw bytes -- but +these primitives are as good as any. + +As in the previous section, the definitions below show stack +parameters instead of instruction stream parameters. + +The multibyte formats (@code{u16}, @code{f64}, etc) take an extra +endianness argument. Only aligned native accesses are currently +fast-pathed in Guile's VM. + +@deffn Instruction bv-u8-ref bv n +@deffnx Instruction bv-s8-ref bv n +@deffnx Instruction bv-u16-native-ref bv n +@deffnx Instruction bv-s16-native-ref bv n +@deffnx Instruction bv-u32-native-ref bv n +@deffnx Instruction bv-s32-native-ref bv n +@deffnx Instruction bv-u64-native-ref bv n +@deffnx Instruction bv-s64-native-ref bv n +@deffnx Instruction bv-f32-native-ref bv n +@deffnx Instruction bv-f64-native-ref bv n +@deffnx Instruction bv-u16-ref bv n endianness +@deffnx Instruction bv-s16-ref bv n endianness +@deffnx Instruction bv-u32-ref bv n endianness +@deffnx Instruction bv-s32-ref bv n endianness +@deffnx Instruction bv-u64-ref bv n endianness +@deffnx Instruction bv-s64-ref bv n endianness +@deffnx Instruction bv-f32-ref bv n endianness +@deffnx Instruction bv-f64-ref bv n endianness +@deffnx Instruction bv-u8-set bv n val +@deffnx Instruction bv-s8-set bv n val +@deffnx Instruction bv-u16-native-set bv n val +@deffnx Instruction bv-s16-native-set bv n val +@deffnx Instruction bv-u32-native-set bv n val +@deffnx Instruction bv-s32-native-set bv n val +@deffnx Instruction bv-u64-native-set bv n val +@deffnx Instruction bv-s64-native-set bv n val +@deffnx Instruction bv-f32-native-set bv n val +@deffnx Instruction bv-f64-native-set bv n val +@deffnx Instruction bv-u16-set bv n val endianness +@deffnx Instruction bv-s16-set bv n val endianness +@deffnx Instruction bv-u32-set bv n val endianness +@deffnx Instruction bv-s32-set bv n val endianness +@deffnx Instruction bv-u64-set bv n val endianness +@deffnx Instruction bv-s64-set bv n val endianness +@deffnx Instruction bv-f32-set bv n val endianness +@deffnx Instruction bv-f64-set bv n val endianness +Inlined implementations of the corresponding bytevector operations. +@end deffn |