diff options
Diffstat (limited to 'doc/ref')
41 files changed, 25265 insertions, 0 deletions
diff --git a/doc/ref/.cvsignore b/doc/ref/.cvsignore new file mode 100644 index 000000000..8eaa8267a --- /dev/null +++ b/doc/ref/.cvsignore @@ -0,0 +1,23 @@ +Makefile +Makefile.in +stamp-vti +stamp-vti.1 +*.log +*.dvi +*.aux +*.toc +*.cp +*.fn +*.vr +*.tp +*.ky +*.pg +*.cps +*.fns +*.tps +*.vrs +*.ps +*.info* +*.html +version.texi +version-tutorial.texi diff --git a/doc/ref/ChangeLog-guile-doc-ref b/doc/ref/ChangeLog-guile-doc-ref new file mode 100644 index 000000000..3d2cc4e09 --- /dev/null +++ b/doc/ref/ChangeLog-guile-doc-ref @@ -0,0 +1,890 @@ +2001-03-09 Neil Jerram <neil@ossau.uklinux.net> + + Moving texinfo files from guile-doc/ref into guile-core/doc: + + * env.texi, indices.texi, mbapi.texi, mltext.texi, scripts.texi, + scsh.texi, tcltk.texi, hierarchy.txt, scheme-indices.texi, + slib.texi, deprecated.texi, scheme-binding.texi, appendices.texi, + scheme-intro.texi, goops.texi, extend.texi, gh.texi, intro.texi, + preface.texi, scm.texi, goops-tutorial.texi, hierarchy.eps, + r4rs.texi, r5rs.texi, texinfo.tex, scheme-reading.texi, + data-rep.texi, scheme-utility.texi, posix.texi, + scheme-control.texi, scheme-debug.texi, scheme-evaluation.texi, + scheme-io.texi, scheme-memory.texi, scheme-modules.texi, + scheme-options.texi, scheme-procedures.texi, + scheme-scheduling.texi, scheme-translation.texi, guile.texi, + scheme-data.texi, scheme-ideas.texi, expect.texi: Removed. + +2001-02-28 Gary Houston <ghouston@arglist.com> + + * expect.texi (Expect): add missing eof? argument in example code. + +2001-02-27 Neil Jerram <neil@ossau.uklinux.net> + + * guile.texi, scheme-data.texi, scheme-ideas.texi: Remove the code + that set paragraph indent to zero, then add @noindent to several + places that need not to be indented. + +2001-02-24 Neil Jerram <neil@ossau.uklinux.net> + + * posix.texi (File System, Time), scheme-control.texi + (Exceptions), scheme-data.texi (Complex, Primitive Numerics, + Random, String Fun, Symbols and Variables, Lists, Bit Vectors, + Hooks), scheme-debug.texi (Debugging), scheme-evaluation.texi + (Reader Extensions, Scheme Read, Fly Evaluation, Loading, + Evaluator Options), scheme-io.texi (Reading, Writing, Default + Ports, File Ports), scheme-memory.texi (Garbage Collection, + Guardians, Objects), scheme-modules.texi (The Guile module + system), scheme-options.texi (Install Config), + scheme-procedures.texi (Procedure Properties, Procedures with + Setters), scheme-scheduling.texi (Arbiters, Asyncs), + scheme-translation.texi (Emacs Lisp Support): Automatic docstring + updates. + + * scheme-io.texi (Binary IO): New node. + + * scheme-control.texi (Multiple Values): New node. + +2001-02-23 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-utility.texi (Sorting), scheme-procedures.texi (Procedure + Properties), scheme-memory.texi (Guardians), scheme-io.texi + (Line/Delimited), scheme-data.texi (String Fun, Symbols and + Variables, Vtables), posix.texi (Ports and File Descriptors, File + System, Network Sockets and Communication): Automatic docstring + updates. + +2001-02-15 Neil Jerram <neil@ossau.uklinux.net> + + * data-rep.texi: Preserve, in comments beginning `@c essay', + material from the standalone version of this essay which is very + soon to be retired from its current location at + guile-core/doc/data-rep.texi. + + * data-rep.texi: Incorporate recent changes to smob example + documentation from the standalone version of this essay. + +2001-02-02 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-reading.texi (Further Reading): Add reference to online + version of SICP. + +2001-01-27 Neil Jerram <neil@ossau.uklinux.net> + + Further changes to get everything to build to dvi with the latest + texinfo.tex. + + * texinfo.tex: Replaced by latest version from ftp.gnu.org. + + * r5rs.texi (Binding constructs): Remove @c inside @t{...} at + lines 2207-2209. + (Lexical structure): Remove @c inside @t{...} at line 7517. + + * r4rs.texi (Example): Remove @c inside @t{...} at lines 6557 and + 6569. + +2001-01-26 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (Handling Errors): Improved markup. + (snarfing): Deleted. + + * data-rep.texi: File copied here from sources directory and + integrated into the reference manual structure. + + * extend.texi (Libguile Intro): New file, new node, to introduce + new Part. + + * guile.texi: Merged Parts V and VI into a single Part: "Extending + Applications Using Guile". Improved some top level node names and + descriptions. Include extend.texi and data-rep.texi. + + * preface.texi (Manual Layout): Updated according to merge of + Parts V and VI. + + * gh.texi: Restructured into a single chapter. + + * scm.texi (C Port Interface, Port Implementation): Moved here + from scheme-io.texi. + + * scheme-io.texi (Default Ports): Renamed from `Port + Environment'. + (Port Internals): Contents moved to scm.texi. + + * r5rs.texi: Changes to allow building of r5rs.dvi from r5rs.texi. + Aubrey Jaffer's view - which I agree with - is that, given that + people have the option of building r5rs.dvi from the original + LaTeX distribution for R5RS, it is not worth fixing his master + copy of r5rs.texi and the tool which autogenerates it. On the + other hand, it is a marginal convenience for people to be able to + build hardcopy from r5rs.texi, even if the results are less good + than with the original LaTeX. Hence the following fixes. + (lines 714, 725, 728, 1614, 2258): Remove invalid parentheses from + @deffn statements. + (line 2316): Change @deffnx to @deffn, and insert `@end deffn' to + terminate preceding @deffn. + (line 7320): Insert `@c ' at beginning of lines that are intended + to be @ignore'd. + + * guile.texi, r4rs.texi, r5rs.texi: Align @direntry descriptions + to start in column 32. + +2001-01-24 Neil Jerram <neil@ossau.uklinux.net> + + * intro.texi: Licensing and Layout material moved to + preface.texi. + (Whirlwind Tour): New chapter as top level for preexisting + sections. + + * guile.texi: Various minor changes to improve the structure at + the beginning of the reference manual. + + * preface.texi: New file, to split out "prefatory material". + Initially with Licensing and Layout material taken from + intro.texi. + + * Makefile.am (dist_texis): Add preface.texi. + +2001-01-19 Neil Jerram <neil@ossau.uklinux.net> + + * intro.texi: Change R4RS everywhere to R5RS. + (What is Guile?): Change "compiling" to "translating". + +2001-01-07 Neil Jerram <neil@ossau.uklinux.net> + + * appendices.texi (Internals): Content merged into Symbols and + Variables node of scheme-data.texi. + (Reporting Bugs): Moved to manual Part I. + + * guile.texi: Inserted new Part for `Guile Modules' as distinct + from core Guile Scheme language/features. Other parts renumbered + correspondingly. Module chapters moved into new part. + + * intro.texi (Reporting Bugs): Node moved here from + appendices.texi. + + * posix.texi (POSIX): Node name changed from `POSIX System Calls + and Networking'. + + * scheme-data.texi (Symbols and Variables): Added texinfo markup + to docstrings that didn't have it. Expanded snarfed argument + names like `o' and `s' to `obarray' and `string'. + + * scheme-debug.texi (Debugging): Node name changed from `Internal + Debugging Interface'. + + * scheme-evaluation.texi (Fly Evaluation): Moved doc for + `interaction-environment' here (previously under module doc). + + * scheme-memory.texi: Structure reorganization. + + * scheme-modules.texi: Structure reorganization. Removed empty + subsections `First-class Variables' and `First-class Modules'. + + * scheme-options.texi (Options and Config): Node name changed from + `Options'. + (Install Config) Node name changed from `Configuration Data'. + + * scheme-scheduling.texi (Scheduling): Node name changed from + `Threads and Dynamic Roots'. + + * scheme-translation.texi (Translation): New top level node for + translation documentation. + +2001-01-05 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-exceptions.texi: Removed. + + * Makefile.am (dist_texis): Removed scheme-exceptions.texi. + + * guile.texi (Top): Renamed/redescribed some top level nodes. No + longer include scheme-exceptions.texi. + + * scheme-control.texi: Merge material that was previously in + scheme-exceptions.texi. + + * posix.texi: Updated close-port reference. + + * scheme-binding.texi, scheme-control.texi, + scheme-evaluation.texi, scheme-intro.texi, scheme-io.texi, + scheme-procedures.texi, scheme-utility.texi: Massaged into desired + structure. + + * scheme-data.texi (Generic Data Types): Changed to "Data Types". + (Numbers) Introduction streamlined. + (Complex Numbers) New material. + +2001-01-05 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi, scheme-io.texi, scheme-memory.texi, + scheme-options.texi: Where a single docstring documents more than + one primitive, add a docstring comment for each additionally + documented primitive. + + * scheme-modules.texi: Update docstring for dynamic-func. + + * scheme-data.texi (Numbers, Numerical Tower, Integers, Reals and + Rationals, Number Syntax): New material. + + * deprecated.texi (Deprecated): Remove obsolete MD5 comment line. + +2000-12-12 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi (Numbers): Documentation added for scientific + functions. + + * Makefile.am (dist_texis): Updated following split of scheme.texi + into per-chapter files. + +2000-12-07 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi (Booleans): Written. + (Numbers): Introduction written, primitives organized into + subsections. + +2000-12-06 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi (Generic Data Types): Added chapter + introduction. + (Bitwise Operations, Random): Moved underneath Numbers. + (Other Data Types): New placeholder section for data types that + are documented elsewhere. + + * scheme-indices.texi, scheme-reading.texi: Added Local Variables + block. + +2000-12-06 Neil Jerram <neil@ossau.uklinux.net> + + This change replaces scheme.texi, which is unmanageably large, by + a set of smaller one-per-chapter files. The set and ordering of + the new files reflects the intended top level structure of the + Guile Scheme part of the reference manual. This structure is not + yet all reflected in the combined Texinfo/Info, though, because I + haven't yet fixed the @node levels appropriately. + + * scheme.texi: Removed, after dividing content into new files. + + * scheme-procedures.texi, scheme-utility.texi, + scheme-binding.texi, scheme-control.texi, scheme-io.texi, + scheme-evaluation.texi, scheme-exceptions.texi, + scheme-memory.texi, scheme-modules.texi, scheme-scheduling.texi, + scheme-options.texi, scheme-translation.texi, scheme-debug.texi, + slib.texi: New files. + + * guile.texi: @include new files instead of scheme.texi. Reorder + existing top level nodes. + +2000-12-01 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-data.texi: Remove @page breaks (following demotion). + + * guile.texi (Top), scheme-ideas.texi: Demote everything one level + so that previous chapters About Data, About Procedures, About + Expressions and About Closure are now combined into a single + Scheme Ideas chapter. Add overall chapter introduction. Fix up + top level nodes accordingly. + + * guile.texi (Top), scheme.texi, scheme-data.texi: Gather material + for Generic Data Types chapter into a new file + (scheme-data.texi). @include new file in guile.texi. Fix up top + level nodes accordingly. (This changes demotes all the affected + material by one level, except for that which was already grouped + together under the Data Structures node.) + + * guile.texi (Top): @include new files. + + * scheme-intro.texi, scheme-ideas.texi: New files. + + * scheme.texi (Guile and R5RS Scheme): Moved introductory chapter + to its own file (scheme-intro.texi). + (About Closure) Chapter completed. + (About Data, About Procedures, About Expressions, About Closure): + Ideas chapters moved to their own file (scheme-ideas.texi); + scheme.texi was just getting too large! + +2000-11-09 Gary Houston <ghouston@arglist.com> + + * posix.texi (Ports and File Descriptors): updated + close-all-ports-except. + +2000-11-07 Gary Houston <ghouston@arglist.com> + + * posix.texi (Ports and File Descriptors): added dup2, close-fdes + and port-for-each. + (Pipes): synchronise open-input-pipe, open-output-pipe with + popen.scm. + +2000-11-04 Gary Houston <ghouston@arglist.com> + + * scheme.texi (Generic Port Operations): "port?" added. + +2000-11-03 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (About Expressions): New material about evaluation + and program execution. + + * scheme.texi (About Procedures): Minor textual improvements. + +2000-10-29 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (About Expressions, About Closure): Placeholder + structure for remaining introductory Scheme material. + + * guile.texi (Top): Shorten some menu item lines to fit on a + single console line. + +2000-10-28 Neil Jerram <neil@ossau.uklinux.net> + + * scheme-indices.texi (R5RS Index, Guile Extensions Index): Print + new indices. + + * guile.texi: Define new R5RS and Guile extension indices. + +2000-10-27 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (Guile and R5RS Scheme): Filled in examples of Guile + extensions. + (About Procedures): New introductory material. + + * scheme-reading.texi: New file. + + * scheme-indices.texi: New file. + + * intro.texi (Scripting Examples): Added @* to fix TeX overfull + hboxes (twice). + (end of file): Added Local Variables block for TeX-master + variable. + + * scheme.texi (R4RS Scheme): Node changed to "Guile and R5RS + Scheme". Content changed to indicate that we plan to document + both standard Scheme and Guile extensions. + (About Data, About Procedures, About Expressions): New Scheme + introductory material chapters. + (Options): Moved material on Options into its own chapter. + (Coding With Keywords): New subsection; extends material on use of + keywords to include examples of and references to (ice-9 optargs). + (passim): Change many uses of @example to @lisp, since the + formatting seems to come out better in TeX. + (Optional Arguments): New placeholder chapter (empty). + (end of file): Added Local Variables block for TeX-master + variable. + + * guile.texi (Top): "R4RS Scheme" node changed to "Guile and R5RS + Scheme". Added Scheme introductory chapters: About Data, About + Procedures and About Expressions. New Options chapter for options + material. New Optional Arguments chapter as placeholder for + (ice-9 optargs) material. New chapter for "Further Reading". New + chapters for indices showing what is standard Scheme and what is + Guile extension. + +2000-10-25 Mikael Djurfeldt <mdj@linnaeus.mit.edu> + + * Makefile.am: Added goops.texi and new files to dist_texis. + + * goops.texi, goops-tutorial.texi, hierarchy.eps, hierarchy.txt: + New files. + +2000-10-15 Neil Jerram <neil@ossau.uklinux.net> + + * gh.texi (Starting and controlling the interpreter): Removed + obsolete note about boot-9.scm not being loaded by gh_enter. + (Thanks to Chris Cramer for pointing this out.) + +2000-10-06 Neil Jerram <neil@ossau.uklinux.net> + + * guile.texi, scheme.texi, posix.texi: Simplified docstring + comments: (i) they new refer to the Texinfo-format file that is + generated by snarfing when libguile is built, rather than to + individual C files in the libguile source; (ii) there is no longer + a need to keep MD5 digest values for the corresponding source + docstring, since I'm now using a different mechanism for keeping + track of source material changes. + + * scheme.texi (Lists): Use "@example" in docstring for append. + + * guile.texi, scheme.texi (Primitive Properties): New chapter, + documenting new primitive property primitives. + +2000-09-22 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (I/O internals): Add full stops (periods) after + standalone uses of @xref. + + * scheme.texi (Structure Layout): Doc for make-struct-layout + changed to remove reference to "read-only" strings, which no + longer exist. + (Structure Basics): Use @pxref rather than @xref for parenthetical + reference. + (Dynamic Roots): Use @code rather than @var for code, in doc for + call-with-dynamic-root. + (Low level thread primitives): Ditto call-with-new-thread. + (Higher level thread procedures): Ditto call-with-new-thread. + (Symbols and Variables): Docs for gensym and symbol-hash updated + according to libguile changes. + + * posix.texi (Generic Port Operations): Synchronized docstring + for unread-string. + + * gh.texi (Defining new Scheme procedures in C): Avoid texinfo + warning by using @code rather than @var for code. + + * scheme.texi: Lots more docstring comments added, and docs + synchronized with libguile source. + (interaction-environment, make-struct, make-vtable-vtable): Newer, + better doc taken from source file. + (cons-source): New docstring written. + (Vectors): New section added. + (Random, Symbols and Variables): New chapters. + + * posix.texi: Lots more docstring comments added. + (pipe, tzset) Newer, better documentation taken from source file. + + * deprecated.texi: New file, for documenting features that are + deprecated and so planned to disappear. + + * guile.texi (Procedures, Reading and Writing, Random, Sorting, + Symbols and Variables, Deprecated): New chapters in the Scheme + part of the reference manual, to hold docstrings that don't + currently fit anywhere else. + +2000-08-28 Neil Jerram <neil@ossau.uklinux.net> + + * posix.texi (Pipes): open-pipe and close-pipe are procedures (in + ice-9/popen.scm), not primitives. + + * scheme.texi (Generic Port Operations): Remove doc for + port-revealed and set-port-revealed!, since these are covered in + posix.texi. + + * posix.texi: Inserted docstring synchronization comments and + synchronized docstrings for all primitives defined in posix.c, + simpos.c, scmsigs.c, stime.c. + (Ports and File Descriptors) Similarly synchronized port-revealed + and set-port-revealed!. + +2000-08-25 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi: Lots more docstrings added. + + * guile.texi (Top): More new chapters: Pairs, Objects, Guardians, + Emacs Lisp Support. + + * scheme.texi (Numbers): New chapter containing docs (many still + empty right now) for numerical primitives. + + * guile.texi (Top): Add chapter for numerical primitives. + +2000-08-18 Neil Jerram <neil@ossau.uklinux.net> + + * posix.texi (Ports and File Descriptors): Docstring for select + substantially changed by update from libguile source. + + * scheme.texi, posix.texi: Lots more primitive docstrings added. + + * guile.texi (Top): Removed empty Reflection chapter, added new + Hooks chapter. + + * scheme.texi: Added docstrings for all Guile primitives from + libguile files from arbiters.c to error.c. + (Reflection): Empty chapter removed. + + * guile.texi (Top): New chapters "Booleans" and "Equality" + (temporary - until we improve the overall organization). + + * scheme.texi (Uniform Arrays): Fix "indentical" typo. + +2000-08-12 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi: Removed superfluous "@c docstring end" markers - + docstring.el now uses "@end deffn" to find the end of the + docstring. + Added a lot more docstring comments, and synced up docstrings with + libguile - all libguile primitives documented in scheme.texi now + have docstring comments and are up to date. + (Evaluation): Updated docstring for eval and eval-string (now + R5RS-compliant). + + * intro.texi (Guile Scripts): Added a couple of blank lines. + +2000-08-11 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi: Add docstring comments and sync up existing + docstrings with libguile source - complete as far as Association + Lists. + (Keywords): Fill out and improve documentation about + keywords. + + * guile.texi: Set paragraph indent to zero. + +2000-08-07 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (libguile error handling): Add note (text supplied by + Gary Houston) giving a pointer on how to do C exception handling + since scm_error_callback was removed. + +2000-08-01 Dirk Herrmann <D.Herrmann@tu-bs.de> + + * scm.texi (libguile error handling): Removed reference to + scm_error_callback, which is not available any more since + guile-1.3. Thanks to Juli-Manel Merino Vidal and to Gary Houston + for pointing this out. + +2000-07-31 Neil Jerram <neil@ossau.uklinux.net> + + * scm.texi (Relationship between Scheme and C functions): + Expand. (Contributed by Thien-Thi Nguyen <ttn@gnu.org>.) + +2000-07-30 Neil Jerram <neil@ossau.uklinux.net> + + * scheme.texi (Association Lists): New, more complete + documentation. + * guile.texi: New top-level manual file based on guile-ref.texi + but modified to reflect the better organization suggested in + sources/jimb-org.texi. + * expect.texi: New file to separate out Expect doc. + * indices.texi: New file to separate indices from appendices. + * intro.texi: Invoking Guile and Meta Switch nodes moved to Guile + Scripting part (scripts.texi). Manual layout node moved to end of + introduction. + * posix.texi: All nodes downgraded one level. Expect, SCSH and + Tcl/Tk nodes moved to dedicated files. + * scheme.texi: Stuff moved around in accordance with + sources/jimb-org.texi reorganization (cvs diff totally confused, + I'm afraid). + * scsh.texi: New file to separate out SCSH doc. + * scripts.texi: New file to separate out Guile scripting doc. + * tcltk.texi: New file to separate out Tcl/Tk interface doc. + * Makefile.am: Changed guile-ref to guile; more distribution + texis. + * Makefile.in: Changed guile-ref to guile; more distribution + texis. + + +2000-05-14 Marius Vollmer <mvo@zagadka.ping.de> + + * posix.texi (Conventions): Added example on how to retrieve errno + value from a system-exception. Thanks to Eric Hanchrow! + +2000-05-04 Marius Vollmer <mvo@zagadka.ping.de> + + * intro.texi: Added chapter about Guile's license. + * guile-ref.texi: Updated menu. + +1999-12-15 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (SLIB installation): new node. + +1999-12-06 Gary Houston <ghouston@freewire.co.uk> + + * r4rs.texi: tweaked the dircategory/direntry for compatibility + with the r5 version. + guile-ref.texi: tweaked the dircategory. + * Makefile.am (info_TEXINFOS): add r5rs.texi. + * r5rs.texi: new file, lifted from Aubrey Jaffer's site. + +1999-12-04 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (Generic Port Operations): add "port-closed?". + +1999-11-22 Jim Blandy <jimb@savonarola.red-bean.com> + + * mbapi.texi: Don't promise any behavior on ill-formed text. + +1999-11-19 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi: rewrote the intros in the array nodes. + +1999-11-18 Gary Houston <ghouston@freewire.co.uk> + + * posix.texi (Network Sockets and Communication): add htons etc. + (Ports and File Descriptors, Network Sockets and Communication): + suggest setvbuf instead of duplicate-port for converting + unbuffered ports to buffered. + + * scheme.texi (Uniform Array): add missing array types to the + table. + +1999-11-17 Gary Houston <ghouston@freewire.co.uk> + + * posix.texi (Network Databases): updated. + +1999-10-24 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (String Ports): add with-output-to-string and + with-input-from-string. + (Port Implementation): update for ptob seek. + +1999-10-18 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi (C Port Interface): update the description of + the rw_random port flag. + +1999-09-22 Gary Houston <ghouston@freewire.co.uk> + + * scheme.texi: added a bit of documentation for port internals. + +1999-09-12 Gary Houston <ghouston@easynet.co.uk> + + * posix.texi (File System): make that "directory-stream?". + +1999-09-11 Gary Houston <ghouston@easynet.co.uk> + + * posix.texi (File System): added "directory?". + +1999-09-06 James Blandy <jimb@mule.m17n.org> + + * mbapi.texi, mltext.texi: New files, describing interfaces for + dealing with multilingual code. + +1999-07-25 Gary Houston <ghouston@easynet.co.uk> + + * scheme.texi, posix.texi: updated for changes in the I/O system + and expect macros. + +1999-01-25 Mark Galassi <rosalia@cygnus.com> + + * scheme.texi (General option interface): applied a typo fix. + Thanks to Eric Hanchrow (offby1@blarg.net). + +1998-11-01 Mark Galassi <rosalia@cygnus.com> + + * scheme.texi (Weak References): incorporated David Lutterkort's + chapter on Weak References, which is based on Mikael's email + message exchange with with Michael Livshin. + +1998-10-29 Jim Blandy <jimb@zwingli.cygnus.com> + + * scheme.texi: Corrected shell commands in example. (Thanks to + Chris Bitmead.) + +1998-10-25 Mikael Djurfeldt <mdj@barbara.nada.kth.se> + + * gh.texi (C to Scheme, Scheme to C): Completed entries about + vector conversions. + +1998-08-26 Mark Galassi <rosalia@cygnus.com> + + * gh.texi (Starting and controlling the interpreter): modified the + gh_enter() docs in response to some good comments from Dirk + Herrmann: now they address the issue of loading ice-9/boot-9.scm, + and include Dirk's hackaround for the problem until we fix it + properly. + +1998-04-29 Mark Galassi <rosalia@cygnus.com> + + * scheme.texi (Dynamic Linking from Marius): added Marius's new + chapter on dynamic linking; there is still a section in dynamic + linking (written by Tim maybe?), and I have to examine how to + resolve that. + +1998-03-30 Mikael Djurfeldt <mdj@nada.kth.se> + + * scheme.texi (Port Operations): Changed entry for port-column and + port-line. (Thanks to Per Bothner.) + +1998-02-02 Mikael Djurfeldt <mdj@mdj.nada.kth.se> + + * scheme.texi (Exceptions): Adjusted documentation to reflect the + removal of the (catch #f ...) mechanism. + +1998-01-28 Mark Galassi <rosalia@nis.lanl.gov> + + * guile-ref.texi: changed @dircategory to "Scheme Programming". + It seems to be the consensus. + +1998-01-20 Mikael Djurfeldt <mdj@mdj.nada.kth.se> + + * gh.texi (C to Scheme): Added documentation for gh_doubles2scm + and gh_doubles2dvect. + (Scheme to C): Added documentation for gh_scm2doubles. + +1998-01-15 Mark Galassi <rosalia@nis.lanl.gov> + + * gh.texi (Calling Scheme procedures from C): removed + gh_make_subr() since Mikael pointed out that it is gone from + Guile. I don't remember its history any more, but I don't think + anyone is missing it. + +1998-01-03 Tim Pierce <twp@skepsis.com> + + * scheme.texi (Evaluation): Several corrections supplied by MDJ. + +Sat Dec 27 19:02:36 1997 Tim Pierce <twp@skepsis.com> + + * appendices.texi (Internals, Symbols): New nodes. + * scheme.texi (Configuration Data): New node. + +1997-12-27 Tim Pierce <twp@skepsis.com> + + * guile-ref.texi (Bitwise Operations): New description. + +1997-12-24 Tim Pierce <twp@skepsis.com> + + * scheme.texi (Port Operations, Evaluation): New nodes. + +1997-12-13 Tim Pierce <twp@skepsis.com> + + * scheme.texi, posix.texi: Documented each procedure as `procedure', + `primitive' or `syntax' as appropriate. + (Records): Change record-type-field-names to record-type-fields. + (Low level thread primitives): Change with-new-thread to + call-with-new-thread. + +Sun Dec 7 22:47:22 1997 Gary Houston <ghouston@actrix.gen.nz> + + * posix.texi (Processes): add "system" procedure. + +1997-11-23 Mark Galassi <rosalia@cygnus.com> + + * gh.texi (Starting and controlling the interpreter): added + documentation for gh_repl() -- gh_repl() has changed since I saw + the scm_shell() routine. + +1997-11-19 Tim Pierce <twp@twp.tezcat.com> + + * scheme.texi (String Fun): New node. + (Hash Tables): Added `get-handle' and `create-handle!' docs. + + * posix.texi (Networking Databases): Add docs for gethost, getnet, + getserv, getproto. Expanded on miscellaneous docs. + +1997-11-18 Tim Pierce <twp@twp.tezcat.com> + + * posix.texi: New file; moved docs for POSIX interface here. + * Makefile.am: Add posix.texi. + * Makefile.in: Regenerated. + * guile-ref.texi: Reorganize top-level menu. @include posix.texi. + * scheme.texi: Moved many nodes around, some restructuring + (e.g. new "Data Structures" node for records, structures, arrays, + hash tables, and so on). + +1997-10-19 Mark Galassi <rosalia@cygnus.com> + + * gh.texi (Calling Scheme procedures from C): added many routines + as I go through R4RS and try to complete the gh_ interface. + +Wed Oct 8 04:51:54 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (Dynamic Roots): added batch mode procedures. + +1997-10-03 Mikael Djurfeldt <mdj@nada.kth.se> + + * scheme.texi (Vtables): Changed 0 --> @code{vtable-index-layout}; + Changed @code{struct-vtable-offset} --> @code{vtable-offset-user}; + Added short note about the print call-back initializer. (This + section is in need of review. However, we shoudn't spend much + time on it since the structs will be replaced by something + equivalent, but with a different interface.} + +Sun Sep 28 00:02:35 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (Keywords): very small re-organization to take + advantage of the fact that read-options is now documented in + another chapter. + +Thu Sep 25 23:37:02 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (Guile options interface): renamed the symbol case + section to "Guile options interface". "Reader options" is now a + subsection of that. I've finally figured a lot of how options + work, thanks to discovering Mikael's comments in options.c and an + old note from Mikael to Jim describing it. + (Guile options interface): reorganized the individual option + groups. This section (on options) of the manual is now reasonably + complete, unless I am completely missing something. + +Wed Sep 24 15:25:03 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (The Guile module system): Added a bit more to this + chapter, mostly the more user-friendly (use-modules (ice-9 + module-name)) approach. + (Symbol case): tried to write something about this, but it will + need to be reviewed by someone who understands the big picture of + read options. I also think the section name should be changed to + something like "Read options". + +Sun Sep 21 18:45:57 1997 Mark Galassi <rosalia@nis.lanl.gov> + + * scheme.texi (SLIB): some little details, including splitting off + what does in the installation chapter. Also added a section on + Jacal, which has some open issues. + + * appendices.texi (Packages not shipped with Guile): added this + section to describe getting resources on SCSH, SLIB and Jacal (and + who knows what else in the future). + +Sat Aug 30 19:31:22 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (Uniform Array): mention start and end arguments + for uniform-array-read! and uniform-array-write. + +Sat Aug 23 19:05:08 1997 Gary Houston <ghouston@actrix.gen.nz> + + * guile-ref.texi (Top): corresponding changes. + * scheme.texi (Exception Handling): add scm-error, strerror. + (Exceptions): renamed from Exception Handling. + (Exceptions): deleted empty section. + +Mon Aug 18 16:11:43 1997 Jim Blandy <jimb@totoro.red-bean.com> + + * texinfo.tex: Installed from texinfo release 3.11. + +Fri Aug 15 08:14:32 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (file system): added truncate-file. + chown, fcntl, fseek, ftell updated. + (ports vs file descriptors): added fsync, open, open-fdes. + (time): added times. + +Sun Aug 10 07:39:55 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (processes): added execle. + +Tue Jul 29 02:01:21 1997 Gary Houston <ghouston@actrix.gen.nz> + + * setvbuf added. primitive-dup[2] removed. + +Sat Jul 26 04:25:40 1997 Gary Houston <ghouston@actrix.gen.nz> + + * various close and dup procedures added, plus setenv. + +Sat Jul 19 04:04:50 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (signals): new section. + (processes): primitive-exit. + (ports vs. file descriptors): force-output, flush-all-ports. + fcntl from NEWS. + +Fri Jul 18 07:58:52 1997 Gary Houston <ghouston@actrix.gen.nz> + + * scheme.texi (SLIB): update initialization details. + (expect): likewise. + (The Scheme shell (scsh)): likewise. + +Fri Jun 27 00:31:25 1997 Tim Pierce <twp@twp.tezcat.com> + + * scheme.texi (Regexp Functions): Add docs for make-regexp flags + regexp/icase, regexp/newline, regexp/basic, regexp/extended. + +Mon Jun 23 12:35:57 1997 Tim Pierce <twpierce@bio-5.bsd.uchicago.edu> + + * appendices.texi (debugger user interface): new text. + (Single-Step, Trace, Backtrace): new nodes. + + * scheme.texi: Many revised nodes, some new ones. + + (Binary Numeric Operations, Input/Output Ports, File Ports, Soft + Ports, String Ports): Imported documentation from SCM and SLIB manuals. + + (Association Lists and Hash Tables, Dictionary Types, Association + Lists, Hash Tables): New nodes. + (Dictionaries in general): Removed. + + (Regular Expressions): Replaced. + (Rx Interface): New node, renamed from old `Regular Expressions'. + (Regexp Functions, Match Functions, Backslash Escapes): new nodes. + + (Property Lists): new node with documentation for both object and + procedure properties. + (Object Properties): removed. + * guile-ref.texi: change `Object Properties' to `Property Lists'. + diff --git a/doc/ref/api.txt b/doc/ref/api.txt new file mode 100644 index 000000000..367cbbf95 --- /dev/null +++ b/doc/ref/api.txt @@ -0,0 +1,185 @@ +Scheme objects +============== + +There are two basic C data types to represent objects in guile: + +- SCM: SCM is the user level abstract C type that is used to represent all of +guile's scheme objects, no matter what the scheme object type is. No C +operation except assignment is guaranteed to work with variables of type SCM. +Only use macros and functions to work with SCM values. Values are converted +between C data types and the SCM type with utility functions and macros. + +- scm_bits_t: An integral data type that is guaranteed to be large enough to +hold all information that is required to represent any scheme object. While +this data type is used to implement guile internals, the use of this type is +also necessary to write certain kinds of extensions to guile. + + +Relationship between SCM and scm_bits_t +======================================= + +A variable of type SCM is guaranteed to hold a valid scheme object. A +variable of type scm_bits_t, however, may either hold a representation of a +SCM value as a C integral type, but may also hold any C value, even if it does +not correspond to a valid scheme object. + +For a variable x of type SCM, the scheme object's type information is stored +in a form that is not directly usable. To be able to work on the type +encoding of the scheme value, the SCM variable has to be transformed into the +corresponding representation as a scm_bits_t variable y by using the +SCM_UNPACK macro. After this has been done, the type of the scheme object x +can be derived from the content of the bits of the scm_bits_t value y, as is +described in -->data-rep. A valid bit encoding of a scheme value as a +scm_bits_t variable can be transformed into the corresponding SCM value by +using the SCM_PACK macro. + +- scm_bits_t SCM_UNPACK (SCM x): Transforms the SCM value x into it's +representation as an integral type. Only after applying SCM_UNPACK it is +possible to access the bits and contents of the SCM value. + +- SCM SCM_PACK (scm_bits_t x): Takes a valid integral representation of a +scheme object and transforms it into its representation as a SCM value. + + +Immediate objects +================= + +A scheme object may either be an immediate, i. e. carrying all necessary +information by itself, or it may contain a reference to a 'cell' with +additional information on the heap. While the fact, whether an object is an +immediate or not should be irrelevant for user code, within guile's own code +the distinction is sometimes of importance. Thus, the following low level +macro is provided: + +- int SCM_IMP (SCM x): A scheme object is an immediate if it fullfills the +SCM_IMP predicate, otherwise it holds an encoded reference to a heap cell. +The result of the predicate is delivered as a C style boolean value. User +code and code that extends guile should normally not be required to use this +macro. + +Summary: +* For a scheme object x of unknown type, check first with SCM_IMP (x) if it is +an immediate object. If so, all of the type and value information can be +determined from the scm_bits_t value that is delivered by SCM_UNPACK (x). + + +Non immediate objects +===================== + +- (scm_cell *) SCM2PTR (SCM x) (FIXME:: this name should be changed) +- SCM PTR2SCM (scm_cell * x) (FIXME:: this name should be changed) + +A scheme object of type SCM that does not fullfill the SCM_IMP predicate holds +an encoded reference to a heap cell. This reference can be decoded to a C +pointer to a heap cell using the SCM2PTR macro. The encoding of a pointer to +a heap cell into a SCM value is done using the PTR2SCM macro. + +Note that it is also possible to transform a non immediate SCM value by using +SCM_UNPACK into a scm_bits_t variable. Hower, the result of SCM_UNPACK may +not be used as a pointer to a scm_cell: Only SCM2PTR is guaranteed to +transform a SCM object into a valid pointer to a heap cell. Also, it is not +allowed to apply PTR2SCM to anything that is not a valid pointer to a heap +cell. + +Summary: +* Only use SCM2PTR for SCM values for which SCM_IMP is false! +* Don't use '(scm_cell*) SCM_UNPACK (x)'! Use 'SCM2PTR (x)' instead! +* Don't use PTR2SCM for anything but a cell pointer! + + +Heap Cell Type Information +========================== + +Heap cells contain a number of entries, each of which is either a scheme +object of type SCM or a raw C value of type scm_bits_t. Which of the cell +entries contain scheme objects and which contain raw C values is determined by +the first entry of the cell, which holds the cell type information. + +- scm_bits_t SCM_CELL_TYPE (SCM x): For a non immediate scheme object x, +deliver the content of the first entry of the heap cell referenced by x. This +value holds the information about the cell type as described in -->data-rep. + +- void SCM_SET_CELL_TYPE (SCM x, scm_bits_t t): For a non immediate scheme +object x, write the value t into the first entry of the heap cell referenced +by x. The value t must hold a valid cell type as described in -->data-rep. + + +Accessing Cell Entries +====================== + +For a non immediate scheme object x, the object type can be determined by +reading the cell type entry using the SCM_CELL_TYPE macro. For the different +types of cells it is known which cell entry holds scheme objects and which cell +entry holds raw C data. To access the different cell entries appropriately, +the following macros are provided: + +- scm_bits_t SCM_CELL_WORD (SCM x, unsigned int n): Deliver the cell entry n +of the heap cell referenced by the non immediate scheme object x as raw data. +It is illegal, to access cell entries that hold scheme objects by using these +macros. For convenience, the following macros are also provided: + SCM_CELL_WORD_0 (x) --> SCM_CELL_WORD (x, 0) + SCM_CELL_WORD_1 (x) --> SCM_CELL_WORD (x, 1) + ... + SCM_CELL_WORD_n (x) --> SCM_CELL_WORD (x, n) + +- SCM SCM_CELL_OBJECT (SCM x, unsigned int n): Deliver the cell entry n of +the heap cell referenced by the non immediate scheme object x as a scheme +object. It is illegal, to access cell entries that do not hold scheme objects +by using these macros. For convenience, the following macros are also +provided: + SCM_CELL_OBJECT_0 (x) --> SCM_CELL_OBJECT (x, 0) + SCM_CELL_OBJECT_1 (x) --> SCM_CELL_OBJECT (x, 1) + ... + SCM_CELL_OBJECT_n (x) --> SCM_CELL_OBJECT (x, n) + +- void SCM_SET_CELL_WORD (SCM x, unsigned int n, scm_bits_t w): Write the raw +C value w into entry number n of the heap cell referenced by the non immediate +scheme value x. Values that are written into cells this way may only be read +from the cells using the SCM_CELL_WORD macros or, in case cell entry 0 is +written, using the SCM_CELL_TYPE macro. For the special case of cell entry 0 +it has to be made sure that w contains a cell type information (see +-->data-rep) which does not describe a scheme object. For convenience, the +following macros are also provided: + SCM_SET_CELL_WORD_0 (x, w) --> SCM_SET_CELL_WORD (x, 0, w) + SCM_SET_CELL_WORD_1 (x, w) --> SCM_SET_CELL_WORD (x, 1, w) + ... + SCM_SET_CELL_WORD_n (x, w) --> SCM_SET_CELL_WORD (x, n, w) + +- void SCM_SET_CELL_OBJECT (SCM x, unsigned int n, SCM o): Write the scheme +object o into entry number n of the heap cell referenced by the non immediate +scheme value x. Values that are written into cells this way may only be read +from the cells using the SCM_CELL_OBJECT macros or, in case cell entry 0 is +written, using the SCM_CELL_TYPE macro. For the special case of cell entry 0 +the writing of a scheme object into this cell is only allowed, if the cell +forms a scheme pair. For convenience, the following macros are also provided: + SCM_SET_CELL_OBJECT_0 (x, o) --> SCM_SET_CELL_OBJECT (x, 0, o) + SCM_SET_CELL_OBJECT_1 (x, o) --> SCM_SET_CELL_OBJECT (x, 1, o) + ... + SCM_SET_CELL_OBJECT_n (x, o) --> SCM_SET_CELL_OBJECT (x, n, o) + +Summary: +* For a non immediate scheme object x of unknown type, get the type + information by using SCM_CELL_TYPE (x). +* As soon as the cell type information is available, only use the appropriate + access methods to read and write data to the different cell entries. + + +Basic Rules for Accessing Cell Entries +====================================== + +For each cell type it is generally up to the implementation of that type which +of the corresponding cell entries hold scheme objects and which hold raw C +values. However, there is one basic rules that has to be followed: Scheme +pairs consist of exactly two cell entries, which both contain scheme objects. +Further, a cell which contains a scheme object in it first entry has to be a +scheme pair. In other words, it is not allowed to store a scheme object in +the first cell entry and a non scheme object in the second cell entry. + +Fixme:shouldn't this rather be SCM_PAIRP / SCM_PAIR_P ? +- int SCM_CONSP (SCM x): Determine, whether the scheme object x is a scheme +pair, i. e. whether x references a heap cell consisting of exactly two +entries, where both entries contain a scheme object. In this case, both +entries will have to be accessed using the SCM_CELL_OBJECT macros. On the +contrary, if the SCM_CONSP predicate is not fulfilled, the first entry of the +scheme cell is guaranteed not to be a scheme value and thus the first cell +entry must be accessed using the SCM_CELL_WORD_0 macro. diff --git a/doc/ref/appendices.texi b/doc/ref/appendices.texi new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/doc/ref/appendices.texi diff --git a/doc/ref/data-rep.texi b/doc/ref/data-rep.texi new file mode 100644 index 000000000..137d11833 --- /dev/null +++ b/doc/ref/data-rep.texi @@ -0,0 +1,2075 @@ +@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 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.1 2001-08-24 09:40:29 ossau Exp $ +@c essay @subtitle For use with Guile @value{VERSION} +@c essay @author Jim Blandy +@c essay @author Free Software Foundation +@c essay @author @email{jimb@@red-bean.com} +@c essay @c The following two commands start the copyright page. +@c essay @page +@c essay @vskip 0pt plus 1filll +@c essay @vskip 0pt plus 1filll +@c essay Copyright @copyright{} 1998 Free Software Foundation + +@c essay Permission is granted to make and distribute verbatim copies of +@c essay this manual provided the copyright notice and this permission notice +@c essay are preserved on all copies. + +@c essay Permission is granted to copy and distribute modified versions of this +@c essay manual under the conditions for verbatim copying, provided that the entire +@c essay resulting derived work is distributed under the terms of a permission +@c essay notice identical to this one. + +@c essay Permission is granted to copy and distribute translations of this manual +@c essay into another language, under the above conditions for modified versions, +@c essay except that this permission notice may be stated in a translation approved +@c essay by Free Software Foundation. +@c essay @end titlepage + +@c essay @c @smallbook +@c essay @c @finalout +@c essay @headings double + + +@c essay @node Top, Data Representation in Scheme, (dir), (dir) +@c essay @top Data Representation in Guile + +@c essay @ifinfo +@c essay This essay is meant to provide the background necessary to read and +@c essay write C code that manipulates Scheme values in a way that conforms to +@c essay libguile's interface. If you would like to write or maintain a +@c essay Guile-based application in C or C++, this is the first information you +@c essay need. + +@c essay In order to make sense of Guile's @code{SCM_} functions, or read +@c essay libguile's source code, it's essential to have a good grasp of how Guile +@c essay actually represents Scheme values. Otherwise, a lot of the code, and +@c essay the conventions it follows, won't make very much sense. + +@c essay We assume you know both C and Scheme, but we do not assume you are +@c essay familiar with Guile's C interface. +@c essay @end ifinfo + + +@page +@node Data Representation +@chapter 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. +* Defining New Types (Smobs):: How to extend Guile with your own + application-specific datatypes. +@end menu + +@node Data Representation in Scheme +@section Data Representation in Scheme + +Scheme is a latently-typed language; this means that the system cannot, +in general, determine the type of a given expression at compile time. +Types only become apparent at run time. Variables do not have fixed +types; a variable may hold a pair at one point, an integer at the next, +and a thousand-element vector later. Instead, values, not variables, +have fixed types. + +In order to implement standard Scheme functions like @code{pair?} and +@code{string?} and provide garbage collection, the representation of +every value must contain enough information to accurately determine its +type at run time. Often, Scheme systems also use this information to +determine whether a program has attempted to apply an operation to an +inappropriately typed value (such as taking the @code{car} of a string). + +Because variables, pairs, and vectors may hold values of any type, +Scheme implementations use a uniform representation for values --- a +single type large enough to hold either a complete value or a pointer +to a complete value, along with the necessary typing information. + +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}. + + +@menu +* A Simple Representation:: +* Faster Integers:: +* Cheaper Pairs:: +* Guile Is Hairier:: +@end menu + +@node A Simple Representation +@subsection A Simple Representation + +The simplest way to meet the above requirements in C would be to +represent each value as a pointer to a structure containing a type +indicator, followed by a union carrying the real value. Assuming that +@code{SCM} is the name of our universal type, we can write: + +@example +enum type @{ integer, pair, string, vector, ... @}; + +typedef struct value *SCM; + +struct value @{ + enum type type; + union @{ + int integer; + struct @{ SCM car, cdr; @} pair; + struct @{ int length; char *elts; @} string; + struct @{ int length; SCM *elts; @} vector; + ... + @} value; +@}; +@end example +with the ellipses replaced with code for the remaining Scheme types. + +This representation is sufficient to implement all of Scheme's +semantics. If @var{x} is an @code{SCM} value: +@itemize @bullet +@item + To test if @var{x} is an integer, we can write @code{@var{x}->type == integer}. +@item + To find its value, we can write @code{@var{x}->value.integer}. +@item + To test if @var{x} is a vector, we can write @code{@var{x}->type == vector}. +@item + If we know @var{x} is a vector, we can write + @code{@var{x}->value.vector.elts[0]} to refer to its first element. +@item + If we know @var{x} is a pair, we can write + @code{@var{x}->value.pair.car} to extract its car. +@end itemize + + +@node Faster Integers +@subsection Faster Integers + +Unfortunately, the above representation has a serious disadvantage. In +order to return an integer, an expression must allocate a @code{struct +value}, initialize it to represent that integer, and return a pointer to +it. Furthermore, fetching an integer's value requires a memory +reference, which is much slower than a register reference on most +processors. Since integers are extremely common, this representation is +too costly, in both time and space. Integers should be very cheap to +create and manipulate. + +One possible solution comes from the observation that, on many +architectures, structures must be aligned on a four-byte boundary. +(Whether or not the machine actually requires it, we can write our own +allocator for @code{struct value} objects that assures this is true.) +In this case, the lower two bits of the structure's address are known to +be zero. + +This gives us the room we need to provide an improved representation +for integers. We make the following rules: +@itemize @bullet +@item +If the lower two bits of an @code{SCM} value are zero, then the SCM +value is a pointer to a @code{struct value}, and everything proceeds as +before. +@item +Otherwise, the @code{SCM} value represents an integer, whose value +appears in its upper bits. +@end itemize + +Here is C code implementing this convention: +@example +enum type @{ pair, string, vector, ... @}; + +typedef struct value *SCM; + +struct value @{ + enum type type; + union @{ + struct @{ SCM car, cdr; @} pair; + struct @{ int length; char *elts; @} string; + struct @{ int length; SCM *elts; @} vector; + ... + @} value; +@}; + +#define POINTER_P(x) (((int) (x) & 3) == 0) +#define INTEGER_P(x) (! POINTER_P (x)) + +#define GET_INTEGER(x) ((int) (x) >> 2) +#define MAKE_INTEGER(x) ((SCM) (((x) << 2) | 1)) +@end example + +Notice that @code{integer} no longer appears as an element of @code{enum +type}, and the union has lost its @code{integer} member. Instead, we +use the @code{POINTER_P} and @code{INTEGER_P} macros to make a coarse +classification of values into integers and non-integers, and do further +type testing as before. + +Here's how we would answer the questions posed above (again, assume +@var{x} is an @code{SCM} value): +@itemize @bullet +@item + To test if @var{x} is an integer, we can write @code{INTEGER_P (@var{x})}. +@item + To find its value, we can write @code{GET_INTEGER (@var{x})}. +@item + To test if @var{x} is a vector, we can write: +@example + @code{POINTER_P (@var{x}) && @var{x}->type == vector} +@end example + Given the new representation, we must make sure @var{x} is truly a + pointer before we dereference it to determine its complete type. +@item + If we know @var{x} is a vector, we can write + @code{@var{x}->value.vector.elts[0]} to refer to its first element, as + before. +@item + If we know @var{x} is a pair, we can write + @code{@var{x}->value.pair.car} to extract its car, just as before. +@end itemize + +This representation allows us to operate more efficiently on integers +than the first. For example, if @var{x} and @var{y} are known to be +integers, we can compute their sum as follows: +@example +MAKE_INTEGER (GET_INTEGER (@var{x}) + GET_INTEGER (@var{y})) +@end example +Now, integer math requires no allocation or memory references. Most +real Scheme systems actually use an even more efficient representation, +but this essay isn't about bit-twiddling. (Hint: what if pointers had +@code{01} in their least significant bits, and integers had @code{00}?) + + +@node Cheaper Pairs +@subsection Cheaper Pairs + +However, there is yet another issue to confront. Most Scheme heaps +contain more pairs than any other type of object; Jonathan Rees says +that pairs occupy 45% of the heap in his Scheme implementation, Scheme +48. However, our representation above spends three @code{SCM}-sized +words per pair --- one for the type, and two for the @sc{car} and +@sc{cdr}. Is there any way to represent pairs using only two words? + +Let us refine the convention we established earlier. Let us assert +that: +@itemize @bullet +@item + If the bottom two bits of an @code{SCM} value are @code{#b00}, then + it is a pointer, as before. +@item + If the bottom two bits are @code{#b01}, then the upper bits are an + integer. This is a bit more restrictive than before. +@item + If the bottom two bits are @code{#b10}, then the value, with the bottom + two bits masked out, is the address of a pair. +@end itemize + +Here is the new C code: +@example +enum type @{ string, vector, ... @}; + +typedef struct value *SCM; + +struct value @{ + enum type type; + union @{ + struct @{ int length; char *elts; @} string; + struct @{ int length; SCM *elts; @} vector; + ... + @} value; +@}; + +struct pair @{ + SCM car, cdr; +@}; + +#define POINTER_P(x) (((int) (x) & 3) == 0) + +#define INTEGER_P(x) (((int) (x) & 3) == 1) +#define GET_INTEGER(x) ((int) (x) >> 2) +#define MAKE_INTEGER(x) ((SCM) (((x) << 2) | 1)) + +#define PAIR_P(x) (((int) (x) & 3) == 2) +#define GET_PAIR(x) ((struct pair *) ((int) (x) & ~3)) +@end example + +Notice that @code{enum type} and @code{struct value} now only contain +provisions for vectors and strings; both integers and pairs have become +special cases. The code above also assumes that an @code{int} is large +enough to hold a pointer, which isn't generally true. + + +Our list of examples is now as follows: +@itemize @bullet +@item + To test if @var{x} is an integer, we can write @code{INTEGER_P + (@var{x})}; this is as before. +@item + To find its value, we can write @code{GET_INTEGER (@var{x})}, as + before. +@item + To test if @var{x} is a vector, we can write: +@example + @code{POINTER_P (@var{x}) && @var{x}->type == vector} +@end example + We must still make sure that @var{x} is a pointer to a @code{struct + value} before dereferencing it to find its type. +@item + If we know @var{x} is a vector, we can write + @code{@var{x}->value.vector.elts[0]} to refer to its first element, as + before. +@item + We can write @code{PAIR_P (@var{x})} to determine if @var{x} is a + pair, and then write @code{GET_PAIR (@var{x})->car} to refer to its + car. +@end itemize + +This change in representation reduces our heap size by 15%. It also +makes it cheaper to decide if a value is a pair, because no memory +references are necessary; it suffices to check the bottom two bits of +the @code{SCM} value. This may be significant when traversing lists, a +common activity in a Scheme system. + +Again, most real Scheme systems use a slighty different implementation; +for example, if GET_PAIR subtracts off the low bits of @code{x}, instead +of masking them off, the optimizer will often be able to combine that +subtraction with the addition of the offset of the structure member we +are referencing, making a modified pointer as fast to use as an +unmodified pointer. + + +@node Guile Is Hairier +@subsection Guile Is Hairier + +We originally started with a very simple typing system --- each object +has a field that indicates its type. Then, for the sake of efficiency +in both time and space, we moved some of the typing information directly +into the @code{SCM} value, and left the rest in the @code{struct value}. +Guile itself employs a more complex hierarchy, storing finer and finer +gradations of type information in different places, depending on the +object's coarser type. + +In the author's opinion, Guile could be simplified greatly without +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 + +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. + + +@menu +* General Rules:: +* Conservative GC:: +* Immediates vs Non-immediates:: +* Immediate Datatypes:: +* Non-immediate Datatypes:: +* Signalling Type Errors:: +* Unpacking the SCM type:: +@end menu + +@node General Rules +@subsection General Rules + +Any code which operates on Guile datatypes must @code{#include} the +header file @code{<libguile.h>}. This file contains a definition for +the @code{SCM} typedef (Guile's universal type, as in the examples +above), and definitions and declarations for a host of macros and +functions that operate on @code{SCM} values. + +All identifiers declared by @code{<libguile.h>} begin with @code{scm_} +or @code{SCM_}. + +@c [[I wish this were true, but I don't think it is at the moment. -JimB]] +@c Macros do not evaluate their arguments more than once, unless documented +@c to do so. + +The functions described here generally check the types of their +@code{SCM} arguments, and signal an error if their arguments are of an +inappropriate type. Macros generally do not, unless that is their +specified purpose. You must verify their argument types beforehand, as +necessary. + +Macros and functions that return a boolean value have names ending in +@code{P} or @code{_p} (for ``predicate''). Those that return a negated +boolean value have names starting with @code{SCM_N}. For example, +@code{SCM_IMP (@var{x})} is a predicate which returns non-zero iff +@var{x} is an immediate value (an @code{IM}). @code{SCM_NCONSP +(@var{x})} is a predicate which returns non-zero iff @var{x} is +@emph{not} a pair object (a @code{CONS}). + + +@node Conservative GC +@subsection Conservative Garbage Collection + +Aside from the latent typing, the major source of constraints on a +Scheme implementation's data representation is the garbage collector. +The collector must be able to traverse every live object in the heap, to +determine which objects are not live. + +There are many ways to implement this, but Guile uses an algorithm +called @dfn{mark and sweep}. The collector scans the system's global +variables and the local variables on the stack to determine which +objects are immediately accessible by the C code. It then scans those +objects to find the objects they point to, @i{et cetera}. The collector +sets a @dfn{mark bit} on each object it finds, so each object is +traversed only once. This process is called @dfn{tracing}. + +When the collector can find no unmarked objects pointed to by marked +objects, it assumes that any objects that are still unmarked will never +be used by the program (since there is no path of dereferences from any +global or local variable that reaches them) and deallocates them. + +In the above paragraphs, we did not specify how the garbage collector +finds the global and local variables; as usual, there are many different +approaches. Frequently, the programmer must maintain a list of pointers +to all global variables that refer to the heap, and another list +(adjusted upon entry to and exit from each function) of local variables, +for the collector's benefit. + +The list of global variables is usually not too difficult to maintain, +since global variables are relatively rare. However, an explicitly +maintained list of local variables (in the author's personal experience) +is a nightmare to maintain. Thus, Guile uses a technique called +@dfn{conservative garbage collection}, to make the local variable list +unnecessary. + +The trick to conservative collection is to treat the stack as an +ordinary range of memory, and assume that @emph{every} word on the stack +is a pointer into the heap. Thus, the collector marks all objects whose +addresses appear anywhere in the stack, without knowing for sure how +that word is meant to be interpreted. + +Obviously, such a system will occasionally retain objects that are +actually garbage, and should be freed. In practice, this is not a +problem. The alternative, an explicitly maintained list of local +variable addresses, is effectively much less reliable, due to programmer +error. + +To accommodate this technique, data must be represented so that the +collector can accurately determine whether a given stack word is a +pointer or not. Guile does this as follows: + +@itemize @bullet +@item +Every heap object has a two-word header, called a @dfn{cell}. Some +objects, like pairs, fit entirely in a cell's two words; others may +store pointers to additional memory in either of the words. For +example, strings and vectors store their length in the first word, and a +pointer to their elements in the second. + +@item +Guile allocates whole arrays of cells at a time, called @dfn{heap +segments}. These segments are always allocated so that the cells they +contain fall on eight-byte boundaries, or whatever is appropriate for +the machine's word size. Guile keeps all cells in a heap segment +initialized, whether or not they are currently in use. + +@item +Guile maintains a sorted table of heap segments. +@end itemize + +Thus, given any random word @var{w} fetched from the stack, Guile's +garbage collector can consult the table to see if @var{w} falls within a +known heap segment, and check @var{w}'s alignment. If both tests pass, +the collector knows that @var{w} is a valid pointer to a cell, +intentional or not, and proceeds to trace the cell. + +Note that heap segments do not contain all the data Guile uses; cells +for objects like vectors and strings contain pointers to other memory +areas. However, since those pointers are internal, and not shared among +many pieces of code, it is enough for the collector to find the cell, +and then use the cell's type to find more pointers to trace. + + +@node Immediates vs Non-immediates +@subsection Immediates vs Non-immediates + +Guile classifies Scheme objects into two kinds: those that fit entirely +within an @code{SCM}, and those that require heap storage. + +The former class are called @dfn{immediates}. The class of immediates +includes small integers, characters, boolean values, the empty list, the +mysterious end-of-file object, and some others. + +The remaining types are called, not suprisingly, @dfn{non-immediates}. +They include pairs, procedures, strings, vectors, and all other data +types in Guile. + +@deftypefn Macro int SCM_IMP (SCM @var{x}) +Return non-zero iff @var{x} is an immediate object. +@end deftypefn + +@deftypefn Macro int SCM_NIMP (SCM @var{x}) +Return non-zero iff @var{x} is a non-immediate object. This is the +exact complement of @code{SCM_IMP}, above. +@end deftypefn + +Note that for versions of Guile prior to 1.4 it was necessary to use the +@code{SCM_NIMP} macro before calling a finer-grained predicate to +determine @var{x}'s type, such as @code{SCM_CONSP} or +@code{SCM_VECTORP}. This is no longer required: the definitions of all +Guile type predicates now include a call to @code{SCM_NIMP} where +necessary. + + +@node Immediate Datatypes +@subsection Immediate Datatypes + +The following datatypes are immediate values; that is, they fit entirely +within an @code{SCM} value. The @code{SCM_IMP} and @code{SCM_NIMP} +macros will distinguish these from non-immediates; see @ref{Immediates +vs Non-immediates} for an explanation of the distinction. + +Note that the type predicates for immediate values work correctly on any +@code{SCM} value; you do not need to call @code{SCM_IMP} first, to +establish that a value is immediate. + +@menu +* Integer Data:: +* Character Data:: +* Boolean Data:: +* Unique Values:: +@end menu + +@node Integer Data +@subsubsection Integers + +Here are functions for operating on small integers, that fit within an +@code{SCM}. Such integers are called @dfn{immediate numbers}, or +@dfn{INUMs}. In general, INUMs occupy all but two bits of an +@code{SCM}. + +Bignums and floating-point numbers are non-immediate objects, and have +their own, separate accessors. The functions here will not work on +them. This is not as much of a problem as you might think, however, +because the system never constructs bignums that could fit in an INUM, +and never uses floating point values for exact integers. + +@deftypefn Macro int SCM_INUMP (SCM @var{x}) +Return non-zero iff @var{x} is a small integer value. +@end deftypefn + +@deftypefn Macro int SCM_NINUMP (SCM @var{x}) +The complement of SCM_INUMP. +@end deftypefn + +@deftypefn Macro int SCM_INUM (SCM @var{x}) +Return the value of @var{x} as an ordinary, C integer. If @var{x} +is not an INUM, the result is undefined. +@end deftypefn + +@deftypefn Macro SCM SCM_MAKINUM (int @var{i}) +Given a C integer @var{i}, return its representation as an @code{SCM}. +This function does not check for overflow. +@end deftypefn + + +@node Character Data +@subsubsection Characters + +Here are functions for operating on characters. + +@deftypefn Macro int SCM_CHARP (SCM @var{x}) +Return non-zero iff @var{x} is a character value. +@end deftypefn + +@deftypefn Macro {unsigned int} SCM_CHAR (SCM @var{x}) +Return the value of @code{x} as a C character. If @var{x} is not a +Scheme character, the result is undefined. +@end deftypefn + +@deftypefn Macro SCM SCM_MAKE_CHAR (int @var{c}) +Given a C character @var{c}, return its representation as a Scheme +character value. +@end deftypefn + + +@node Boolean Data +@subsubsection Booleans + +Here are functions and macros for operating on booleans. + +@deftypefn Macro SCM SCM_BOOL_T +@deftypefnx Macro SCM SCM_BOOL_F +The Scheme true and false values. +@end deftypefn + +@deftypefn Macro int SCM_NFALSEP (@var{x}) +Convert the Scheme boolean value to a C boolean. Since every object in +Scheme except @code{#f} is true, this amounts to comparing @var{x} to +@code{#f}; hence the name. +@c Noel feels a chill here. +@end deftypefn + +@deftypefn Macro SCM SCM_BOOL_NOT (@var{x}) +Return the boolean inverse of @var{x}. If @var{x} is not a +Scheme boolean, the result is undefined. +@end deftypefn + + +@node Unique Values +@subsubsection Unique Values + +The immediate values that are neither small integers, characters, nor +booleans are all unique values --- that is, datatypes with only one +instance. + +@deftypefn Macro SCM SCM_EOL +The Scheme empty list object, or ``End Of List'' object, usually written +in Scheme as @code{'()}. +@end deftypefn + +@deftypefn Macro SCM SCM_EOF_VAL +The Scheme end-of-file value. It has no standard written +representation, for obvious reasons. +@end deftypefn + +@deftypefn Macro SCM SCM_UNSPECIFIED +The value returned by expressions which the Scheme standard says return +an ``unspecified'' value. + +This is sort of a weirdly literal way to take things, but the standard +read-eval-print loop prints nothing when the expression returns this +value, so it's not a bad idea to return this when you can't think of +anything else helpful. +@end deftypefn + +@deftypefn Macro SCM SCM_UNDEFINED +The ``undefined'' value. Its most important property is that is not +equal to any valid Scheme value. This is put to various internal uses +by C code interacting with Guile. + +For example, when you write a C function that is callable from Scheme +and which takes optional arguments, the interpreter passes +@code{SCM_UNDEFINED} for any arguments you did not receive. + +We also use this to mark unbound variables. +@end deftypefn + +@deftypefn Macro int SCM_UNBNDP (SCM @var{x}) +Return true if @var{x} is @code{SCM_UNDEFINED}. Apply this to a +symbol's value to see if it has a binding as a global variable. +@end deftypefn + + +@node Non-immediate Datatypes +@subsection Non-immediate Datatypes + +A non-immediate datatype is one which lives in the heap, either because +it cannot fit entirely within a @code{SCM} word, or because it denotes a +specific storage location (in the nomenclature of the Revised^5 Report +on Scheme). + +The @code{SCM_IMP} and @code{SCM_NIMP} macros will distinguish these +from immediates; see @ref{Immediates vs Non-immediates}. + +Given a cell, Guile distinguishes between pairs and other non-immediate +types by storing special @dfn{tag} values in a non-pair cell's car, that +cannot appear in normal pairs. A cell with a non-tag value in its car +is an ordinary pair. The type of a cell with a tag in its car depends +on the tag; the non-immediate type predicates test this value. If a tag +value appears elsewhere (in a vector, for example), the heap may become +corrupted. + +Note how the type information for a non-immediate object is split +between the @code{SCM} word and the cell that the @code{SCM} word points +to. The @code{SCM} word itself only indicates that the object is +non-immediate --- in other words stored in a heap cell. The tag stored +in the first word of the heap cell indicates more precisely the type of +that object. + +The type predicates for non-immediate values work correctly on any +@code{SCM} value; you do not need to call @code{SCM_NIMP} first, to +establish that a value is non-immediate. + +@menu +* Pair Data:: +* Vector Data:: +* Procedures:: +* Closures:: +* Subrs:: +* Port Data:: +@end menu + + +@node Pair Data +@subsubsection Pairs + +Pairs are the essential building block of list structure in Scheme. A +pair object has two fields, called the @dfn{car} and the @dfn{cdr}. + +It is conventional for a pair's @sc{car} to contain an element of a +list, and the @sc{cdr} to point to the next pair in the list, or to +contain @code{SCM_EOL}, indicating the end of the list. Thus, a set of +pairs chained through their @sc{cdr}s constitutes a singly-linked list. +Scheme and libguile define many functions which operate on lists +constructed in this fashion, so although lists chained through the +@sc{car}s of pairs will work fine too, they may be less convenient to +manipulate, and receive less support from the community. + +Guile implements pairs by mapping the @sc{car} and @sc{cdr} of a pair +directly into the two words of the cell. + + +@deftypefn Macro int SCM_CONSP (SCM @var{x}) +Return non-zero iff @var{x} is a Scheme pair object. +@end deftypefn + +@deftypefn Macro int SCM_NCONSP (SCM @var{x}) +The complement of SCM_CONSP. +@end deftypefn + +@deftypefn Macro void SCM_NEWCELL (SCM @var{into}) +Allocate a new cell, and set @var{into} to point to it. This macro +expands to a statement, not an expression, and @var{into} must be an +lvalue of type SCM. + +This is the most primitive way to allocate a cell; it is quite fast. + +The @sc{car} of the cell initially tags it as a ``free cell''. If the +caller intends to use it as an ordinary cons, she must store ordinary +SCM values in its @sc{car} and @sc{cdr}. + +If the caller intends to use it as a header for some other type, she +must store an appropriate magic value in the cell's @sc{car}, to mark +it as a member of that type, and store whatever value in the @sc{cdr} +that type expects. You should generally not do this, unless you are +implementing a new datatype, and thoroughly understand the code in +@code{<libguile/tags.h>}. +@end deftypefn + +@deftypefun SCM scm_cons (SCM @var{car}, SCM @var{cdr}) +Allocate (``CONStruct'') a new pair, with @var{car} and @var{cdr} as its +contents. +@end deftypefun + +The macros below perform no typechecking. The results are undefined if +@var{cell} is an immediate. However, since all non-immediate Guile +objects are constructed from cells, and these macros simply return the +first element of a cell, they actually can be useful on datatypes other +than pairs. (Of course, it is not very modular to use them outside of +the code which implements that datatype.) + +@deftypefn Macro SCM SCM_CAR (SCM @var{cell}) +Return the @sc{car}, or first field, of @var{cell}. +@end deftypefn + +@deftypefn Macro SCM SCM_CDR (SCM @var{cell}) +Return the @sc{cdr}, or second field, of @var{cell}. +@end deftypefn + +@deftypefn Macro void SCM_SETCAR (SCM @var{cell}, SCM @var{x}) +Set the @sc{car} of @var{cell} to @var{x}. +@end deftypefn + +@deftypefn Macro void SCM_SETCDR (SCM @var{cell}, SCM @var{x}) +Set the @sc{cdr} of @var{cell} to @var{x}. +@end deftypefn + +@deftypefn Macro SCM SCM_CAAR (SCM @var{cell}) +@deftypefnx Macro SCM SCM_CADR (SCM @var{cell}) +@deftypefnx Macro SCM SCM_CDAR (SCM @var{cell}) @dots{} +@deftypefnx Macro SCM SCM_CDDDDR (SCM @var{cell}) +Return the @sc{car} of the @sc{car} of @var{cell}, the @sc{car} of the +@sc{cdr} of @var{cell}, @i{et cetera}. +@end deftypefn + + +@node Vector Data +@subsubsection Vectors, Strings, and Symbols + +Vectors, strings, and symbols have some properties in common. They all +have a length, and they all have an array of elements. In the case of a +vector, the elements are @code{SCM} values; in the case of a string or +symbol, the elements are characters. + +All these types store their length (along with some tagging bits) in the +@sc{car} of their header cell, and store a pointer to the elements in +their @sc{cdr}. Thus, the @code{SCM_CAR} and @code{SCM_CDR} macros +are (somewhat) meaningful when applied to these datatypes. + +@deftypefn Macro int SCM_VECTORP (SCM @var{x}) +Return non-zero iff @var{x} is a vector. +@end deftypefn + +@deftypefn Macro int SCM_STRINGP (SCM @var{x}) +Return non-zero iff @var{x} is a string. +@end deftypefn + +@deftypefn Macro int SCM_SYMBOLP (SCM @var{x}) +Return non-zero iff @var{x} is a symbol. +@end deftypefn + +@deftypefn Macro int SCM_VECTOR_LENGTH (SCM @var{x}) +@deftypefnx Macro int SCM_STRING_LENGTH (SCM @var{x}) +@deftypefnx Macro int SCM_SYMBOL_LENGTH (SCM @var{x}) +Return the length of the object @var{x}. The result is undefined if +@var{x} is not a vector, string, or symbol, respectively. +@end deftypefn + +@deftypefn Macro {SCM *} SCM_VECTOR_BASE (SCM @var{x}) +Return a pointer to the array of elements of the vector @var{x}. +The result is undefined if @var{x} is not a vector. +@end deftypefn + +@deftypefn Macro {char *} SCM_STRING_CHARS (SCM @var{x}) +@deftypefnx Macro {char *} SCM_SYMBOL_CHARS (SCM @var{x}) +Return a pointer to the characters of @var{x}. The result is undefined +if @var{x} is not a symbol or string, respectively. +@end deftypefn + +There are also a few magic values stuffed into memory before a symbol's +characters, but you don't want to know about those. What cruft! + + +@node Procedures +@subsubsection Procedures + +Guile provides two kinds of procedures: @dfn{closures}, which are the +result of evaluating a @code{lambda} expression, and @dfn{subrs}, which +are C functions packaged up as Scheme objects, to make them available to +Scheme programmers. + +(There are actually other sorts of procedures: compiled closures, and +continuations; see the source code for details about them.) + +@deftypefun SCM scm_procedure_p (SCM @var{x}) +Return @code{SCM_BOOL_T} iff @var{x} is a Scheme procedure object, of +any sort. Otherwise, return @code{SCM_BOOL_F}. +@end deftypefun + + +@node Closures +@subsubsection Closures + +[FIXME: this needs to be further subbed, but texinfo has no subsubsub] + +A closure is a procedure object, generated as the value of a +@code{lambda} expression in Scheme. The representation of a closure is +straightforward --- it contains a pointer to the code of the lambda +expression from which it was created, and a pointer to the environment +it closes over. + +In Guile, each closure also has a property list, allowing the system to +store information about the closure. I'm not sure what this is used for +at the moment --- the debugger, maybe? + +@deftypefn Macro int SCM_CLOSUREP (SCM @var{x}) +Return non-zero iff @var{x} is a closure. +@end deftypefn + +@deftypefn Macro SCM SCM_PROCPROPS (SCM @var{x}) +Return the property list of the closure @var{x}. The results are +undefined if @var{x} is not a closure. +@end deftypefn + +@deftypefn Macro void SCM_SETPROCPROPS (SCM @var{x}, SCM @var{p}) +Set the property list of the closure @var{x} to @var{p}. The results +are undefined if @var{x} is not a closure. +@end deftypefn + +@deftypefn Macro SCM SCM_CODE (SCM @var{x}) +Return the code of the closure @var{x}. The result is undefined if +@var{x} is not a closure. + +This function should probably only be used internally by the +interpreter, since the representation of the code is intimately +connected with the interpreter's implementation. +@end deftypefn + +@deftypefn Macro SCM SCM_ENV (SCM @var{x}) +Return the environment enclosed by @var{x}. +The result is undefined if @var{x} is not a closure. + +This function should probably only be used internally by the +interpreter, since the representation of the environment is intimately +connected with the interpreter's implementation. +@end deftypefn + + +@node Subrs +@subsubsection Subrs + +[FIXME: this needs to be further subbed, but texinfo has no subsubsub] + +A subr is a pointer to a C function, packaged up as a Scheme object to +make it callable by Scheme code. In addition to the function pointer, +the subr also contains a pointer to the name of the function, and +information about the number of arguments accepted by the C fuction, for +the sake of error checking. + +There is no single type predicate macro that recognizes subrs, as +distinct from other kinds of procedures. The closest thing is +@code{scm_procedure_p}; see @ref{Procedures}. + +@deftypefn Macro {char *} SCM_SNAME (@var{x}) +Return the name of the subr @var{x}. The result is undefined if +@var{x} is not a subr. +@end deftypefn + +@deftypefun SCM scm_make_gsubr (char *@var{name}, int @var{req}, int @var{opt}, int @var{rest}, SCM (*@var{function})()) +Create a new subr object named @var{name}, based on the C function +@var{function}, make it visible to Scheme the value of as a global +variable named @var{name}, and return the subr object. + +The subr object accepts @var{req} required arguments, @var{opt} optional +arguments, and a @var{rest} argument iff @var{rest} is non-zero. The C +function @var{function} should accept @code{@var{req} + @var{opt}} +arguments, or @code{@var{req} + @var{opt} + 1} arguments if @code{rest} +is non-zero. + +When a subr object is applied, it must be applied to at least @var{req} +arguments, or else Guile signals an error. @var{function} receives the +subr's first @var{req} arguments as its first @var{req} arguments. If +there are fewer than @var{opt} arguments remaining, then @var{function} +receives the value @code{SCM_UNDEFINED} for any missing optional +arguments. If @var{rst} is non-zero, then any arguments after the first +@code{@var{req} + @var{opt}} are packaged up as a list as passed as +@var{function}'s last argument. + +Note that subrs can actually only accept a predefined set of +combinations of required, optional, and rest arguments. For example, a +subr can take one required argument, or one required and one optional +argument, but a subr can't take one required and two optional arguments. +It's bizarre, but that's the way the interpreter was written. If the +arguments to @code{scm_make_gsubr} do not fit one of the predefined +patterns, then @code{scm_make_gsubr} will return a compiled closure +object instead of a subr object. +@end deftypefun + + +@node Port Data +@subsubsection Ports + +Haven't written this yet, 'cos I don't understand ports yet. + + +@node Signalling Type Errors +@subsection Signalling Type Errors + +Every function visible at the Scheme level should aggressively check the +types of its arguments, to avoid misinterpreting a value, and perhaps +causing a segmentation fault. Guile provides some macros to make this +easier. + +@deftypefn Macro void SCM_ASSERT (int @var{test}, SCM @var{obj}, unsigned int @var{position}, const char *@var{subr}) +If @var{test} is zero, signal a ``wrong type argument'' error, +attributed to the subroutine named @var{subr}, operating on the value +@var{obj}, which is the @var{position}'th argument of @var{subr}. +@end deftypefn + +@deftypefn Macro int SCM_ARG1 +@deftypefnx Macro int SCM_ARG2 +@deftypefnx Macro int SCM_ARG3 +@deftypefnx Macro int SCM_ARG4 +@deftypefnx Macro int SCM_ARG5 +@deftypefnx Macro int SCM_ARG6 +@deftypefnx Macro int SCM_ARG7 +One of the above values can be used for @var{position} to indicate the +number of the argument of @var{subr} which is being checked. +Alternatively, a positive integer number can be used, which allows to +check arguments after the seventh. However, for parameter numbers up to +seven it is preferable to use @code{SCM_ARGN} instead of the +corresponding raw number, since it will make the code easier to +understand. +@end deftypefn + +@deftypefn Macro int SCM_ARGn +Passing a value of zero or @code{SCM_ARGn} for @var{position} allows to +leave it unspecified which argument's type is incorrect. Again, +@code{SCM_ARGn} should be preferred over a raw zero constant. +@end deftypefn + + +@node Unpacking the SCM type +@subsection Unpacking the SCM Type + +The previous sections have explained how @code{SCM} values can refer to +immediate and non-immediate Scheme objects. For immediate objects, the +complete object value is stored in the @code{SCM} word itself, while for +non-immediates, the @code{SCM} word contains a pointer to a heap cell, +and further information about the object in question is stored in that +cell. This section describes how the @code{SCM} type is actually +represented and used at the C level. + +In fact, there are two basic C data types to represent objects in Guile: + +@itemize @bullet +@item +@code{SCM} is the user level abstract C type that is used to represent +all of Guile's Scheme objects, no matter what the Scheme object type is. +No C operation except assignment is guaranteed to work with variables of +type @code{SCM}, so you should only use macros and functions to work +with @code{SCM} values. Values are converted between C data types and +the @code{SCM} type with utility functions and macros. + +@item +@code{scm_bits_t} is an integral data type that is guaranteed to be +large enough to hold all information that is required to represent any +Scheme object. While this data type is mostly used to implement Guile's +internals, the use of this type is also necessary to write certain kinds +of extensions to Guile. +@end itemize + +@menu +* Relationship between SCM and scm_bits_t:: +* Immediate objects:: +* Non-immediate objects:: +* Heap Cell Type Information:: +* Accessing Cell Entries:: +* Basic Rules for Accessing Cell Entries:: +@end menu + + +@node Relationship between SCM and scm_bits_t +@subsubsection Relationship between @code{SCM} and @code{scm_bits_t} + +A variable of type @code{SCM} is guaranteed to hold a valid Scheme +object. A variable of type @code{scm_bits_t}, on the other hand, may +hold a representation of a @code{SCM} value as a C integral type, but +may also hold any C value, even if it does not correspond to a valid +Scheme object. + +For a variable @var{x} of type @code{SCM}, the Scheme object's type +information is stored in a form that is not directly usable. To be able +to work on the type encoding of the scheme value, the @code{SCM} +variable has to be transformed into the corresponding representation as +a @code{scm_bits_t} variable @var{y} by using the @code{SCM_UNPACK} +macro. Once this has been done, the type of the scheme object @var{x} +can be derived from the content of the bits of the @code{scm_bits_t} +value @var{y}, in the way illustrated by the example earlier in this +chapter (@pxref{Cheaper Pairs}). Conversely, a valid bit encoding of a +Scheme value as a @code{scm_bits_t} variable can be transformed into the +corresponding @code{SCM} value using the @code{SCM_PACK} macro. + +@deftypefn Macro scm_bits_t SCM_UNPACK (SCM @var{x}) +Transforms the @code{SCM} value @var{x} into its representation as an +integral type. Only after applying @code{SCM_UNPACK} it is possible to +access the bits and contents of the @code{SCM} value. +@end deftypefn + +@deftypefn Macro SCM SCM_PACK (scm_bits_t @var{x}) +Takes a valid integral representation of a Scheme object and transforms +it into its representation as a @code{SCM} value. +@end deftypefn + + +@node Immediate objects +@subsubsection Immediate objects + +A Scheme object may either be an immediate, i.e. carrying all necessary +information by itself, or it may contain a reference to a @dfn{cell} +with additional information on the heap. Although in general it should +be irrelevant for user code whether an object is an immediate or not, +within Guile's own code the distinction is sometimes of importance. +Thus, the following low level macro is provided: + +@deftypefn Macro int SCM_IMP (SCM @var{x}) +A Scheme object is an immediate if it fulfills the @code{SCM_IMP} +predicate, otherwise it holds an encoded reference to a heap cell. The +result of the predicate is delivered as a C style boolean value. User +code and code that extends Guile should normally not be required to use +this macro. +@end deftypefn + +@noindent +Summary: +@itemize @bullet +@item +Given a Scheme object @var{x} of unknown type, check first +with @code{SCM_IMP (@var{x})} if it is an immediate object. +@item +If so, all of the type and value information can be determined from the +@code{scm_bits_t} value that is delivered by @code{SCM_UNPACK +(@var{x})}. +@end itemize + + +@node Non-immediate objects +@subsubsection Non-immediate objects + +A Scheme object of type @code{SCM} that does not fullfill the +@code{SCM_IMP} predicate holds an encoded reference to a heap cell. +This reference can be decoded to a C pointer to a heap cell using the +@code{SCM2PTR} macro. The encoding of a pointer to a heap cell into a +@code{SCM} value is done using the @code{PTR2SCM} macro. + +@c (FIXME:: this name should be changed) +@deftypefn Macro (scm_cell *) SCM2PTR (SCM @var{x}) +Extract and return the heap cell pointer from a non-immediate @code{SCM} +object @var{x}. +@end deftypefn + +@c (FIXME:: this name should be changed) +@deftypefn Macro SCM PTR2SCM (scm_cell * @var{x}) +Return a @code{SCM} value that encodes a reference to the heap cell +pointer @var{x}. +@end deftypefn + +Note that it is also possible to transform a non-immediate @code{SCM} +value by using @code{SCM_UNPACK} into a @code{scm_bits_t} variable. +However, the result of @code{SCM_UNPACK} may not be used as a pointer to +a @code{scm_cell}: only @code{SCM2PTR} is guaranteed to transform a +@code{SCM} object into a valid pointer to a heap cell. Also, it is not +allowed to apply @code{PTR2SCM} to anything that is not a valid pointer +to a heap cell. + +@noindent +Summary: +@itemize @bullet +@item +Only use @code{SCM2PTR} on @code{SCM} values for which @code{SCM_IMP} is +false! +@item +Don't use @code{(scm_cell *) SCM_UNPACK (@var{x})}! Use @code{SCM2PTR +(@var{x})} instead! +@item +Don't use @code{PTR2SCM} for anything but a cell pointer! +@end itemize + + +@node Heap Cell Type Information +@subsubsection Heap Cell Type Information + +Heap cells contain a number of entries, each of which is either a scheme +object of type @code{SCM} or a raw C value of type @code{scm_bits_t}. +Which of the cell entries contain Scheme objects and which contain raw C +values is determined by the first entry of the cell, which holds the +cell type information. + +@deftypefn Macro scm_bits_t SCM_CELL_TYPE (SCM @var{x}) +For a non-immediate Scheme object @var{x}, deliver the content of the +first entry of the heap cell referenced by @var{x}. This value holds +the information about the cell type. +@end deftypefn + +@deftypefn Macro void SCM_SET_CELL_TYPE (SCM @var{x}, scm_bits_t @var{t}) +For a non-immediate Scheme object @var{x}, write the value @var{t} into +the first entry of the heap cell referenced by @var{x}. The value +@var{t} must hold a valid cell type. +@end deftypefn + + +@node Accessing Cell Entries +@subsubsection Accessing Cell Entries + +For a non-immediate Scheme object @var{x}, the object type can be +determined by reading the cell type entry using the @code{SCM_CELL_TYPE} +macro. For each different type of cell it is known which cell entries +hold Scheme objects and which cell entries hold raw C data. To access +the different cell entries appropriately, the following macros are +provided. + +@deftypefn Macro scm_bits_t SCM_CELL_WORD (SCM @var{x}, unsigned int @var{n}) +Deliver the cell entry @var{n} of the heap cell referenced by the +non-immediate Scheme object @var{x} as raw data. It is illegal, to +access cell entries that hold Scheme objects by using these macros. For +convenience, the following macros are also provided. +@itemize @bullet +@item +SCM_CELL_WORD_0 (@var{x}) @result{} SCM_CELL_WORD (@var{x}, 0) +@item +SCM_CELL_WORD_1 (@var{x}) @result{} SCM_CELL_WORD (@var{x}, 1) +@item +@dots{} +@item +SCM_CELL_WORD_@var{n} (@var{x}) @result{} SCM_CELL_WORD (@var{x}, @var{n}) +@end itemize +@end deftypefn + +@deftypefn Macro SCM SCM_CELL_OBJECT (SCM @var{x}, unsigned int @var{n}) +Deliver the cell entry @var{n} of the heap cell referenced by the +non-immediate Scheme object @var{x} as a Scheme object. It is illegal, +to access cell entries that do not hold Scheme objects by using these +macros. For convenience, the following macros are also provided. +@itemize @bullet +@item +SCM_CELL_OBJECT_0 (@var{x}) @result{} SCM_CELL_OBJECT (@var{x}, 0) +@item +SCM_CELL_OBJECT_1 (@var{x}) @result{} SCM_CELL_OBJECT (@var{x}, 1) +@item +@dots{} +@item +SCM_CELL_OBJECT_@var{n} (@var{x}) @result{} SCM_CELL_OBJECT (@var{x}, +@var{n}) +@end itemize +@end deftypefn + +@deftypefn Macro void SCM_SET_CELL_WORD (SCM @var{x}, unsigned int @var{n}, scm_bits_t @var{w}) +Write the raw C value @var{w} into entry number @var{n} of the heap cell +referenced by the non-immediate Scheme value @var{x}. Values that are +written into cells this way may only be read from the cells using the +@code{SCM_CELL_WORD} macros or, in case cell entry 0 is written, using +the @code{SCM_CELL_TYPE} macro. For the special case of cell entry 0 it +has to be made sure that @var{w} contains a cell type information which +does not describe a Scheme object. For convenience, the following +macros are also provided. +@itemize @bullet +@item +SCM_SET_CELL_WORD_0 (@var{x}, @var{w}) @result{} SCM_SET_CELL_WORD +(@var{x}, 0, @var{w}) +@item +SCM_SET_CELL_WORD_1 (@var{x}, @var{w}) @result{} SCM_SET_CELL_WORD +(@var{x}, 1, @var{w}) +@item +@dots{} +@item +SCM_SET_CELL_WORD_@var{n} (@var{x}, @var{w}) @result{} SCM_SET_CELL_WORD +(@var{x}, @var{n}, @var{w}) +@end itemize +@end deftypefn + +@deftypefn Macro void SCM_SET_CELL_OBJECT (SCM @var{x}, unsigned int @var{n}, SCM @var{o}) +Write the Scheme object @var{o} into entry number @var{n} of the heap +cell referenced by the non-immediate Scheme value @var{x}. Values that +are written into cells this way may only be read from the cells using +the @code{SCM_CELL_OBJECT} macros or, in case cell entry 0 is written, +using the @code{SCM_CELL_TYPE} macro. For the special case of cell +entry 0 the writing of a Scheme object into this cell is only allowed +if the cell forms a Scheme pair. For convenience, the following macros +are also provided. +@itemize @bullet +@item +SCM_SET_CELL_OBJECT_0 (@var{x}, @var{o}) @result{} SCM_SET_CELL_OBJECT +(@var{x}, 0, @var{o}) +@item +SCM_SET_CELL_OBJECT_1 (@var{x}, @var{o}) @result{} SCM_SET_CELL_OBJECT +(@var{x}, 1, @var{o}) +@item +@dots{} +@item +SCM_SET_CELL_OBJECT_@var{n} (@var{x}, @var{o}) @result{} +SCM_SET_CELL_OBJECT (@var{x}, @var{n}, @var{o}) +@end itemize +@end deftypefn + +@noindent +Summary: +@itemize @bullet +@item +For a non-immediate Scheme object @var{x} of unknown type, get the type +information by using @code{SCM_CELL_TYPE (@var{x})}. +@item +As soon as the cell type information is available, only use the +appropriate access methods to read and write data to the different cell +entries. +@end itemize + + +@node Basic Rules for Accessing Cell Entries +@subsubsection Basic Rules for Accessing Cell Entries + +For each cell type it is generally up to the implementation of that type +which of the corresponding cell entries hold Scheme objects and which +hold raw C values. However, there is one basic rule that has to be +followed: Scheme pairs consist of exactly two cell entries, which both +contain Scheme objects. Further, a cell which contains a Scheme object +in it first entry has to be a Scheme pair. In other words, it is not +allowed to store a Scheme object in the first cell entry and a non +Scheme object in the second cell entry. + +@c Fixme:shouldn't this rather be SCM_PAIRP / SCM_PAIR_P ? +@deftypefn Macro int SCM_CONSP (SCM @var{x}) +Determine, whether the Scheme object @var{x} is a Scheme pair, +i.e. whether @var{x} references a heap cell consisting of exactly two +entries, where both entries contain a Scheme object. In this case, both +entries will have to be accessed using the @code{SCM_CELL_OBJECT} +macros. On the contrary, if the @code{SCM_CONSP} predicate is not +fulfilled, the first entry of the Scheme cell is guaranteed not to be a +Scheme value and thus the first cell entry must be accessed using the +@code{SCM_CELL_WORD_0} macro. +@end deftypefn + + +@node Defining New Types (Smobs) +@section Defining New Types (Smobs) + +@dfn{Smobs} are Guile's mechanism for adding new non-immediate types to +the system.@footnote{The term ``smob'' was coined by Aubrey Jaffer, who +says it comes from ``small object'', referring to the fact that only the +@sc{cdr} and part of the @sc{car} of a smob's cell are available for +use.} To define a new smob type, the programmer provides Guile with +some essential information about the type --- how to print it, how to +garbage collect it, and so on --- and Guile returns a fresh type tag for +use in the first word of new cells. The programmer can then use +@code{scm_c_define_gsubr} to make a set of C functions that create and +operate on these objects visible to Scheme code. + +(You can find a complete version of the example code used in this +section in the Guile distribution, in @file{doc/example-smob}. That +directory includes a makefile and a suitable @code{main} function, so +you can build a complete interactive Guile shell, extended with the +datatypes described here.) + +@menu +* Describing a New Type:: +* Creating Instances:: +* Typechecking:: +* Garbage Collecting Smobs:: +* A Common Mistake In Allocating Smobs:: +* Garbage Collecting Simple Smobs:: +* A Complete Example:: +@end menu + +@node Describing a New Type +@subsection Describing a New Type + +To define a new type, the programmer must write four functions to +manage instances of the type: + +@table @code +@item mark +Guile will apply this function to each instance of the new type it +encounters during garbage collection. This function is responsible for +telling the collector about any other non-immediate objects the object +refers to. The default smob mark function is to not mark any data. +@xref{Garbage Collecting Smobs}, for more details. + +@item free +Guile will apply this function to each instance of the new type it could +not find any live pointers to. The function should release all +resources held by the object and return the number of bytes released. +This is analagous to the Java finalization method-- it is invoked at an +unspecified time (when garbage collection occurs) after the object is +dead. The default free function frees the smob data (if the size of the +struct passed to @code{scm_make_smob_type} is non-zero) using +@code{scm_must_free} and returns the size of that struct. @xref{Garbage +Collecting Smobs}, for more details. + +@item print +@c GJB:FIXME:: @var{exp} and @var{port} need to refer to a prototype of +@c the print function.... where is that, or where should it go? +Guile will apply this function to each instance of the new type to print +the value, as for @code{display} or @code{write}. The function should +write a printed representation of @var{exp} on @var{port}, in accordance +with the parameters in @var{pstate}. (For more information on print +states, see @ref{Port Data}.) The default print function prints +@code{#<NAME ADDRESS>} where @code{NAME} is the first argument passed to +@code{scm_make_smob_type}. + +@item equalp +If Scheme code asks the @code{equal?} function to compare two instances +of the same smob type, Guile calls this function. It should return +@code{SCM_BOOL_T} if @var{a} and @var{b} should be considered +@code{equal?}, or @code{SCM_BOOL_F} otherwise. If @code{equalp} is +@code{NULL}, @code{equal?} will assume that two instances of this type are +never @code{equal?} unless they are @code{eq?}. + +@end table + +To actually register the new smob type, call @code{scm_make_smob_type}: + +@deftypefun scm_bits_t scm_make_smob_type (const char *name, size_t size) +This function implements the standard way of adding a new smob type, +named @var{name}, with instance size @var{size}, to the system. The +return value is a tag that is used in creating instances of the type. +If @var{size} is 0, then no memory will be allocated when instances of +the smob are created, and nothing will be freed by the default free +function. Default values are provided for mark, free, print, and, +equalp, as described above. If you want to customize any of these +functions, the call to @code{scm_make_smob_type} should be immediately +followed by calls to one or several of @code{scm_set_smob_mark}, +@code{scm_set_smob_free}, @code{scm_set_smob_print}, and/or +@code{scm_set_smob_equalp}. +@end deftypefun + +Each of the below @code{scm_set_smob_XXX} functions registers a smob +special function for a given type. Each function is intended to be used +only zero or one time per type, and the call should be placed +immediately following the call to @code{scm_make_smob_type}. + +@deftypefun void scm_set_smob_mark (scm_bits_t tc, SCM (*mark) (SCM)) +This function sets the smob marking procedure for the smob type specified by +the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}. +@end deftypefun + +@deftypefun void scm_set_smob_free (scm_bits_t tc, size_t (*free) (SCM)) +This function sets the smob freeing procedure for the smob type specified by +the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}. +@end deftypefun + +@deftypefun void scm_set_smob_print (scm_bits_t tc, int (*print) (SCM, SCM, scm_print_state*)) +This function sets the smob printing procedure for the smob type specified by +the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}. +@end deftypefun + +@deftypefun void scm_set_smob_equalp (scm_bits_t tc, SCM (*equalp) (SCM, SCM)) +This function sets the smob equality-testing predicate for the smob type specified by +the tag @var{tc}. @var{tc} is the tag returned by @code{scm_make_smob_type}. +@end deftypefun + +In versions 1.4 and earlier, there was another way of creating smob +types, using @code{scm_make_smob_type_mfpe}. This function is now +deprecated and will be removed in a future version of Guile. You should +use the mechanism described above for new code, and change old code not +to use deprecated features. + +Instead of using @code{scm_make_smob_type} and calling each of the +individual @code{scm_set_smob_XXX} functions to register each special +function independently, you could use @code{scm_make_smob_type_mfpe} to +register all of the special functions at once as you create the smob +type + +@deftypefun long scm_make_smob_type_mfpe(const char *name, size_t size, SCM (*mark) (SCM), size_t (*free) (SCM), int (*print) (SCM, SCM, scm_print_state*), SCM (*equalp) (SCM, SCM)) +This function invokes @code{scm_make_smob_type} on its first two arguments +to add a new smob type named @var{name}, with instance size @var{size} to the system. +It also registers the @var{mark}, @var{free}, @var{print}, @var{equalp} smob +special functions for that new type. Any of these parameters can be @code{NULL} +to have that special function use the default behaviour for guile. +The return value is a tag that is used in creating instances of the type. If @var{size} +is 0, then no memory will be allocated when instances of the smob are created, and +nothing will be freed by the default free function. +@end deftypefun + +For example, here is how one might declare and register a new type +representing eight-bit grayscale images: + +@example +#include <libguile.h> + +static scm_bits_t image_tag; + +void +init_image_type (void) +@{ + image_tag = scm_make_smob_type ("image", sizeof (struct image)); + scm_set_smob_mark (image_tag, mark_image); + scm_set_smob_free (image_tag, free_image); + scm_set_smob_print (image_tag, print_image); +@} +@end example + + +@node Creating Instances +@subsection Creating Instances + +Like other non-immediate types, smobs start with a cell whose first word +contains typing information, and whose remaining words are free for any +use. + +After the header word containing the type code, smobs can have either +one, two or three additional words of data. These words store either a +pointer to the internal C structure holding the smob-specific data, or +the smob data itself. To create an instance of a smob type following +these standards, you should use @code{SCM_NEWSMOB}, @code{SCM_NEWSMOB2} +or @code{SCM_NEWSMOB3}:@footnote{The @code{SCM_NEWSMOB2} and +@code{SCM_NEWSMOB3} variants will allocate double cells and thus use +twice as much memory as smobs created by @code{SCM_NEWSMOB}.} + +@deftypefn Macro void SCM_NEWSMOB(SCM value, scm_bits_t tag, void *data) +@deftypefnx Macro void SCM_NEWSMOB2(SCM value, scm_bits_t tag, void *data1, void *data2) +@deftypefnx Macro void SCM_NEWSMOB3(SCM value, scm_bits_t tag, void *data1, void *data2, void *data3) +Make @var{value} contain a smob instance of the type with tag @var{tag} +and smob data @var{data} (or @var{data1}, @var{data2}, and @var{data3}). +@var{value} must be previously declared as C type @code{SCM}. +@end deftypefn + +Since it is often the case (e.g., in smob constructors) that you will +create a smob instance and return it, there is also a slightly specialized +macro for this situation: + +@deftypefn Macro fn_returns SCM_RETURN_NEWSMOB(scm_bits_t tag, void *data) +@deftypefnx Macro fn_returns SCM_RETURN_NEWSMOB2(scm_bits_t tag, void *data1, void *data2) +@deftypefnx Macro fn_returns SCM_RETURN_NEWSMOB3(scm_bits_t tag, void *data1, void *data2, void *data3) +This macro expands to a block of code that creates a smob instance of +the type with tag @var{tag} and smob data @var{data} (or @var{data1}, +@var{data2}, and @var{data3}), and returns that @code{SCM} value. It +should be the last piece of code in a block. +@end deftypefn + +Guile provides the following functions for managing memory, which are +often helpful when implementing smobs: + +@deftypefun {char *} scm_must_malloc (size_t @var{len}, char *@var{what}) +Allocate @var{len} bytes of memory, using @code{malloc}, and return a +pointer to them. + +If there is not enough memory available, invoke the garbage collector, +and try once more. If there is still not enough, signal an error, +reporting that we could not allocate @var{what}. + +This function also helps maintain statistics about the size of the heap. +@end deftypefun + +@deftypefun {char *} scm_must_realloc (char *@var{addr}, size_t @var{olen}, size_t @var{len}, char *@var{what}) +Resize (and possibly relocate) the block of memory at @var{addr}, to +have a size of @var{len} bytes, by calling @code{realloc}. Return a +pointer to the new block. + +If there is not enough memory available, invoke the garbage collector, +and try once more. If there is still not enough, signal an error, +reporting that we could not allocate @var{what}. + +The value @var{olen} should be the old size of the block of memory at +@var{addr}; it is only used for keeping statistics on the size of the +heap. +@end deftypefun + +@deftypefun void scm_must_free (char *@var{addr}) +Free the block of memory at @var{addr}, using @code{free}. If +@var{addr} is zero, signal an error, complaining of an attempt to free +something that is already free. + +This does no record-keeping; instead, the smob's @code{free} function +must take care of that. + +This function isn't usually sufficiently different from the usual +@code{free} function to be worth using. +@end deftypefun + + +Continuing the above example, if the global variable @code{image_tag} +contains a tag returned by @code{scm_make_smob_type}, here is how we +could construct a smob whose @sc{cdr} contains a pointer to a freshly +allocated @code{struct image}: + +@example +struct image @{ + int width, height; + char *pixels; + + /* The name of this image */ + SCM name; + + /* A function to call when this image is + modified, e.g., to update the screen, + or SCM_BOOL_F if no action necessary */ + SCM update_func; +@}; + +SCM +make_image (SCM name, SCM s_width, SCM s_height) +@{ + struct image *image; + int width, height; + + SCM_ASSERT (SCM_STRINGP (name), name, SCM_ARG1, "make-image"); + SCM_ASSERT (SCM_INUMP (s_width), s_width, SCM_ARG2, "make-image"); + SCM_ASSERT (SCM_INUMP (s_height), s_height, SCM_ARG3, "make-image"); + + width = SCM_INUM (s_width); + height = SCM_INUM (s_height); + + image = (struct image *) scm_must_malloc (sizeof (struct image), "image"); + image->width = width; + image->height = height; + image->pixels = scm_must_malloc (width * height, "image pixels"); + image->name = name; + image->update_func = SCM_BOOL_F; + + SCM_RETURN_NEWSMOB (image_tag, image); +@} +@end example + + +@node Typechecking +@subsection Typechecking + +Functions that operate on smobs should aggressively check the types of +their arguments, to avoid misinterpreting some other datatype as a smob, +and perhaps causing a segmentation fault. Fortunately, this is pretty +simple to do. The function need only verify that its argument is a +non-immediate, whose first word is the type tag returned by +@code{scm_make_smob_type}. + +For example, here is a simple function that operates on an image smob, +and checks the type of its argument. We also present an expanded +version of the @code{init_image_type} function, to make +@code{clear_image} and the image constructor function @code{make_image} +visible to Scheme code. + +@example +SCM +clear_image (SCM image_smob) +@{ + int area; + struct image *image; + + SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob), + image_smob, SCM_ARG1, "clear-image"); + + image = (struct image *) SCM_SMOB_DATA (image_smob); + area = image->width * image->height; + memset (image->pixels, 0, area); + + /* Invoke the image's update function. */ + if (image->update_func != SCM_BOOL_F) + scm_apply (image->update_func, SCM_EOL, SCM_EOL); + + return SCM_UNSPECIFIED; +@} + + +void +init_image_type (void) +@{ + image_tag = scm_make_smob_type ("image", sizeof (struct image)); + scm_set_smob_mark (image_tag, mark_image); + scm_set_smob_free (image_tag, free_image); + scm_set_smob_print (image_tag, print_image); + + scm_c_define_gsubr ("clear-image", 1, 0, 0, clear_image); + scm_c_define_gsubr ("make-image", 3, 0, 0, make_image); +@} +@end example + +@c GJB:FIXME:: should talk about guile-snarf somewhere! + + +@node Garbage Collecting Smobs +@subsection Garbage Collecting Smobs + +Once a smob has been released to the tender mercies of the Scheme +system, it must be prepared to survive garbage collection. Guile calls +the @code{mark} and @code{free} functions of the @code{scm_smobfuns} +structure to manage this. + +As described before (@pxref{Conservative GC}), every object in the +Scheme system has a @dfn{mark bit}, which the garbage collector uses to +tell live objects from dead ones. When collection starts, every +object's mark bit is clear. The collector traces pointers through the +heap, starting from objects known to be live, and sets the mark bit on +each object it encounters. When it can find no more unmarked objects, +the collector walks all objects, live and dead, frees those whose mark +bits are still clear, and clears the mark bit on the others. + +The two main portions of the collection are called the @dfn{mark phase}, +during which the collector marks live objects, and the @dfn{sweep +phase}, during which the collector frees all unmarked objects. + +The mark bit of a smob lives in a special memory region. When the +collector encounters a smob, it sets the smob's mark bit, and uses the +smob's type tag to find the appropriate @code{mark} function for that +smob: the one listed in that smob's @code{scm_smobfuns} structure. It +then calls the @code{mark} function, passing it the smob as its only +argument. + +The @code{mark} function is responsible for marking any other Scheme +objects the smob refers to. If it does not do so, the objects' mark +bits will still be clear when the collector begins to sweep, and the +collector will free them. If this occurs, it will probably break, or at +least confuse, any code operating on the smob; the smob's @code{SCM} +values will have become dangling references. + +To mark an arbitrary Scheme object, the @code{mark} function may call +this function: + +@deftypefun void scm_gc_mark (SCM @var{x}) +Mark the object @var{x}, and recurse on any objects @var{x} refers to. +If @var{x}'s mark bit is already set, return immediately. +@end deftypefun + +Thus, here is how we might write the @code{mark} function for the image +smob type discussed above: + +@example +@group +SCM +mark_image (SCM image_smob) +@{ + /* Mark the image's name and update function. */ + struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); + + scm_gc_mark (image->name); + scm_gc_mark (image->update_func); + + return SCM_BOOL_F; +@} +@end group +@end example + +Note that, even though the image's @code{update_func} could be an +arbitrarily complex structure (representing a procedure and any values +enclosed in its environment), @code{scm_gc_mark} will recurse as +necessary to mark all its components. Because @code{scm_gc_mark} sets +an object's mark bit before it recurses, it is not confused by +circular structures. + +As an optimization, the collector will mark whatever value is returned +by the @code{mark} function; this helps limit depth of recursion during +the mark phase. Thus, the code above could also be written as: +@example +@group +SCM +mark_image (SCM image_smob) +@{ + /* Mark the image's name and update function. */ + struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); + + scm_gc_mark (image->name); + return image->update_func; +@} +@end group +@end example + + +Finally, when the collector encounters an unmarked smob during the sweep +phase, it uses the smob's tag to find the appropriate @code{free} +function for the smob. It then calls the function, passing it the smob +as its only argument. + +The @code{free} function must release any resources used by the smob. +However, it need not free objects managed by the collector; the +collector will take care of them. The return type of the @code{free} +function should be @code{size_t}, an unsigned integral type; the +@code{free} function should return the number of bytes released, to help +the collector maintain statistics on the size of the heap. + +Here is how we might write the @code{free} function for the image smob +type: +@example +size_t +free_image (SCM image_smob) +@{ + struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); + size_t size = image->width * image->height + sizeof (*image); + + free (image->pixels); + free (image); + + return size; +@} +@end example + +During the sweep phase, the garbage collector will clear the mark bits +on all live objects. The code which implements a smob need not do this +itself. + +There is no way for smob code to be notified when collection is +complete. + +It is usually a good idea to minimize the amount of processing done +during garbage collection; keep @code{mark} and @code{free} functions +very simple. Since collections occur at unpredictable times, it is easy +for any unusual activity to interfere with normal code. + + +@node A Common Mistake In Allocating Smobs, Garbage Collecting Simple Smobs, Garbage Collecting Smobs, Defining New Types (Smobs) +@subsection A Common Mistake In Allocating Smobs + +When constructing new objects, you must be careful that the garbage +collector can always find any new objects you allocate. For example, +suppose we wrote the @code{make_image} function this way: + +@example +SCM +make_image (SCM name, SCM s_width, SCM s_height) +@{ + struct image *image; + SCM image_smob; + int width, height; + + SCM_ASSERT (SCM_STRINGP (name), name, SCM_ARG1, "make-image"); + SCM_ASSERT (SCM_INUMP (s_width), s_width, SCM_ARG2, "make-image"); + SCM_ASSERT (SCM_INUMP (s_height), s_height, SCM_ARG3, "make-image"); + + width = SCM_INUM (s_width); + height = SCM_INUM (s_height); + + image = (struct image *) scm_must_malloc (sizeof (struct image), "image"); + image->width = width; + image->height = height; + image->pixels = scm_must_malloc (width * height, "image pixels"); + + /* THESE TWO LINES HAVE CHANGED: */ + image->name = scm_string_copy (name); + image->update_func = scm_c_define_gsubr (@dots{}); + + SCM_NEWCELL (image_smob); + SCM_SET_CELL_WORD_1 (image_smob, image); + SCM_SET_CELL_TYPE (image_smob, image_tag); + + return image_smob; +@} +@end example + +This code is incorrect. The calls to @code{scm_string_copy} and +@code{scm_c_define_gsubr} allocate fresh objects. Allocating any new object +may cause the garbage collector to run. If @code{scm_c_define_gsubr} +invokes a collection, the garbage collector has no way to discover that +@code{image->name} points to the new string object; the @code{image} +structure is not yet part of any Scheme object, so the garbage collector +will not traverse it. Since the garbage collector cannot find any +references to the new string object, it will free it, leaving +@code{image} pointing to a dead object. + +A correct implementation might say, instead: + +@example + image->name = SCM_BOOL_F; + image->update_func = SCM_BOOL_F; + + SCM_NEWCELL (image_smob); + SCM_SET_CELL_WORD_1 (image_smob, image); + SCM_SET_CELL_TYPE (image_smob, image_tag); + + image->name = scm_string_copy (name); + image->update_func = scm_c_define_gsubr (@dots{}); + + return image_smob; +@end example + +Now, by the time we allocate the new string and function objects, +@code{image_smob} points to @code{image}. If the garbage collector +scans the stack, it will find a reference to @code{image_smob} and +traverse @code{image}, so any objects @code{image} points to will be +preserved. + + +@node Garbage Collecting Simple Smobs, A Complete Example, A Common Mistake In Allocating Smobs, Defining New Types (Smobs) +@subsection Garbage Collecting Simple Smobs + +It is often useful to define very simple smob types --- smobs which have +no data to mark, other than the cell itself, or smobs whose first data +word is simply an ordinary Scheme object, to be marked recursively. +Guile provides some functions to handle these common cases; you can use +this function as your smob type's @code{mark} function, if your smob's +structure is simple enough. + +If the smob refers to no other Scheme objects, then no action is +necessary; the garbage collector has already marked the smob cell +itself. In that case, you can use zero as your mark function. + +@deftypefun SCM scm_markcdr (SCM @var{x}) +Mark the references in the smob @var{x}, assuming that @var{x}'s first +data word contains an ordinary Scheme object, and @var{x} refers to no +other objects. This function simply returns @var{x}'s first data word. + +This is only useful for simple smobs created by @code{SCM_NEWSMOB} or +@code{SCM_RETURN_NEWSMOB}, not for smobs allocated as double cells. +@end deftypefun + +@deftypefun size_t scm_free0 (SCM @var{x}) +Do nothing; return zero. This function is appropriate for smobs that +use either zero or @code{scm_markcdr} as their marking functions, and +refer to no heap storage, including memory managed by @code{malloc}, +other than the smob's header cell. + +This function should not be needed anymore, because simply passing +@code{NULL} as the free function does the same. +@end deftypefun + + +@node A Complete Example +@subsection A Complete Example + +Here is the complete text of the implementation of the image datatype, +as presented in the sections above. We also provide a definition for +the smob's @code{print} function, and make some objects and functions +static, to clarify exactly what the surrounding code is using. + +As mentioned above, you can find this code in the Guile distribution, in +@file{doc/example-smob}. That directory includes a makefile and a +suitable @code{main} function, so you can build a complete interactive +Guile shell, extended with the datatypes described here.) + +@example +/* file "image-type.c" */ + +#include <stdlib.h> +#include <libguile.h> + +static scm_bits_t image_tag; + +struct image @{ + int width, height; + char *pixels; + + /* The name of this image */ + SCM name; + + /* A function to call when this image is + modified, e.g., to update the screen, + or SCM_BOOL_F if no action necessary */ + SCM update_func; +@}; + +static SCM +make_image (SCM name, SCM s_width, SCM s_height) +@{ + struct image *image; + int width, height; + + SCM_ASSERT (SCM_STRINGP (name), name, SCM_ARG1, "make-image"); + SCM_ASSERT (SCM_INUMP (s_width), s_width, SCM_ARG2, "make-image"); + SCM_ASSERT (SCM_INUMP (s_height), s_height, SCM_ARG3, "make-image"); + + width = SCM_INUM (s_width); + height = SCM_INUM (s_height); + + image = (struct image *) scm_must_malloc (sizeof (struct image), "image"); + image->width = width; + image->height = height; + image->pixels = scm_must_malloc (width * height, "image pixels"); + image->name = name; + image->update_func = SCM_BOOL_F; + + SCM_RETURN_NEWSMOB (image_tag, image); +@} + +static SCM +clear_image (SCM image_smob) +@{ + int area; + struct image *image; + + SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob), + image_smob, SCM_ARG1, "clear-image"); + + image = (struct image *) SCM_SMOB_DATA (image_smob); + area = image->width * image->height; + memset (image->pixels, 0, area); + + /* Invoke the image's update function. */ + if (image->update_func != SCM_BOOL_F) + scm_apply (image->update_func, SCM_EOL, SCM_EOL); + + return SCM_UNSPECIFIED; +@} + +static SCM +mark_image (SCM image_smob) +@{ + /* Mark the image's name and update function. */ + struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); + + scm_gc_mark (image->name); + return image->update_func; +@} + +static size_t +free_image (SCM image_smob) +@{ + struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); + size_t size = image->width * image->height + sizeof (struct image); + + free (image->pixels); + free (image); + + return size; +@} + +static int +print_image (SCM image_smob, SCM port, scm_print_state *pstate) +@{ + struct image *image = (struct image *) SCM_SMOB_DATA (image_smob); + + scm_puts ("#<image ", port); + scm_display (image->name, port); + scm_puts (">", port); + + /* non-zero means success */ + return 1; +@} + +void +init_image_type (void) +@{ + image_tag = scm_make_smob_type ("image", sizeof (struct image)); + scm_set_smob_mark (image_tag, mark_image); + scm_set_smob_free (image_tag, free_image); + scm_set_smob_print (image_tag, print_image); + + scm_c_define_gsubr ("clear-image", 1, 0, 0, clear_image); + scm_c_define_gsubr ("make-image", 3, 0, 0, make_image); +@} +@end example + +Here is a sample build and interaction with the code from the +@file{example-smob} directory, on the author's machine: + +@example +zwingli:example-smob$ make CC=gcc +gcc `guile-config compile` -c image-type.c -o image-type.o +gcc `guile-config compile` -c myguile.c -o myguile.o +gcc image-type.o myguile.o `guile-config link` -o myguile +zwingli:example-smob$ ./myguile +guile> make-image +#<primitive-procedure make-image> +guile> (define i (make-image "Whistler's Mother" 100 100)) +guile> i +#<image Whistler's Mother> +guile> (clear-image i) +guile> (clear-image 4) +ERROR: In procedure clear-image in expression (clear-image 4): +ERROR: Wrong type argument in position 1: 4 +ABORT: (wrong-type-arg) + +Type "(backtrace)" to get more information. +guile> +@end example + +@c essay @bye diff --git a/doc/ref/deprecated.texi b/doc/ref/deprecated.texi new file mode 100644 index 000000000..e99e73819 --- /dev/null +++ b/doc/ref/deprecated.texi @@ -0,0 +1,138 @@ +@page +@node Deprecated +@chapter Deprecated + +@menu +* Shared And Read Only Strings:: +@end menu + + +@node Shared And Read Only Strings +@section Shared And Read Only Strings + +The procedures described in this section are deprecated because explicit +shared substrings are planned to disappear from Guile. + +Instead, all strings will be implemented using sharing internally, +combined with a copy-on-write strategy. Once internal string sharing +and copy-on-write have been implemented, it will be unnecessary to +preserve the concept of read only strings. + +@menu +* Shared Substrings:: Strings which share memory with each other. +* Read Only Strings:: Treating certain non-strings as strings. +@end menu + + +@node Shared Substrings +@subsection Shared Substrings + +Whenever you extract a substring using @code{substring}, the Scheme +interpreter allocates a new string and copies data from the old string. +This is expensive, but @code{substring} is so convenient for +manipulating text that programmers use it often. + +Guile Scheme provides the concept of the @dfn{shared substring} to +improve performance of many substring-related operations. A shared +substring is an object that mostly behaves just like an ordinary +substring, except that it actually shares storage space with its parent +string. + +@deffn primitive make-shared-substring str [start [end]] +Return a shared substring of @var{str}. The arguments are the +same as for the @code{substring} function: the shared substring +returned includes all of the text from @var{str} between +indexes @var{start} (inclusive) and @var{end} (exclusive). If +@var{end} is omitted, it defaults to the end of @var{str}. The +shared substring returned by @code{make-shared-substring} +occupies the same storage space as @var{str}. +@end deffn + +Example: + +@example +(define foo "the quick brown fox") +(define bar (make-shared-substring some-string 4 9)) + +foo => "t h e q u i c k b r o w n f o x" +bar =========> |---------| +@end example + +The shared substring @var{bar} is not given its own storage space. +Instead, the Guile interpreter notes internally that @var{bar} points to +a portion of the memory allocated to @var{foo}. However, @var{bar} +behaves like an ordinary string in most respects: it may be used with +string primitives like @code{string-length}, @code{string-ref}, +@code{string=?}. Guile makes the necessary translation between indices +of @var{bar} and indices of @var{foo} automatically. + +@example +(string-length? bar) @result{} 5 ; bar only extends from indices 4 to 9 +(string-ref bar 3) @result{} #\c ; same as (string-ref foo 7) +(make-shared-substring bar 2) + @result{} "ick" ; can even make a shared substring! +@end example + +Because creating a shared substring does not require allocating new +storage from the heap, it is a very fast operation. However, because it +shares memory with its parent string, a change to the contents of the +parent string will implicitly change the contents of its shared +substrings. + +@example +(string-set! foo 7 #\r) +bar @result{} "quirk" +@end example + +Guile considers shared substrings to be immutable. This is because +programmers might not always be aware that a given string is really a +shared substring, and might innocently try to mutate it without +realizing that the change would affect its parent string. (We are +currently considering a "copy-on-write" strategy that would permit +modifying shared substrings without affecting the parent string.) + +In general, shared substrings are useful in circumstances where it is +important to divide a string into smaller portions, but you do not +expect to change the contents of any of the strings involved. + + +@node Read Only Strings +@subsection Read Only Strings + +In previous versions of Guile, there was the idea that some string-based +primitives such as @code{string-append} could equally accept symbols as +arguments. For example, one could write + +@lisp +(string-append '/home/ 'vigilia) +@end lisp + +@noindent +and get @code{"/home/vigilia"} as the result. The term @dfn{read only +string} was adopted to describe the argument type expected by such +primitives. + +This idea has now been removed. The predicate @code{read-only-string?} +still exists, but deprecated, and is equivalent to + +@lisp +(lambda (x) (or (string? x) (symbol? x))) +@end lisp + +@noindent +But no Guile primitives now use @code{read-only-string?} to validate +their arguments. + +String-based primitives such as @code{string-append} +now require strings: + +@lisp +(string-append '/home/ 'vigilia) +@result{} +ERROR: Wrong type argument (expecting STRINGP): /home/ +@end lisp + +@deffn primitive read-only-string? obj +Return @code{#t} if @var{obj} is either a string or a symbol, +otherwise return @code{#f}. +@end deffn diff --git a/doc/ref/expect.texi b/doc/ref/expect.texi new file mode 100644 index 000000000..7e169e428 --- /dev/null +++ b/doc/ref/expect.texi @@ -0,0 +1,142 @@ +@page +@node Expect +@chapter Expect + +The macros in this section are made available with: + +@smalllisp +(use-modules (ice-9 expect)) +@end smalllisp + +@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. +Actions can be taken when a particular string is matched, when a timeout +occurs, or when end-of-file is seen on the port. The @code{expect} macro +is described below; @code{expect-strings} is a front-end to @code{expect} +based on regexec (see the regular expression documentation). + +@defmac expect-strings clause @dots{} +By default, @code{expect-strings} will read from the current input port. +The first term in each clause consists of an expression evaluating to +a string pattern (regular expression). As characters +are read one-by-one from the port, they are accumulated in a buffer string +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 +(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 + +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 +and end of the string. + +There are two other ways to write a clause: + +The expression(s) to evaluate +can be omitted, in which case the result of the regular expression match +(converted to strings, as obtained from regexec with match-pick set to "") +will be returned if the pattern matches. + +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 +("^daemon" => write) +("^d\\(aemon\\)" => (lambda args (for-each write args))) +("^da\\(em\\)on" => (lambda (all sub) + (write all) (newline) + (write sub) (newline))) +@end smalllisp + +The order of the substrings corresponds to the order in which the +opening brackets occur. + +A number of variables can be used to control the behaviour +of @code{expect} (and @code{expect-strings}). +Most have default top-level bindings to the value @code{#f}, +which produces the default behaviour. +They can be redefined at the +top level or locally bound in a form enclosing the expect expression. + +@table @code +@item expect-port +A port to read characters from, instead of the current input port. +@item expect-timeout +@code{expect} will terminate after this number of +seconds, returning @code{#f} or the value returned by expect-timeout-proc. +@item expect-timeout-proc +A procedure called if timeout occurs. The procedure takes a single argument: +the accumulated string. +@item expect-eof-proc +A procedure called if end-of-file is detected on the input port. The +procedure takes a single argument: the accumulated string. +@item expect-char-proc +A procedure to be called every time a character is read from the +port. The procedure takes a single argument: the character which was read. +@item expect-strings-compile-flags +Flags to be used when compiling a regular expression, which are passed +to @code{make-regexp} @xref{Regexp Functions}. The default value +is @code{regexp/newline}. +@item expect-strings-exec-flags +Flags to be used when executing a regular expression, which are +passed to regexp-exec @xref{Regexp Functions}. +The default value is @code{regexp/noteol}, which prevents @code{$} +from matching the end of the string while it is still accumulating, +but still allows it to match after a line break or at the end of file. +@end table + +Here's an example using all of the variables: + +@smalllisp +(let ((expect-port (open-input-file "/etc/passwd")) + (expect-timeout 1) + (expect-timeout-proc + (lambda (s) (display "Times up!\n"))) + (expect-eof-proc + (lambda (s) (display "Reached the end of the file!\n"))) + (expect-char-proc display) + (expect-strings-compile-flags (logior regexp/newline regexp/icase)) + (expect-strings-exec-flags 0)) + (expect-strings + ("^nobody" (display "Got a nobody user\n")))) +@end smalllisp +@end defmac + +@defmac expect clause @dots{} +@code{expect} is used in the same way as @code{expect-strings}, +but tests are specified not as patterns, but as procedures. The +procedures are called in turn after each character is read from the +port, with two arguments: the value of the accumulated string and +a flag to indicate whether end-of-file has been reached. The flag +will usually be @code{#f}, but if end-of-file is reached, the procedures +are called an additional time with the final accumulated string and +@code{#t}. + +The test is successful if the procedure returns a non-false value. + +If the @code{=>} syntax is used, then if the test succeeds it must return +a list containing the arguments to be provided to the corresponding +expression. + +In the following example, a string will only be matched at the beginning +of the file: + +@smalllisp +(let ((expect-port (open-input-file "/etc/passwd"))) + (expect + ((lambda (s eof?) (string=? s "fnord!")) + (display "Got a nobody user!\n")))) +@end smalllisp + +The control variables described for @code{expect-strings} also +influence the behaviour of @code{expect}, with the exception of +variables whose names begin with @code{expect-strings-}. +@end defmac diff --git a/doc/ref/extend.texi b/doc/ref/extend.texi new file mode 100644 index 000000000..5c72bef33 --- /dev/null +++ b/doc/ref/extend.texi @@ -0,0 +1,44 @@ +@page +@node Libguile Intro +@chapter Using Guile as an Extension Language + +The chapters in this part of the manual explain how to use Guile as a +powerful application extension language. + +An important change for the 1.6.x series of Guile releases is that the +GH interface is now deprecated. For the reasoning behind this decision, +see @xref{GH deprecation}. The GH interface will continue to be +supported for the 1.6.x and 1.8.x release series, but will be dropped +thereafter, so developers are encouraged to switch progressively to the +scm interface. The last chapter in this part of the manual (@pxref{GH}) +documents both how to use GH and how to switch from GH to scm. + +The Guile developers believe that clarification of the GH vs. scm +debate, and the consequent deprecation of the GH interface, are in the +long term interests of the project. However it does create an +unfortunate situation for developers who want to start a project using +Guile and so read the manual to find out how to proceed. They will +discover that the GH interface, although quite well documented, is +deprecated, but that there is almost no adequate documentation for its +theoretical replacement, the scm interface. Moreover, the scm interface +still has the odd few rough edges which need smoothing down. + +Therefore, although deprecated, it is quite OK to continue to use the GH +interface if you feel uncomfortable with the `scm_' interface as it +stands today. By the time that support for GH is dropped, we plan to +have thoroughly documented the `scm_' interface, and to have enhanced it +such that conversion from GH to the `scm_' interface will be very +straightforward, and probably mostly automated. + +As far as documentation of the scm interface is concerned, the current +position is that it is a bit confused, but that the situation should +improve rapidly once the 1.6.0 release is out. The plan is to refocus +the bulk of Part II, currently ``Guile Scheme'', as the ``Guile API +Reference'' so that it covers both Scheme and C interfaces. (This makes +sense because almost all of Guile's primitive procedures on the Scheme +level --- e.g. @code{memq} --- are also available as C level primitives +in the scm interface --- e.g. @code{scm_memq}.) There will then remain +a certain amount of Scheme-specific (such as the ``Basic Ideas'' +chapter) and C-specific documentation (such as SMOB usage and +interaction with the garbage collector) to collect into corresponding +chapters. diff --git a/doc/ref/gh.texi b/doc/ref/gh.texi new file mode 100644 index 000000000..15d89c18f --- /dev/null +++ b/doc/ref/gh.texi @@ -0,0 +1,1164 @@ +@page +@node GH +@chapter GH: A Portable C to Scheme Interface +@cindex libguile - gh +@cindex gh +@cindex gh - reference manual + +This chapter shows how to use the GH interface to call Guile from your +application's C code, and to add new Scheme level procedures to Guile +whose behaviour is specified by application specific code written in C. + +Note, however, that the GH interface is now deprecated, and developers +are encouraged to switch to using the scm interface instead. Therefore, +for each GH feature, this chapter should also document how to achieve +the same result using the scm interface. + +@menu +* GH deprecation:: Why the GH interface is now deprecated. +* gh preliminaries:: +* Data types and constants defined by gh:: +* Starting and controlling the interpreter:: +* Error messages:: +* Executing Scheme code:: +* Defining new Scheme procedures in C:: +* Converting data between C and Scheme:: +* Type predicates:: +* Equality predicates:: +* Memory allocation and garbage collection:: +* Calling Scheme procedures from C:: +* Mixing gh and scm APIs:: +* scm transition summary:: +@end menu + + +@node GH deprecation +@section Why the GH Interface is Now Deprecated + +Historically, the GH interface was the product of a practical problem +and a neat idea. The practical problem was that the interface of the +@code{scm_} functions with which Guile itself was written (inherited +from Aubrey Jaffer's SCM) was so closely tied to the (rather arcane) +details of the internal data representation that it was extremely +difficult to write a Guile extension using these functions. The neat +idea was to define a high level language extension interface in such a +way that other extension language projects, not just Guile, would be +able to provide an implementation of that interface; then applications +using this interface could be compiled with whichever of the various +available implementations they chose. So the GH interface was created, +and advertised both as the recommended interface for application +developers wishing to use Guile, and as a portable high level interface +that could theoretically be implemented by other extension language +projects. + +Time passed, and various things changed. Crucially, an enormous number +of improvements were made to the @code{scm_} interface that Guile itself +uses in its implementation, with the result that it is now both easy and +comfortable to write a Guile extension with this interface. At the same +time, the contents of the GH interface were somewhat neglected by the +core Guile developers, such that some key operations --- such as smob +creation and management --- are simply not possible using GH alone. +Finally, the idea of multiple implementations of the GH interface did +not really crystallize (apart, I believe, from a short lived +implementation by the MzScheme project). + +For all these reasons, the Guile developers have decided to deprecate +the GH interface --- which means that support for GH will be completely +removed after the next few releases --- and to focus only on the +@code{scm_} interface, with additions to ensure that it is as easy to +use in all respects as GH was. + +It remains an open question whether a deep kind of interface portability +would be useful for extension language-based applications, and it may +still be an interesting project to attempt to define a corresponding +GH-like interface, but the Guile developers no longer plan to try to do +this as part of the core Guile project. + + +@node gh preliminaries +@section gh preliminaries + +To use gh, you must have the following toward the beginning of your C +source: +@smallexample +#include <guile/gh.h> +@end smallexample +@cindex gh - headers + +When you link, you will have to add at least @code{-lguile} to the list +of libraries. If you are using more of Guile than the basic Scheme +interpreter, you will have to add more libraries. +@cindex gh - linking + + +@node Data types and constants defined by gh +@section Data types and constants defined by gh +@cindex libguile - data types + +The following C constants and data types are defined in gh: + +@deftp {Data type} SCM +This is a C data type used to store all Scheme data, no matter what the +Scheme type. Values are converted between C data types and the SCM type +with utility functions described below (@pxref{Converting data between C +and Scheme}). [FIXME: put in references to Jim's essay and so forth.] +@end deftp +@cindex SCM data type + +@defvr Constant SCM_BOOL_T +@defvrx Constant SCM_BOOL_F +The @emph{Scheme} values returned by many boolean procedures in +libguile. + +This can cause confusion because they are different from 0 and 1. In +testing a boolean function in libguile programming, you must always make +sure that you check the spec: @code{gh_} and @code{scm_} functions will +usually return @code{SCM_BOOL_T} and @code{SCM_BOOL_F}, but other C +functions usually can be tested against 0 and 1, so programmers' fingers +tend to just type @code{if (boolean_function()) @{ ... @}} +@end defvr + +@defvr Constant SCM_UNSPECIFIED +This is a SCM value that is not the same as any legal Scheme value. It +is the value that a Scheme function returns when its specification says +that its return value is unspecified. +@end defvr + +@defvr Constant SCM_UNDEFINED +This is another SCM value that is not the same as any legal Scheme +value. It is the value used to mark variables that do not yet have a +value, and it is also used in C to terminate functions with variable +numbers of arguments, such as @code{gh_list()}. +@end defvr + + +@node Starting and controlling the interpreter +@section Starting and controlling the interpreter +@cindex libguile - start interpreter + +In almost every case, your first @code{gh_} call will be: + +@deftypefun void gh_enter (int @var{argc}, char *@var{argv}[], void (*@var{main_prog})()) +Starts up a Scheme interpreter with all the builtin Scheme primitives. +@code{gh_enter()} never exits, and the user's code should all be in the +@code{@var{main_prog}()} function. @code{argc} and @code{argv} will be +passed to @var{main_prog}. + +@deftypefun void main_prog (int @var{argc}, char *@var{argv}[]) +This is the user's main program. It will be invoked by +@code{gh_enter()} after Guile has been started up. +@end deftypefun + +Note that you can use @code{gh_repl} inside @code{gh_enter} (in other +words, inside the code for @code{main-prog}) if you want the program to +be controled by a Scheme read-eval-print loop. +@end deftypefun + +@cindex read eval print loop -- from the gh_ interface +@cindex REPL -- from the gh_ interface +A convenience routine which enters the Guile interpreter with the +standard Guile read-eval-print loop (@dfn{REPL}) is: + +@deftypefun void gh_repl (int @var{argc}, char *@var{argv}[]) +Enters the Scheme interpreter giving control to the Scheme REPL. +Arguments are processed as if the Guile program @file{guile} were being +invoked. + +Note that @code{gh_repl} should be used @emph{inside} @code{gh_enter}, +since any Guile interpreter calls are meaningless unless they happen in +the context of the interpreter. + +Also note that when you use @code{gh_repl}, your program will be +controlled by Guile's REPL (which is written in Scheme and has many +useful features). Use straight C code inside @code{gh_enter} if you +want to maintain execution control in your C program. +@end deftypefun + +You will typically use @code{gh_enter} and @code{gh_repl} when you +want a Guile interpreter enhanced by your own libraries, but otherwise +quite normal. For example, to build a Guile--derived program that +includes some random number routines @dfn{GSL} (GNU Scientific Library), +you would write a C program that looks like this: + +@smallexample +#include <guile/gh.h> +#include <gsl_ran.h> + +/* random number suite */ +SCM gw_ran_seed(SCM s) +@{ + gsl_ran_seed(gh_scm2int(s)); + return SCM_UNSPECIFIED; +@} + +SCM gw_ran_random() +@{ + SCM x; + + x = gh_ulong2scm(gsl_ran_random()); + return x; +@} + +SCM gw_ran_uniform() +@{ + SCM x; + + x = gh_double2scm(gsl_ran_uniform()); + return x; +@} +SCM gw_ran_max() +@{ + return gh_double2scm(gsl_ran_max()); +@} + +void +init_gsl() +@{ + /* random number suite */ + gh_new_procedure("gsl-ran-seed", gw_ran_seed, 1, 0, 0); + gh_new_procedure("gsl-ran-random", gw_ran_random, 0, 0, 0); + gh_new_procedure("gsl-ran-uniform", gw_ran_uniform, 0, 0, 0); + gh_new_procedure("gsl-ran-max", gw_ran_max, 0, 0, 0); +@} + +void +main_prog (int argc, char *argv[]) +@{ + init_gsl(); + + gh_repl(argc, argv); +@} + +int +main (int argc, char *argv[]) +@{ + gh_enter (argc, argv, main_prog); +@} +@end smallexample + +Then, supposing the C program is in @file{guile-gsl.c}, you could +compile it with @kbd{gcc -o guile-gsl guile-gsl.c -lguile -lgsl}. + +The resulting program @file{guile-gsl} would have new primitive +procedures @code{gsl-ran-random}, @code{gsl-ran-gaussian} and so forth. + + +@node Error messages +@section Error messages +@cindex libguile - error messages +@cindex error messages in libguile + +[FIXME: need to fill this based on Jim's new mechanism] + + +@node Executing Scheme code +@section Executing Scheme code +@cindex libguile - executing Scheme +@cindex executing Scheme + +Once you have an interpreter running, you can ask it to evaluate Scheme +code. There are two calls that implement this: + +@deftypefun SCM gh_eval_str (char *@var{scheme_code}) +This asks the interpreter to evaluate a single string of Scheme code, +and returns the result of the last expression evaluated. + +Note that the line of code in @var{scheme_code} must be a well formed +Scheme expression. If you have many lines of code before you balance +parentheses, you must either concatenate them into one string, or use +@code{gh_eval_file()}. +@end deftypefun + +@deftypefun SCM gh_eval_file (char *@var{fname}) +@deftypefunx SCM gh_load (char *@var{fname}) +@code{gh_eval_file} is completely analogous to @code{gh_eval_str()}, +except that a whole file is evaluated instead of a string. +@code{gh_eval_file} returns @code{SCM_UNSPECIFIED}. + +@code{gh_load} is identical to @code{gh_eval_file} (it's a macro that +calls @code{gh_eval_file} on its argument). It is provided to start +making the @code{gh_} interface match the R5RS Scheme procedures +closely. +@end deftypefun + + +@node Defining new Scheme procedures in C +@section Defining new Scheme procedures in C +@cindex libguile - new procedures +@cindex new procedures +@cindex procedures, new +@cindex new primitives +@cindex primitives, new + +The real interface between C and Scheme comes when you can write new +Scheme procedures in C. This is done through the routine + + +@deftypefn {Libguile high} SCM gh_new_procedure (char *@var{proc_name}, SCM (*@var{fn})(), int @var{n_required_args}, int @var{n_optional_args}, int @var{restp}) +@code{gh_new_procedure} defines a new Scheme procedure. Its Scheme name +will be @var{proc_name}, it will be implemented by the C function +(*@var{fn})(), it will take at least @var{n_required_args} arguments, +and at most @var{n_optional_args} extra arguments. + +When the @var{restp} parameter is 1, the procedure takes a final +argument: a list of remaining parameters. + +@code{gh_new_procedure} returns an SCM value representing the procedure. + +The C function @var{fn} should have the form +@deftypefn {Libguile high} SCM fn (SCM @var{req1}, SCM @var{req2}, ..., SCM @var{opt1}, SCM @var{opt2}, ..., SCM @var{rest_args}) +The arguments are all passed as SCM values, so the user will have to use +the conversion functions to convert to standard C types. + +Examples of C functions used as new Scheme primitives can be found in +the sample programs @code{learn0} and @code{learn1}. +@end deftypefn + +@end deftypefn + +@strong{Rationale:} this is the correct way to define new Scheme +procedures in C. The ugly mess of arguments is required because of how +C handles procedures with variable numbers of arguments. + +@strong{Note:} what about documentation strings? + +@cartouche +There are several important considerations to be made when writing the C +routine @code{(*fn)()}. + +First of all the C routine has to return type @code{SCM}. + +Second, all arguments passed to the C funcion will be of type +@code{SCM}. + +Third: the C routine is now subject to Scheme flow control, which means +that it could be interrupted at any point, and then reentered. This +means that you have to be very careful with operations such as +allocating memory, modifying static data @dots{} + +Fourth: to get around the latter issue, you can use +@code{GH_DEFER_INTS} and @code{GH_ALLOW_INTS}. +@end cartouche + +@defmac GH_DEFER_INTS +@defmacx GH_ALLOW_INTS +These macros disable and reenable Scheme's flow control. They +@end defmac + + +@c [??? have to do this right; maybe using subsections, or maybe creating a +@c section called Flow control issues...] + +@c [??? Go into exhaustive detail with examples of the various possible +@c combinations of required and optional args...] + + +@node Converting data between C and Scheme +@section Converting data between C and Scheme +@cindex libguile - converting data +@cindex data conversion +@cindex converting data + +Guile provides mechanisms to convert data between C and Scheme. This +allows new builtin procedures to understand their arguments (which are +of type @code{SCM}) and return values of type @code{SCM}. + + +@menu +* C to Scheme:: +* Scheme to C:: +@end menu + +@node C to Scheme +@subsection C to Scheme + +@deftypefun SCM gh_bool2scm (int @var{x}) +Returns @code{#f} if @var{x} is zero, @code{#t} otherwise. +@end deftypefun + +@deftypefun SCM gh_ulong2scm (unsigned long @var{x}) +@deftypefunx SCM gh_long2scm (long @var{x}) +@deftypefunx SCM gh_double2scm (double @var{x}) +@deftypefunx SCM gh_char2scm (char @var{x}) +Returns a Scheme object with the value of the C quantity @var{x}. +@end deftypefun + +@deftypefun SCM gh_str2scm (char *@var{s}, int @var{len}) +Returns a new Scheme string with the (not necessarily null-terminated) C +array @var{s} data. +@end deftypefun + +@deftypefun SCM gh_str02scm (char *@var{s}) +Returns a new Scheme string with the null-terminated C string @var{s} +data. +@end deftypefun + +@deftypefun SCM gh_set_substr (char *@var{src}, SCM @var{dst}, int @var{start}, int @var{len}) +Copy @var{len} characters at @var{src} into the @emph{existing} Scheme +string @var{dst}, starting at @var{start}. @var{start} is an index into +@var{dst}; zero means the beginning of the string. + +If @var{start} + @var{len} is off the end of @var{dst}, signal an +out-of-range error. +@end deftypefun + +@deftypefun SCM gh_symbol2scm (char *@var{name}) +Given a null-terminated string @var{name}, return the symbol with that +name. +@end deftypefun + +@deftypefun SCM gh_ints2scm (int *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_doubles2scm (double *@var{dptr}, int @var{n}) +Make a scheme vector containing the @var{n} ints or doubles at memory +location @var{dptr}. +@end deftypefun + +@deftypefun SCM gh_chars2byvect (char *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_shorts2svect (short *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_longs2ivect (long *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_ulongs2uvect (ulong *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_floats2fvect (float *@var{dptr}, int @var{n}) +@deftypefunx SCM gh_doubles2dvect (double *@var{dptr}, int @var{n}) +Make a scheme uniform vector containing the @var{n} chars, shorts, +longs, unsigned longs, floats or doubles at memory location @var{dptr}. +@end deftypefun + + + +@node Scheme to C +@subsection Scheme to C + +@deftypefun int gh_scm2bool (SCM @var{obj}) +@deftypefunx {unsigned long} gh_scm2ulong (SCM @var{obj}) +@deftypefunx long gh_scm2long (SCM @var{obj}) +@deftypefunx double gh_scm2double (SCM @var{obj}) +@deftypefunx int gh_scm2char (SCM @var{obj}) +These routines convert the Scheme object to the given C type. +@end deftypefun + +@deftypefun char *gh_scm2newstr (SCM @var{str}, int *@var{lenp}) +Given a Scheme string @var{str}, return a pointer to a new copy of its +contents, followed by a null byte. If @var{lenp} is non-null, set +@code{*@var{lenp}} to the string's length. + +This function uses malloc to obtain storage for the copy; the caller is +responsible for freeing it. + +Note that Scheme strings may contain arbitrary data, including null +characters. This means that null termination is not a reliable way to +determine the length of the returned value. However, the function +always copies the complete contents of @var{str}, and sets @var{*lenp} +to the true length of the string (when @var{lenp} is non-null). +@end deftypefun + + +@deftypefun void gh_get_substr (SCM str, char *return_str, int *lenp) +Copy @var{len} characters at @var{start} from the Scheme string +@var{src} to memory at @var{dst}. @var{start} is an index into +@var{src}; zero means the beginning of the string. @var{dst} has +already been allocated by the caller. + +If @var{start} + @var{len} is off the end of @var{src}, signal an +out-of-range error. +@end deftypefun + +@deftypefun char *gh_symbol2newstr (SCM @var{sym}, int *@var{lenp}) +Takes a Scheme symbol and returns a string of the form +@code{"'symbol-name"}. If @var{lenp} is non-null, the string's length +is returned in @code{*@var{lenp}}. + +This function uses malloc to obtain storage for the returned string; the +caller is responsible for freeing it. +@end deftypefun + +@deftypefun char *gh_scm2chars (SCM @var{vector}, chars *@var{result}) +@deftypefunx short *gh_scm2shorts (SCM @var{vector}, short *@var{result}) +@deftypefunx long *gh_scm2longs (SCM @var{vector}, long *@var{result}) +@deftypefunx float *gh_scm2floats (SCM @var{vector}, float *@var{result}) +@deftypefunx double *gh_scm2doubles (SCM @var{vector}, double *@var{result}) +Copy the numbers in @var{vector} to the array pointed to by @var{result} +and return it. If @var{result} is NULL, allocate a double array large +enough. + +@var{vector} can be an ordinary vector, a weak vector, or a signed or +unsigned uniform vector of the same type as the result array. For +chars, @var{vector} can be a string or substring. For floats and +doubles, @var{vector} can contain a mix of inexact and integer values. + +If @var{vector} is of unsigned type and contains values too large to fit +in the signed destination array, those values will be wrapped around, +that is, data will be copied as if the destination array was unsigned. +@end deftypefun + + +@node Type predicates +@section Type predicates + +These C functions mirror Scheme's type predicate procedures with one +important difference. The C routines return C boolean values (0 and 1) +instead of @code{SCM_BOOL_T} and @code{SCM_BOOL_F}. + +The Scheme notational convention of putting a @code{?} at the end of +predicate procedure names is mirrored in C by placing @code{_p} at the +end of the procedure. For example, @code{(pair? ...)} maps to +@code{gh_pair_p(...)}. + +@deftypefun int gh_boolean_p (SCM @var{val}) +Returns 1 if @var{val} is a boolean, 0 otherwise. +@end deftypefun + +@deftypefun int gh_symbol_p (SCM @var{val}) +Returns 1 if @var{val} is a symbol, 0 otherwise. +@end deftypefun + +@deftypefun int gh_char_p (SCM @var{val}) +Returns 1 if @var{val} is a char, 0 otherwise. +@end deftypefun + +@deftypefun int gh_vector_p (SCM @var{val}) +Returns 1 if @var{val} is a vector, 0 otherwise. +@end deftypefun + +@deftypefun int gh_pair_p (SCM @var{val}) +Returns 1 if @var{val} is a pair, 0 otherwise. +@end deftypefun + +@deftypefun int gh_procedure_p (SCM @var{val}) +Returns 1 if @var{val} is a procedure, 0 otherwise. +@end deftypefun + +@deftypefun int gh_list_p (SCM @var{val}) +Returns 1 if @var{val} is a list, 0 otherwise. +@end deftypefun + +@deftypefun int gh_inexact_p (SCM @var{val}) +Returns 1 if @var{val} is an inexact number, 0 otherwise. +@end deftypefun + +@deftypefun int gh_exact_p (SCM @var{val}) +Returns 1 if @var{val} is an exact number, 0 otherwise. +@end deftypefun + + +@node Equality predicates +@section Equality predicates + +These C functions mirror Scheme's equality predicate procedures with one +important difference. The C routines return C boolean values (0 and 1) +instead of @code{SCM_BOOL_T} and @code{SCM_BOOL_F}. + +The Scheme notational convention of putting a @code{?} at the end of +predicate procedure names is mirrored in C by placing @code{_p} at the +end of the procedure. For example, @code{(equal? ...)} maps to +@code{gh_equal_p(...)}. + +@deftypefun int gh_eq_p (SCM x, SCM y) +Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's +@code{eq?} predicate, 0 otherwise. +@end deftypefun + +@deftypefun int gh_eqv_p (SCM x, SCM y) +Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's +@code{eqv?} predicate, 0 otherwise. +@end deftypefun + +@deftypefun int gh_equal_p (SCM x, SCM y) +Returns 1 if @var{x} and @var{y} are equal in the sense of Scheme's +@code{equal?} predicate, 0 otherwise. +@end deftypefun + +@deftypefun int gh_string_equal_p (SCM @var{s1}, SCM @var{s2}) +Returns 1 if the strings @var{s1} and @var{s2} are equal, 0 otherwise. +@end deftypefun + +@deftypefun int gh_null_p (SCM @var{l}) +Returns 1 if @var{l} is an empty list or pair; 0 otherwise. +@end deftypefun + + +@node Memory allocation and garbage collection +@section Memory allocation and garbage collection + +@c [FIXME: flesh this out with some description of garbage collection in +@c scm/guile] + +@c @deftypefun SCM gh_mkarray (int size) +@c Allocate memory for a Scheme object in a garbage-collector-friendly +@c manner. +@c @end deftypefun + + +@node Calling Scheme procedures from C +@section Calling Scheme procedures from C + +Many of the Scheme primitives are available in the @code{gh_} +interface; they take and return objects of type SCM, and one could +basically use them to write C code that mimics Scheme code. + +I will list these routines here without much explanation, since what +they do is the same as documented in @ref{Standard procedures, R5RS, , +r5rs, R5RS}. But I will point out that when a procedure takes a +variable number of arguments (such as @code{gh_list}), you should pass +the constant @var{SCM_UNDEFINED} from C to signify the end of the list. + +@deftypefun SCM gh_define (char *@var{name}, SCM @var{val}) +Corresponds to the Scheme @code{(define name val)}: it binds a value to +the given name (which is a C string). Returns the new object. +@end deftypefun + +@heading Pairs and lists + +@deftypefun SCM gh_cons (SCM @var{a}, SCM @var{b}) +@deftypefunx SCM gh_list (SCM l0, SCM l1, ... , SCM_UNDEFINED) +These correspond to the Scheme @code{(cons a b)} and @code{(list l0 l1 +...)} procedures. Note that @code{gh_list()} is a C macro that invokes +@code{scm_listify()}. +@end deftypefun + +@deftypefun SCM gh_car (SCM @var{obj}) +@deftypefunx SCM gh_cdr (SCM @var{obj}) +@dots{} + +@deftypefunx SCM gh_c[ad][ad][ad][ad]r (SCM @var{obj}) +These correspond to the Scheme @code{(caadar ls)} procedures etc @dots{} +@end deftypefun + +@deftypefun SCM gh_set_car_x(SCM @var{pair}, SCM @var{value}) +Modifies the CAR of @var{pair} to be @var{value}. This is equivalent to +the Scheme procedure @code{(set-car! ...)}. +@end deftypefun + +@deftypefun SCM gh_set_cdr_x(SCM @var{pair}, SCM @var{value}) +Modifies the CDR of @var{pair} to be @var{value}. This is equivalent to +the Scheme procedure @code{(set-cdr! ...)}. +@end deftypefun + +@deftypefun {unsigned long} gh_length (SCM @var{ls}) +Returns the length of the list. +@end deftypefun + +@deftypefun SCM gh_append (SCM @var{args}) +@deftypefunx SCM gh_append2 (SCM @var{l1}, SCM @var{l2}) +@deftypefunx SCM gh_append3 (SCM @var{l1}, SCM @var{l2}, @var{l3}) +@deftypefunx SCM gh_append4 (SCM @var{l1}, SCM @var{l2}, @var{l3}, @var{l4}) +@code{gh_append()} takes @var{args}, which is a list of lists +@code{(list1 list2 ...)}, and returns a list containing all the elements +of the individual lists. + +A typical invocation of @code{gh_append()} to append 5 lists together +would be +@smallexample + gh_append(gh_list(l1, l2, l3, l4, l5, SCM_UNDEFINED)); +@end smallexample + +The functions @code{gh_append2()}, @code{gh_append2()}, +@code{gh_append3()} and @code{gh_append4()} are convenience routines to +make it easier for C programs to form the list of lists that goes as an +argument to @code{gh_append()}. +@end deftypefun + +@deftypefun SCM gh_reverse (SCM @var{ls}) +Returns a new list that has the same elements as @var{ls} but in the +reverse order. Note that this is implemented as a macro which calls +@code{scm_reverse()}. +@end deftypefun + +@deftypefun SCM gh_list_tail (SCM @var{ls}, SCM @var{k}) +Returns the sublist of @var{ls} with the last @var{k} elements. +@end deftypefun + +@deftypefun SCM gh_list_ref (SCM @var{ls}, SCM @var{k}) +Returns the @var{k}th element of the list @var{ls}. +@end deftypefun + +@deftypefun SCM gh_memq (SCM @var{x}, SCM @var{ls}) +@deftypefunx SCM gh_memv (SCM @var{x}, SCM @var{ls}) +@deftypefunx SCM gh_member (SCM @var{x}, SCM @var{ls}) +These functions return the first sublist of @var{ls} whose CAR is +@var{x}. They correspond to @code{(memq x ls)}, @code{(memv x ls)} and +@code{(member x ls)}, and hence use (respectively) @code{eq?}, +@code{eqv?} and @code{equal?} to do comparisons. + +If @var{x} does not appear in @var{ls}, the value @code{SCM_BOOL_F} (not +the empty list) is returned. + +Note that these functions are implemented as macros which call +@code{scm_memq()}, @code{scm_memv()} and @code{scm_member()} +respectively. +@end deftypefun + +@deftypefun SCM gh_assq (SCM @var{x}, SCM @var{alist}) +@deftypefunx SCM gh_assv (SCM @var{x}, SCM @var{alist}) +@deftypefunx SCM gh_assoc (SCM @var{x}, SCM @var{alist}) +These functions search an @dfn{association list} (list of pairs) +@var{alist} for the first pair whose CAR is @var{x}, and they return +that pair. + +If no pair in @var{alist} has @var{x} as its CAR, the value +@code{SCM_BOOL_F} (not the empty list) is returned. + +Note that these functions are implemented as macros which call +@code{scm_assq()}, @code{scm_assv()} and @code{scm_assoc()} +respectively. +@end deftypefun + + +@heading Symbols + +@c @deftypefun SCM gh_symbol (SCM str, SCM len) +@c @deftypefunx SCM gh_tmp_symbol (SCM str, SCM len) +@c Takes the given string @var{str} of length @var{len} and returns a +@c symbol corresponding to that string. +@c @end deftypefun + + +@heading Vectors + +@deftypefun SCM gh_make_vector (SCM @var{n}, SCM @var{fill}) +@deftypefunx SCM gh_vector (SCM @var{ls}) +@deftypefunx SCM gh_vector_ref (SCM @var{v}, SCM @var{i}) +@deftypefunx SCM gh_vector_set (SCM @var{v}, SCM @var{i}, SCM @var{val}) +@deftypefunx {unsigned long} gh_vector_length (SCM @var{v}) +@deftypefunx SCM gh_list_to_vector (SCM @var{ls}) +These correspond to the Scheme @code{(make-vector n fill)}, +@code{(vector a b c ...)} @code{(vector-ref v i)} @code{(vector-set v i +value)} @code{(vector-length v)} @code{(list->vector ls)} procedures. + +The correspondence is not perfect for @code{gh_vector}: this routine +taks a list @var{ls} instead of the individual list elements, thus +making it identical to @code{gh_list_to_vector}. + +There is also a difference in gh_vector_length: the value returned is a +C @code{unsigned long} instead of an SCM object. +@end deftypefun + + +@heading Procedures + +@c @deftypefun SCM gh_make_subr (SCM (*@var{fn})(), int @var{req}, int @var{opt}, int @var{restp}, char *@var{sym}) +@c Make the C function @var{fn} available to Scheme programs. The function +@c will be bound to the symbol @var{sym}. The arguments @var{req}, +@c @var{opt} and @var{restp} describe @var{fn}'s calling conventions. The +@c function must take @var{req} required arguments and may take @var{opt} +@c optional arguments. Any optional arguments which are not supplied by +@c the caller will be bound to @var{SCM_UNSPECIFIED}. If @var{restp} is +@c non-zero, it means that @var{fn} may be called with an arbitrary number +@c of arguments, and that any extra arguments supplied by the caller will +@c be passed to @var{fn} as a list. The @var{restp} argument is exactly +@c like Scheme's @code{(lambda (arg1 arg2 . arglist))} calling convention. +@c +@c For example, the procedure @code{read-line}, which takes optional +@c @var{port} and @var{handle-delim} arguments, would be declared like so: +@c +@c @example +@c SCM scm_read_line (SCM port, SCM handle_delim); +@c gh_make_subr (scm_read_line, 0, 2, 0, "read-line"); +@c @end example +@c +@c The @var{req} argument to @code{gh_make_subr} is 0 to indicate that +@c there are no required arguments, so @code{read-line} may be called +@c without any arguments at all. The @var{opt} argument is 2, to indicate +@c that both the @var{port} and @var{handle_delim} arguments to +@c @code{scm_read_line} are optional, and will be bound to +@c @code{SCM_UNSPECIFIED} if the calling program does not supply them. +@c Because the @var{restp} argument is 0, this function may not be called +@c with more than two arguments. +@c @end deftypefun + +@deftypefun SCM gh_apply (SCM proc, SCM args) +Call the Scheme procedure @var{proc}, with the elements of @var{args} as +arguments. @var{args} must be a proper list. +@end deftypefun + +@deftypefun SCM gh_call0 (SCM proc) +@deftypefunx SCM gh_call1 (SCM proc, SCM arg) +@deftypefunx SCM gh_call2 (SCM proc, SCM arg1, SCM arg2) +@deftypefunx SCM gh_call3 (SCM proc, SCM arg1, SCM arg2, SCM arg3) +Call the Scheme procedure @var{proc} with no arguments +(@code{gh_call0}), one argument (@code{gh_call1}), and so on. You can +get the same effect by wrapping the arguments up into a list, and +calling @code{gh_apply}; Guile provides these functions for convenience. +@end deftypefun + + +@deftypefun SCM gh_catch (SCM key, SCM thunk, SCM handler) +@deftypefunx SCM gh_throw (SCM key, SCM args) +Corresponds to the Scheme @code{catch} and @code{throw} procedures, +which in Guile are provided as primitives. +@end deftypefun + +@c [FIXME: must add the I/O section in gscm.h] + +@deftypefun SCM gh_is_eq (SCM a, SCM b) +@deftypefunx SCM gh_is_eqv (SCM a, SCM b) +@deftypefunx SCM gh_is_equal (SCM a, SCM b) +These correspond to the Scheme @code{eq?}, @code{eqv?} and @code{equal?} +predicates. +@end deftypefun + +@deftypefun int gh_obj_length (SCM @var{obj}) +Returns the raw object length. +@end deftypefun + +@heading Data lookup + +For now I just include Tim Pierce's comments from the @file{gh_data.c} +file; it should be organized into a documentation of the two functions +here. + +@smallexample +/* Data lookups between C and Scheme + + Look up a symbol with a given name, and return the object to which + it is bound. gh_lookup examines the Guile top level, and + gh_module_lookup checks the module namespace specified by the + `vec' argument. + + The return value is the Scheme object to which SNAME is bound, or + SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME: + should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be + bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference? + -twp] */ +@end smallexample + + +@node Mixing gh and scm APIs +@section Mixing gh and scm APIs + + +@node scm transition summary +@section Transitioning to the scm Interface + +The following table summarizes the available information on how to +transition from the GH to the scm interface. Where transitioning is not +completely straightforward, the table includes a reference to more +detailed documentation in the preceding sections. + +@table @asis +@item Header file +Use @code{#include <libguile.h>} instead of @code{#include +<guile/gh.h>}. + +@item Compiling and Linking +Use @code{guile-config} to pick up the flags required to compile C or +C++ code that uses @code{libguile}, like so + +@smallexample +$(CC) -o prog.o -c prog.c `guile-config compile` +@end smallexample + +If you are using libtool to link your executables, just use +@code{-lguile} in your link command. Libtool will expand this into +the needed linker options automatically. If you are not using +libtool, use the @code{guile-config} program to query the needed +options explicitely. A linker command like + +@smallexample +$(CC) -o prog prog.o `guile-config link` +@end smallexample + +should be all that is needed. To link shared libraries that will be +used as Guile Extensions, use libtool to control both the compilation +and the link stage. + +@item The @code{SCM} type +No change: the scm interface also uses this type to represent an +arbitrary Scheme value. + +@item @code{SCM_BOOL_F} and @code{SCM_BOOL_T} +No change. + +@item @code{SCM_UNSPECIFIED} and @code{SCM_UNDEFINED} +No change. + +@item @code{gh_enter} +Use @code{scm_boot_guile} instead, but note that @code{scm_boot_guile} +has a slightly different calling convention from @code{gh_enter}: +@code{scm_boot_guile}, and the main program function that you specify +for @code{scm_boot_guile} to call, both take an additional @var{closure} +parameter. @ref{Guile Initialization Functions} for more details. + +@item @code{gh_repl} +Use @code{scm_shell} instead. + +@item @code{gh_init} +Use @code{scm_init_guile} instead. + +@item @code{gh_eval_str} +Use @code{scm_c_eval_string} instead. + +@item @code{gh_eval_file} or @code{gh_load} +Use @code{scm_c_primitive_load} instead. + +@item @code{gh_new_procedure} +Use @code{scm_c_define_gsubr} instead, but note that the arguments are +in a different order: for @code{scm_c_define_gsubr} the C function +pointer is the last argument. @ref{A Sample Guile Extension} for an +example. + +@item @code{gh_defer_ints} and @code{gh_allow_ints} +Use @code{SCM_DEFER_INTS} and @code{SCM_ALLOW_INTS} instead. Note that +these macros are used without parentheses, as in @code{SCM_DEFER_INTS;}. + +@item @code{gh_bool2scm} +Use @code{SCM_BOOL} instead. + +@item @code{gh_ulong2scm} +Use @code{scm_ulong2num} instead. + +@item @code{gh_long2scm} +Use @code{scm_long2num} instead. + +@item @code{gh_double2scm} +Use @code{scm_make_real} instead. + +@item @code{gh_char2scm} +Use @code{SCM_MAKE_CHAR} instead. + +@item @code{gh_str2scm} +Use @code{scm_mem2string} instead. + +@item @code{gh_str02scm} +Use @code{scm_makfrom0str} instead. + +@item @code{gh_set_substr} +No direct scm equivalent. [FIXME] + +@item @code{gh_symbol2scm} +Use @code{scm_str2symbol} instead. [FIXME: inconsistent naming, +should be @code{scm_str02symbol}.] + +@item @code{gh_ints2scm} and @code{gh_doubles2scm} +No direct scm equivalent. [FIXME] + +@item @code{gh_chars2byvect} and @code{gh_shorts2svect} +No direct scm equivalent. [FIXME] + +@item @code{gh_longs2ivect} and @code{gh_ulongs2uvect} +No direct scm equivalent. [FIXME] + +@item @code{gh_floats2fvect} and @code{gh_doubles2dvect} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2bool} +Use @code{SCM_NFALSEP} instead. + +@item @code{gh_scm2int} +Replace @code{gh_scm2int (@var{obj})} by +@example +scm_num2int (@var{obj}, SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2ulong} +Replace @code{gh_scm2ulong (@var{obj})} by +@example +scm_num2ulong (@var{obj}, SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2long} +Replace @code{gh_scm2long (@var{obj})} by +@example +scm_num2long (@var{obj}, SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2double} +Replace @code{gh_scm2double (@var{obj})} by +@example +scm_num2dbl (@var{obj}, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_scm2char} +Use the @code{SCM_CHAR} macro instead, but note that @code{SCM_CHAR} +does not check that its argument is actually a character. To check that +a @code{SCM} value is a character before using @code{SCM_CHAR} to +extract the character value, use the @code{SCM_VALIDATE_CHAR} macro. + +@item @code{gh_scm2newstr} +No direct scm equivalent. [FIXME] + +@item @code{gh_get_substr} +No direct scm equivalent. [FIXME] + +@item @code{gh_symbol2newstr} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2chars} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2shorts} and @code{gh_scm2longs} +No direct scm equivalent. [FIXME] + +@item @code{gh_scm2floats} and @code{gh_scm2doubles} +No direct scm equivalent. [FIXME] + +@item @code{gh_boolean_p} +Use the @code{SCM_BOOLP} macro instead, or replace @code{gh_boolean_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_boolean_p (@var{obj})) +@end example + +@item @code{gh_symbol_p} +Use the @code{SCM_SYMBOLP} macro instead, or replace @code{gh_symbol_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_symbol_p (@var{obj})) +@end example + +@item @code{gh_char_p} +Use the @code{SCM_CHARP} macro instead, or replace @code{gh_char_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_char_p (@var{obj})) +@end example + +@item @code{gh_vector_p} +Use the @code{SCM_VECTORP} macro instead, or replace @code{gh_vector_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_vector_p (@var{obj})) +@end example + +@item @code{gh_pair_p} +Use the @code{SCM_CONSP} macro instead, or replace @code{gh_pair_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_pair_p (@var{obj})) +@end example + +@item @code{gh_number_p} +Use the @code{SCM_NUMBERP} macro instead, or replace @code{gh_number_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_number_p (@var{obj})) +@end example + +@item @code{gh_string_p} +Use the @code{SCM_STRINGP} macro instead, or replace @code{gh_string_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_string_p (@var{obj})) +@end example + +@item @code{gh_procedure_p} +Replace @code{gh_procedure_p (@var{obj})} by +@example +SCM_NFALSEP (scm_procedure_p (@var{obj})) +@end example + +@item @code{gh_list_p} +Replace @code{gh_list_p (@var{obj})} by +@example +SCM_NFALSEP (scm_list_p (@var{obj})) +@end example + +@item @code{gh_inexact_p} +Use the @code{SCM_INEXACTP} macro instead, or replace @code{gh_inexact_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_inexact_p (@var{obj})) +@end example + +@item @code{gh_exact_p} +Replace @code{gh_exact_p (@var{obj})} by +@example +SCM_NFALSEP (scm_exact_p (@var{obj})) +@end example + +@item @code{gh_eq_p} +Use the @code{SCM_EQ_P} macro instead, or replace @code{gh_eq_p +(@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_eq_p (@var{x}, @var{y})) +@end example + +@item @code{gh_eqv_p} +Replace @code{gh_eqv_p (@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_eqv_p (@var{x}, @var{y})) +@end example + +@item @code{gh_equal_p} +Replace @code{gh_equal_p (@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_equal_p (@var{x}, @var{y})) +@end example + +@item @code{gh_string_equal_p} +Replace @code{gh_string_equal_p (@var{x}, @var{y})} by +@example +SCM_NFALSEP (scm_string_equal_p (@var{x}, @var{y})) +@end example + +@item @code{gh_null_p} +Use the @code{SCM_NULLP} macro instead, or replace @code{gh_null_p +(@var{obj})} by +@example +SCM_NFALSEP (scm_null_p (@var{obj})) +@end example + +@item @code{gh_cons} +Use @code{scm_cons} instead. + +@item @code{gh_car} and @code{gh_cdr} +Use the @code{SCM_CAR} and @code{SCM_CDR} macros instead. + +@item @code{gh_cxxr} and @code{gh_cxxxr} +(Where each x is either @samp{a} or @samp{d}.) Use the corresponding +@code{SCM_CXXR} or @code{SCM_CXXXR} macro instead. + +@item @code{gh_set_car_x} and @code{gh_set_cdr_x} +Use @code{scm_set_car_x} and @code{scm_set_cdr_x} instead. + +@item @code{gh_list} +Use @code{scm_listify} instead. + +@item @code{gh_length} +Replace @code{gh_length (@var{lst})} by +@example +scm_num2ulong (scm_length (@var{lst}), SCM_ARG1, @var{str}) +@end example +where @var{str} is a C string that describes the context of the call. + +@item @code{gh_append} +Use @code{scm_append} instead. + +@item @code{gh_append2}, @code{gh_append3}, @code{gh_append4} +Replace @code{gh_append@var{N} (@var{l1}, @dots{}, @var{lN})} by +@example +scm_append (scm_listify (@var{l1}, @dots{}, @var{lN}, SCM_UNDEFINED)) +@end example + +@item @code{gh_reverse} +Use @code{scm_reverse} instead. + +@item @code{gh_list_tail} and @code{gh_list_ref} +Use @code{scm_list_tail} and @code{scm_list_ref} instead. + +@item @code{gh_memq}, @code{gh_memv} and @code{gh_member} +Use @code{scm_memq}, @code{scm_memv} and @code{scm_member} instead. + +@item @code{gh_assq}, @code{gh_assv} and @code{gh_assoc} +Use @code{scm_assq}, @code{scm_assv} and @code{scm_assoc} instead. + +@item @code{gh_make_vector} +Use @code{scm_make_vector} instead. + +@item @code{gh_vector} or @code{gh_list_to_vector} +Use @code{scm_vector} instead. + +@item @code{gh_vector_ref} and @code{gh_vector_set_x} +Use @code{scm_vector_ref} and @code{scm_vector_set_x} instead. + +@item @code{gh_vector_length} +Use the @code{SCM_VECTOR_LENGTH} macro instead. + +@item @code{gh_apply} +Use @code{scm_apply} instead, but note that @code{scm_apply} takes an +additional third argument that you should set to @code{SCM_EOL}. + +@end table diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi new file mode 100644 index 000000000..1ba439931 --- /dev/null +++ b/doc/ref/guile.texi @@ -0,0 +1,301 @@ +\input texinfo +@c -*-texinfo-*- +@c %**start of header +@setfilename guile.info +@settitle Guile Reference Manual +@set guile +@c %**end of header + +@c Notes: (distilled from Jim's and Tim's notes, and kept up to date) +@c +@c Remember to use "primitive" whereever appropriate. +@c FIXME: gotta change existing "subr" uses to "Primitive". +@c [JimB:] In my text for the Guile snarfer, I've used the term "subr" +@c to denote a C function made available to the Scheme world as a +@c function. This terminology is weird, but consistent with the +@c function names and also with Emacs Lisp, which I assume takes +@c Maclisp's lead. +@c +@c When adding a new function to the Guile manual, please document +@c it with @deffn as one of `primitive', `procedure', or `syntax'. +@c +@c For a list of Guile primitives that are not yet incorporated into the +@c reference manual, see the file `new-docstrings.texi', which holds all +@c the docstrings snarfed from the libguile C sources for primitives +@c that are not in the reference manual. If you have worked with some +@c of these concepts, implemented them, or just happen to know what they +@c do, please write up a little explanation -- it would be a big help. +@c Alternatively, if you know of a great reason why some of these should +@c *not* go in the manual, please let me know. + +@c Define indices that are used in the Guile Scheme part of the +@c reference manual to group stuff according to whether it is R5RS or a +@c Guile extension. +@defcodeindex rn +@defcodeindex ge + +@include version.texi + +@c @iftex +@c @cropmarks +@c @end iftex + +@dircategory The Algorithmic Language Scheme +@direntry +* Guile Reference: (guile). The Guile reference manual. +@end direntry + +@setchapternewpage off + +@ifinfo +Guile Reference Manual +Copyright (C) 1996 Free Software Foundation @* +Copyright (C) 1997 Free Software Foundation @* +Copyright (C) 2000 Free Software Foundation @* +Copyright (C) 2001 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). +@end ignore + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by the Free Software Foundation. +@end ifinfo + +@titlepage +@sp 10 +@comment The title is printed in a large font. +@title Guile Reference Manual +@subtitle $Id: guile.texi,v 1.1 2001-08-24 09:40:29 ossau Exp $ +@subtitle For use with Guile @value{VERSION} +@include AUTHORS + +@c The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +@vskip 0pt plus 1filll +Copyright @copyright{} 1996 Free Software Foundation + +Copyright @copyright{} 1997 Free Software Foundation + +Copyright @copyright{} 2000 Free Software Foundation + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation approved +by Free Software Foundation. +@end titlepage + +@c @smallbook +@finalout +@headings double + +@c Where to find Guile examples. +@set example-dir doc/examples + +@ifinfo +@node Top, Guile License, (dir), (dir) +@top The Guile Reference Manual + +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 Info file contains edition 1.0 of the reference manual, +corresponding to Guile version @value{VERSION}. +@end ifinfo + +@menu +Preface + +* Guile License:: Conditions for copying and using Guile. +* Manual Layout:: How to read the rest of this manual. +* Manual Conventions:: Conventional terminology. + +Part I: Introduction to Guile + +* What is Guile?:: And what does it do? +* Whirlwind Tour:: An introductory whirlwind tour. +* Reporting Bugs:: Reporting bugs in Guile or this manual. + +Part II: Guile Scheme + +* Scheme Intro:: Introduction to Guile Scheme. +* Basic Ideas:: Basic ideas in Scheme. +* Data Types:: Data types for generic use. +* Procedures and Macros:: Procedures and macros. +* Utility Functions:: General utility functions. +* 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. +* Memory Management:: Memory management and garbage collection. +* Objects:: Low level object orientation support. +* Modules:: Designing reusable code libraries. +* Scheduling:: Threads, mutexes, asyncs and dynamic roots. +* Options and Config:: Runtime options and configuration. +* Translation:: Support for translating other languages. +* Debugging:: Internal debugging interface. +* Deprecated:: Features that are planned to disappear. +* Further Reading:: Where to find out more about Scheme programming. +* R5RS Index:: +* Guile Extensions Index:: + +Part III: Guile Modules + +* SLIB:: Using the SLIB Scheme library. +* POSIX:: POSIX system calls and networking. +* SRFI Support:: Support for various SRFIs. +* Readline Support:: Module for using the readline library. +* Value History:: Maintaining a value history in the REPL. +* Pretty Printing:: Nicely formatting Scheme objects for output. +* Formatted Output:: The @code{format} procedure. +* Expect:: Controlling interactive programs with Guile. +* The Scheme shell (scsh):: + The SCSH compatibility module has been made an + add-on, so maybe it shouldn't be documented here + (though it is nice to have a link from here to the + Guile-scsh manual, if one exists). +@c * Tcl/Tk Interface:: + +Part IV: Guile Scripting + +* Guile Scripting:: How to write Guile scripts. +* Command Line Handling:: Command line options and arguments. + +Part V: Extending Applications Using Guile + +* Libguile Intro:: Using Guile as an extension language. +* Data Representation:: Data representation in Guile. +* Scheme Primitives:: Writing Scheme primitives in C. +* I/O Extensions:: Using and extending ports in C. +* Handling Errors:: How to handle errors in C code. +* GH:: The deprecated GH interface. + +Appendices + +* Obtaining and Installing Guile:: +* Debugger User Interface:: + +Indices + +* Concept Index:: +* Procedure Index:: +* Variable Index:: +* Type Index:: + +@end menu + +@include preface.texi + +@c preliminary +@iftex +@page +@unnumbered{Part I: Introduction to Guile} +@end iftex + +@include intro.texi + +@c programming in Scheme +@iftex +@page +@unnumbered{Part II: Guile Scheme} +@end iftex + +@include scheme-intro.texi +@include scheme-ideas.texi +@include scheme-data.texi +@include scheme-procedures.texi +@include scheme-utility.texi +@include scheme-binding.texi +@include scheme-control.texi +@include scheme-io.texi +@include scheme-evaluation.texi +@include scheme-memory.texi +@include scheme-modules.texi +@include scheme-scheduling.texi +@c object orientation support here +@include scheme-options.texi +@include scheme-translation.texi +@include scheme-debug.texi +@include deprecated.texi +@include scheme-reading.texi +@include scheme-indices.texi + +@c Unix system interface +@iftex +@page +@unnumbered{Part III: Guile Modules} +@end iftex + +@include slib.texi +@include posix.texi +@include srfi-modules.texi +@include repl-modules.texi +@include misc-modules.texi +@include expect.texi +@include scsh.texi +@c @include tcltk.texi + +@c Guile as an scripting language +@iftex +@page +@unnumbered{Part IV: Guile Scripting} +@end iftex + +@include scripts.texi +@include script-getopt.texi + +@c Guile as an extension language +@iftex +@page +@unnumbered{Part V: Extending Applications Using Guile} +@end iftex + +@include extend.texi +@include data-rep.texi +@include scm.texi +@include gh.texi + +@c Appendices +@iftex +@page +@unnumbered{Appendices} +@end iftex + +@include appendices.texi + +@c Indices +@iftex +@page +@unnumbered{Indices} +@end iftex + +@include indices.texi + +@contents + +@bye diff --git a/doc/ref/indices.texi b/doc/ref/indices.texi new file mode 100644 index 000000000..a35592e90 --- /dev/null +++ b/doc/ref/indices.texi @@ -0,0 +1,54 @@ +@node Concept Index +@unnumbered Concept Index + +This index contains concepts, keywords and non-Schemey names for several +features, to make it easier to locate the desired sections. + +@printindex cp + + +@page +@node Procedure Index +@unnumbered Procedure Index + +@c FIXME::martin: Review me! + +This is an alphabetical list of all the procedures and macros in Guile. + +When looking for a particular procedure, please look under its Scheme +name as well as under its C name. The C name can be constructed from +the Scheme names by a simple transformation described in the section +@xref{Transforming Scheme name to C name}. + +@printindex fn + + +@page +@node Variable Index +@unnumbered Variable Index + +@c FIXME::martin: Review me! + +This is an alphabetical list of all the important variables and +constants in Guile. + +When looking for a particular variable or constant, please look under +its Scheme name as well as under its C name. The C name can be +constructed from the Scheme names by a simple transformation described +in the section @xref{Transforming Scheme name to C name}. + +@printindex vr + + +@page +@c Spell out this node fully, because it is the last real node +@c in the top-level menu. Leaving off the pointers here causes +@c spurious makeinfo errors. +@node Type Index +@unnumbered Type Index + +This is an alphabetical list of all the important data types defined in +the Guile Programmers Manual. + +@printindex tp + diff --git a/doc/ref/intro.texi b/doc/ref/intro.texi new file mode 100644 index 000000000..28e30d06b --- /dev/null +++ b/doc/ref/intro.texi @@ -0,0 +1,1023 @@ +@c $Id: intro.texi,v 1.1 2001-08-24 09:40:29 ossau Exp $ + +@page +@node What is Guile? +@chapter What is Guile? + +Guile is an interpreter for the Scheme programming language, packaged +for use in a wide variety of environments. Guile implements Scheme as +described in the +@tex +Revised$^5$ +@end tex +@ifinfo +Revised^5 +@end ifinfo +Report on the Algorithmic Language Scheme (usually known as R5RS), +providing clean and general data and control structures. Guile goes +beyond the rather austere language presented in R5RS, extending it with +a module system, full access to POSIX system calls, networking support, +multiple threads, dynamic linking, a foreign function call interface, +powerful string processing, and many other features needed for +programming in the real world. + +Like a shell, Guile can run interactively, reading expressions from the +user, evaluating them, and displaying the results, or as a script +interpreter, reading and executing Scheme code from a file. However, +Guile is also packaged as an object library, allowing other applications +to easily incorporate a complete Scheme interpreter. An application can +use Guile as an extension language, a clean and powerful configuration +language, or as multi-purpose ``glue'', connecting primitives provided +by the application. It is easy to call Scheme code from C code and vice +versa, giving the application designer full control of how and when to +invoke the interpreter. Applications can add new functions, data types, +control structures, and even syntax to Guile, creating a domain-specific +language tailored to the task at hand, but based on a robust language +design. + +Guile's module system allows one to break up a large program into +manageable sections with well-defined interfaces between them. Modules +may contain a mixture of interpreted and compiled code; Guile can use +either static or dynamic linking to incorporate compiled code. Modules +also encourage developers to package up useful collections of routines +for general distribution; as of this writing, one can find Emacs +interfaces, database access routines, compilers, GUI toolkit interfaces, +and HTTP client functions, among others. + +In the future, we hope to expand Guile to support other languages like +Tcl and Perl by translating them to Scheme code. This means that users +can program applications which use Guile in the language of their +choice, rather than having the tastes of the application's author +imposed on them. + +@page +@node Whirlwind Tour +@chapter A Whirlwind Tour + +This chapter presents a quick tour of all the ways that Guile can be +used. + +@menu +* Running Guile Interactively:: +* Guile Scripts:: +* Linking Programs With Guile:: +* Writing Extensions for Guile:: +* Guile Modules:: +@end menu + + +@node Running Guile Interactively +@section Running Guile Interactively + +In its simplest form, Guile acts as an interactive interpreter for the +Scheme programming language, reading and evaluating Scheme expressions +the user enters from the terminal. Here is a sample interaction between +Guile and a user; the user's input appears after the @code{$} and +@code{guile>} prompts: + +@example +$ guile +guile> (+ 1 2 3) ; add some numbers +6 +guile> (define (factorial n) ; define a function + (if (zero? n) 1 (* n (factorial (- n 1))))) +guile> (factorial 20) +2432902008176640000 +guile> (getpwnam "jimb") ; find my entry in /etc/passwd +#("jimb" ".0krIpK2VqNbU" 4008 10 "Jim Blandy" "/u/jimb" + "/usr/local/bin/bash") +guile> @kbd{C-d} +$ +@end example + +@c [[When we get a fancier read-eval-print loop, with features for bouncing +@c around among modules, referring to the value of the last expression, +@c etc. then this section will get longer.]] + + +@node Guile Scripts +@section Guile Scripts + +Like AWK, Perl, or any shell, Guile can interpret script files. A Guile +script is simply a file of Scheme code with some extra information at +the beginning which tells the operating system how to invoke Guile, and +then tells Guile how to handle the Scheme code. + +Before we present the details, here is a trivial Guile script: + +@example +#!/usr/local/bin/guile -s +!# +(display "Hello, world!") +(newline) +@end example + +@menu +* The Top of a Script File:: How to start a Guile script. +* Scripting Examples:: Simple Guile scripts, explained. +@end menu + + +@node The Top of a Script File +@subsection The Top of a Script File + +The first line of a Guile script must tell the operating system to use +Guile to evaluate the script, and then tell Guile how to go about doing +that. Here is the simplest case: + +@itemize @bullet + +@item +The first two characters of the file must be @samp{#!}. + +The operating system interprets this to mean that the rest of the line +is the name of an executable that can interpret the script. Guile, +however, interprets these characters as the beginning of a multi-line +comment, terminated by the characters @samp{!#} on a line by themselves. +(This is an extension to the syntax described in R5RS, added to support +shell scripts.) + +@item +Immediately after those two characters must come the full pathname to +the Guile interpreter. On most systems, this would be +@samp{/usr/local/bin/guile}. + +@item +Then must come a space, followed by a command-line argument to pass to +Guile; this should be @samp{-s}. This switch tells Guile to run a +script, instead of soliciting the user for input from the terminal. +There are more elaborate things one can do here; see @ref{The Meta +Switch}. + +@item +Follow this with a newline. + +@item +The second line of the script should contain only the characters +@samp{!#} --- just like the top of the file, but reversed. The +operating system never reads this far, but Guile treats this as the end +of the comment begun on the first line by the @samp{#!} characters. + +@item +The rest of the file should be a Scheme program. + +@end itemize + +Guile reads the program, evaluating expressions in the order that they +appear. Upon reaching the end of the file, Guile exits. + +The function @code{command-line} returns the name of the script file and +any command-line arguments passed by the user, as a list of strings. + +For example, consider the following script file: +@example +#!/usr/local/bin/guile -s +!# +(write (command-line)) +(newline) +@end example + +If you put that text in a file called @file{foo} in the current +directory, then you could make it executable and try it out like this: +@example +$ chmod a+x foo +$ ./foo +("./foo") +$ ./foo bar baz +("./foo" "bar" "baz") +$ +@end example + +As another example, here is a simple replacement for the POSIX +@code{echo} command: +@example +#!/usr/local/bin/guile -s +!# +(for-each (lambda (s) (display s) (display " ")) + (cdr (command-line))) +(newline) +@end example + +@deffn procedure command-line +@deffnx primitive program-arguments +Return a list of the command-line arguments passed to the currently +running program. If the program invoked Guile with the @samp{-s}, +@samp{-c} or @samp{--} switches, these procedures ignore everything up +to and including those switches. +@end deffn + + +@node Scripting Examples +@subsection Scripting Examples + +To start with, here are some examples of invoking Guile directly: + +@table @code + +@item guile -- a b c +Run Guile interactively; @code{(command-line)} will return @* +@code{("/usr/local/bin/guile" "a" "b" "c")}. + +@item guile -s /u/jimb/ex2 a b c +Load the file @file{/u/jimb/ex2}; @code{(command-line)} will return @* +@code{("/u/jimb/ex2" "a" "b" "c")}. + +@item guile -c '(write %load-path) (newline)' +Write the value of the variable @code{%load-path}, print a newline, +and exit. + +@item guile -e main -s /u/jimb/ex4 foo +Load the file @file{/u/jimb/ex4}, and then call the function +@code{main}, passing it the list @code{("/u/jimb/ex4" "foo")}. + +@item guile -l first -ds -l last -s script +Load the files @file{first}, @file{script}, and @file{last}, in that +order. The @code{-ds} switch says when to process the @code{-s} +switch. For a more motivated example, see the scripts below. + +@end table + + +Here is a very simple Guile script: +@example +#!/usr/local/bin/guile -s +!# +(display "Hello, world!") +(newline) +@end example +The first line marks the file as a Guile script. When the user invokes +it, the system runs @file{/usr/local/bin/guile} to interpret the script, +passing @code{-s}, the script's filename, and any arguments given to the +script as command-line arguments. When Guile sees @code{-s +@var{script}}, it loads @var{script}. Thus, running this program +produces the output: +@example +Hello, world! +@end example + +Here is a script which prints the factorial of its argument: +@example +#!/usr/local/bin/guile -s +!# +(define (fact n) + (if (zero? n) 1 + (* n (fact (- n 1))))) + +(display (fact (string->number (cadr (command-line))))) +(newline) +@end example +In action: +@example +$ fact 5 +120 +$ +@end example + +However, suppose we want to use the definition of @code{fact} in this +file from another script. We can't simply @code{load} the script file, +and then use @code{fact}'s definition, because the script will try to +compute and display a factorial when we load it. To avoid this problem, +we might write the script this way: + +@example +#!/usr/local/bin/guile \ +-e main -s +!# +(define (fact n) + (if (zero? n) 1 + (* n (fact (- n 1))))) + +(define (main args) + (display (fact (string->number (cadr args)))) + (newline)) +@end example +This version packages the actions the script should perform in a +function, @code{main}. This allows us to load the file purely for its +definitions, without any extraneous computation taking place. Then we +used the meta switch @code{\} and the entry point switch @code{-e} to +tell Guile to call @code{main} after loading the script. +@example +$ fact 50 +30414093201713378043612608166064768844377641568960512000000000000 +@end example + +Suppose that we now want to write a script which computes the +@code{choose} function: given a set of @var{m} distinct objects, +@code{(choose @var{n} @var{m})} is the number of distinct subsets +containing @var{n} objects each. It's easy to write @code{choose} given +@code{fact}, so we might write the script this way: +@example +#!/usr/local/bin/guile \ +-l fact -e main -s +!# +(define (choose n m) + (/ (fact m) (* (fact (- m n)) (fact n)))) + +(define (main args) + (let ((n (string->number (cadr args))) + (m (string->number (caddr args)))) + (display (choose n m)) + (newline))) +@end example + +The command-line arguments here tell Guile to first load the file +@file{fact}, and then run the script, with @code{main} as the entry +point. In other words, the @code{choose} script can use definitions +made in the @code{fact} script. Here are some sample runs: +@example +$ choose 0 4 +1 +$ choose 1 4 +4 +$ choose 2 4 +6 +$ choose 3 4 +4 +$ choose 4 4 +1 +$ choose 50 100 +100891344545564193334812497256 +@end example + + +@node Linking Programs With Guile +@section Linking Programs With Guile + +The Guile interpreter is available as an object library, to be linked +into applications using Scheme as a configuration or extension +language. This chapter covers the mechanics of linking your program +with Guile on a typical POSIX system. + +Parts III and IV of this manual describe the C functions Guile provides. +Furthermore, any Scheme function described in this manual as a +``Primitive'' is also callable from C; see @ref{Scheme Primitives}. + +The header file @code{<libguile.h>} provides declarations for all of +Guile's functions and constants. You should @code{#include} it at the +head of any C source file that uses identifiers described in this +manual. Once you've compiled your source files, you need to link them +against the Guile object code library, @code{libguile}. + +On most systems, you should not need to do tell the compiler and linker +explicitely where they can find @file{libguile.h} and @file{libguile}. +When Guile has been installed in a peculiar way, or when you are on a +peculiar system, things might not be so easy and you might need to pass +additional @code{-I} or @code{-L} options to the compiler. Guile +provides the utility program @code{guile-config} to help you find the +right values for these options. You would typically run +@code{guile-config} during the configuration phase of your program and +use the obtained information in the Makefile. + +@menu +* Guile Initialization Functions:: What to call first. +* A Sample Guile Main Program:: Sources and makefiles. +@end menu + + +@node Guile Initialization Functions +@subsection Guile Initialization Functions + +To initialize Guile, you can use one of two functions. The first, +@code{scm_boot_guile}, is the most portable way to initialize Guile. It +should be used whenever you have control over the main function of your +program because it never returns. The second function, +@code{scm_init_guile}, does return and can thus be used in more +situations. However, @code{scm_init_guile} is not as widely available +as @code{scm_boot_guile} because it needs to rely on non-portable code +to find the stack bounds. When Guile does not know how to find these +bounds on your system, it will not provide @code{scm_init_guile}. + +When you can tolerate the limits of @code{scm_boot_guile}, you should +use it in favor of @code{scm_init_guile} since that will make your +program more portable. + +@deftypefun void scm_boot_guile (int @var{argc}, char **@var{argv}, void (*@var{main_func}) (), void *@var{closure}) +Initialize the Guile Scheme interpreter. Then call @var{main_func}, +passing it @var{closure}, @var{argc}, and @var{argv}. @var{main_func} +should do all the work of the program (initializing other packages, +defining application-specific functions, reading user input, and so on) +before returning. When @var{main_func} returns, call @code{exit (0)}; +@code{scm_boot_guile} never returns. If you want some other exit value, +have @var{main_func} call exit itself. + +@code{scm_boot_guile} arranges for the Scheme @code{command-line} +function to return the strings given by @var{argc} and @var{argv}. If +@var{main_func} modifies @var{argc} or @var{argv}, it should call +@code{scm_set_program_arguments} with the final list, so Scheme code +will know which arguments have been processed. + +Why must the caller do all the real work from @var{main_func}? Guile's +garbage collector scans the stack to find all local variables that +reference Scheme objects. To do this, it needs to know the bounds of +the stack that might contain such references. Because there is no +protable way in C to find the base of the stack, @code{scm_boot_guile} +assumes that all references are above its own stack frame. If you try +to manipulate Scheme objects after this function returns, it's the luck +of the draw whether Guile's storage manager will be able to find the +objects you allocate. So, @code{scm_boot_guile} function exits, rather +than returning, to discourage you from making that mistake. + +See @code{scm_init_guile}, below, for a function that can find the real +base of the stack, but not in a portable way. +@end deftypefun + +@deftypefun void scm_init_guile () +Initialize the Guile Scheme interpreter. + +In contrast to @code{scm_boot_guile}, this function knows how to find +the true base of the stack and thus does not need to usurp the control +flow of your program. However, since finding the stack base can not be +done portably, this function might not be available in all installations +of Guile. If you can, you should use @code{scm_boot_guile} instead. + +Note that @code{scm_init_guile} does not inform Guile about the command +line arguments that should be returned by the Scheme function +@code{comamnd-line}. You can use @code{scm_set_program_arguments} to do +this. +@end deftypefun + +One common way to use Guile is to write a set of C functions which +perform some useful task, make them callable from Scheme, and then link +the program with Guile. This yields a Scheme interpreter just like +@code{guile}, but augmented with extra functions for some specific +application --- a special-purpose scripting language. + +In this situation, the application should probably process its +command-line arguments in the same manner as the stock Guile +interpreter. To make that straightforward, Guile provides this +function: + +@deftypefun void scm_shell (int @var{argc}, char **@var{argv}) +Process command-line arguments in the manner of the @code{guile} +executable. This includes loading the normal Guile initialization +files, interacting with the user or running any scripts or expressions +specified by @code{-s} or @code{-e} options, and then exiting. +@xref{Invoking Guile}, for more details. + +Since this function does not return, you must do all +application-specific initialization before calling this function. +@end deftypefun + + +@node A Sample Guile Main Program +@subsection A Sample Guile Main Program + +Here is @file{simple-guile.c}, source code for a @code{main} and an +@code{inner_main} function that will produce a complete Guile +interpreter. + +@example +/* simple-guile.c --- how to start up the Guile + interpreter from C code. */ + +/* Get declarations for all the scm_ functions. */ +#include <libguile.h> + +static void +inner_main (void *closure, int argc, char **argv) +@{ + /* module initializations would go here */ + scm_shell (argc, argv); +@} + +int +main (int argc, char **argv) +@{ + scm_boot_guile (argc, argv, inner_main, 0); + return 0; /* never reached */ +@} +@end example + +The @code{main} function calls @code{scm_boot_guile} to initialize +Guile, passing it @code{inner_main}. Once @code{scm_boot_guile} is +ready, it invokes @code{inner_main}, which calls @code{scm_shell} to +process the command-line arguments in the usual way. + +Here is a Makefile which you can use to compile the above program. It +uses @code{guile-config} to learn about the necessary compiler and +linker flags. +@example +# Use GCC, if you have it installed. +CC=gcc + +# Tell the C compiler where to find <libguile.h> +CFLAGS=`guile-config compile` + +# Tell the linker what libraries to use and where to find them. +LIBS=`guile-config link` + +simple-guile: simple-guile.o + $@{CC@} simple-guile.o $@{LIBS@} -o simple-guile + +simple-guile.o: simple-guile.c + $@{CC@} -c $@{CFLAGS@} simple-guile.c +@end example + +If you are using the GNU Autoconf package to make your application more +portable, Autoconf will settle many of the details in the Makefile above +automatically, making it much simpler and more portable; we recommend +using Autoconf with Guile. Guile also provides the @code{GUILE_FLAGS} +macro for autoconf that performs all necessary checks. Here is a +@file{configure.in} file for @code{simple-guile} that uses this macro. +Autoconf can use as this file as template to generate a @code{configure} +script. In order for Autoconf to find the @code{GUILE_FLAGS} macro, you +will need to run @code{aclocal} first. This is not really Guile +specific, so you should refer to the Autoconf documentation REFFIXME +when in doubt. +@example +AC_INIT(simple-guile.c) + +# Find a C compiler. +AC_PROG_CC + +# Check for Guile +GUILE_FLAGS + +# Generate a Makefile, based on the results. +AC_OUTPUT(Makefile) +@end example + +Here is a @code{Makefile.in} template, from which the @code{configure} +script produces a Makefile customized for the host system: +@example +# The configure script fills in these values. +CC=@@CC@@ +CFLAGS=@@GUILE_CFLAGS@@ +LIBS=@@GUILE_LDFLAGS@@ + +simple-guile: simple-guile.o + $@{CC@} simple-guile.o $@{LIBS@} -o simple-guile +simple-guile.o: simple-guile.c + $@{CC@} -c $@{CFLAGS@} simple-guile.c +@end example + +The developer should use Autoconf to generate the @file{configure} +script from the @file{configure.in} template, and distribute +@file{configure} with the application. Here's how a user might go about +building the application: + +@example +$ ls +Makefile.in configure* configure.in simple-guile.c +$ ./configure +creating cache ./config.cache +checking for gcc... (cached) gcc +checking whether the C compiler (gcc ) works... yes +checking whether the C compiler (gcc ) is a cross-compiler... no +checking whether we are using GNU C... (cached) yes +checking whether gcc accepts -g... (cached) yes +checking for Guile... yes +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 +$ ./simple-guile +guile> (+ 1 2 3) +6 +guile> (getpwnam "jimb") +#("jimb" "83Z7d75W2tyJQ" 4008 10 "Jim Blandy" "/u/jimb" + "/usr/local/bin/bash") +guile> (exit) +$ +@end example + +@node Writing Extensions for Guile +@section Writing Extensions for Guile + +The previous sections have briefly explained how to write programs that +make use of an embedded Guile interpreter. But sometimes, all you want +to do is make new primitive procedures and data types available to the +Scheme programmer. Writing a new version of @code{guile} is +inconvenient in this case and it would in fact make the life of the +users of your new features needlessly hard. + +@c [[ the following is probably a bit longwinded ]] + +For example, suppose that there is a program @code{guile-db} that is a +version of Guile with additional features for accessing a database. +People who want to write Scheme programs that use these features would +have to use @code{guile-db} instead of the usual @code{guile} program. +Now suppose that there is also a program @code{guile-gtk} that extends +Guile with access to the popular Gtk+ toolkit for graphical user +interfaces. People who want to write GUIs in Scheme would have to use +@code{guile-gtk}. Now, what happens when you want to write a Scheme +application that uses a GUI to let the user accessa a database? You +would have to write a @emph{third} program that incorporates both the +database stuff and the GUI stuff. This might not be easy (because +@code{guile-gtk} might be a quite obscure program, say) and taking this +example further makes it easy to see that this approach can not work in +practice. + +It would have been much better if both the database features and the GUI +feature had been provided as libraries that can just be linked with +@code{guile}. Guile makes it easy to do just this, and we encourage you +to make your extensions to Guile available as libraries whenever +possible. + +You write the new primitive procedures and data types in the normal +fashion, and link them into a shared library instead of into a +standalone program. The shared library can then be loaded dynamically +by Guile. + +@menu +* A Sample Guile Extension:: +@end menu + +@node A Sample Guile Extension +@subsection A Sample Guile Extension + +This section explains how to make the Bessel functions of the C library +available to Scheme. First we need to write the appropriate glue code +to convert the arguments and return values of the functions from Scheme +to C and back. Additionally, we need a function that will add them to +the set of Guile primitives. Because this is just an example, we will +only implement this for the @code{j0} function, tho. + +Consider the following file @file{bessel.c}. + +@smallexample +#include <math.h> +#include <libguile.h> + +SCM +j0_wrapper (SCM x) +@{ + return scm_make_real (j0 (scm_num2dbl (x, "j0"))); +@} + +void +init_bessel () +@{ + scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper); +@} +@end smallexample + +This C source file needs to be compiled into a shared library. Here is +how to do it on GNU/Linux: + +@smallexample +gcc -shared -o libguile-bessel.so -fPIC bessel.c +@end smallexample + +For creating shared libraries portably, we recommend the use of +@code{GNU Libtool}. + +A shared library can be loaded into a running Guile process with the +function @code{load-extension}. In addition to the name of the +library to load, this function also expects the name of function from +that library that will be called to initialize it. For our example, +we are going to call the function @code{init_bessel} which will make +@code{j0_wrapper} available to Scheme programs with the name +@code{j0}. Note that we do not specify a filename extension such as +@file{.so} when invoking @code{load-extension}. The right extension for +the host platform will be provided automatically. + +@smalllisp +(load-extension "libguile-bessel" "init_bessel") +(j0 2) +@result{} 0.223890779141236 +@end smalllisp + +For this to work, @code{load-extension} must be able to find +@file{libguile-bessel}, of course. It will look in the places that +are usual for your operating system, and it will additionally look +into the directories listed in the @code{LTDL_LIBRRAY_PATH} +environment variable. + +To see how these Guile extensions via shared libraries relate to the +module system, see below @xref{Intro to Modules and Extensions}. + +@node Guile Modules +@section Guile Modules + +Guile has support for dividing a program into @dfn{modules}. By using +modules, you can group related code together and manage the +composition of complete programs from largely independent parts. + +(Although the module system implementation is in flux, feel free to use it +anyway. Guile will provide reasonable backwards compatability.) + +Details on the module system beyond this introductory material can be found in +@xref{Modules}. + + +@menu +* Intro to Using Guile Modules:: +* Intro to Writing New Modules:: +* Intro to Modules and Extensions:: +@end menu + +@node Intro to Using Guile Modules +@subsection Intro to Using Existing Modules + +Guile comes with a lot of useful modules, for example for string +processing or command line parsing. Additionally, there exist many +Guile modules written by other Guile hackers, but which have to be +installed manually. + +Existing modules have to be placed in places where Guile looks for them +by default or in colon-separated directories in the environment variable +@code{GUILE_LOAD_PATH}. When this variable is set, those directories +are searched first, then the the default. The following command +shows the complete list of directories searched: + +@smallexample +guile -c '(write %load-path) (newline)' +@end smallexample + +Suppose you want to use the procedures and variables exported by the +module @code{(ice-9 popen)}, which provides the means for communicating +with other processes over pipes. Add the following line to your +currently running Guile REPL or the top of you script file. + +@lisp +(use-modules (ice-9 popen)) +@end lisp + +This will load the module and make the procedures exported by +@code{(ice-9 popen)} automatically available. The next step could be to +open a pipe to @file{ls} and read the contents of the current directory, +one line at a time. + +@lisp +(define p (open-input-pipe "ls -l")) +(read-line p) +@result{} +"total 30" +(read-line p) +@result{} +"drwxr-sr-x 2 mgrabmue mgrabmue 1024 Mar 29 19:57 CVS" +@end lisp + + +@node Intro to Writing New Modules +@subsection Intro to Writing New Modules + +Of course it is possible to write modules yourself. Using modules for +structuring your programs makes them more readable and lets you +distribute them more easily. Also, explicitly defining the procedures +and variables which are exported from a module adds documentation to the +source and specifies the interface a module provides. + +In Guile, you can create new modules and switch to exisiting modules in +order to add bindings to them using the syntactic form +@code{define-module}. + +@lisp +(define-module (foo bar)) + +(define (frob x) x) +@end lisp + +Will create the module @code{(foo bar)}.@footnote{It is only convention +that the module names in this section have two elements. One or more +than two elements are perfectly fine, such as @code{(foo)} or @code{(foo +bar braz)}} All definitions following this statement will add bindings +to the module @code{(foo bar)}, and these bindings will not be visible +outside of the module. To make the bindings accessible to other +modules, you have to export them explicitly using one of the following +means: + +@itemize @bullet +@item +Export them with the @code{export} form: +@lisp +(export frob) +@end lisp + +@item +Include them into the @code{define-module} form with the keyword +@code{export}: +@lisp +(define-module (foo bar) + #:export (frob)) +@end lisp + +@item +Change the definition of @code{frob} to use @code{define-public}, which +is a combination of @code{define} and @code{export}. +@lisp +(define-public (frob x) x) +@end lisp +@end itemize + +After exporting, other modules can access the exported items simply by +using @code{use-modules} to load the module @code{(foo bar)}. + + +@node Intro to Modules and Extensions +@subsection Intro to Modules and Extensions + +In addition to Scheme code you can also put things that are defined in +C into a module. + +You do this by writing a small Scheme file that defines the module. +That Scheme file in turn invokes @code{load-extension} to make the +features defined in C available. This works since all definitions +made by @code{scm_c_define_gsubr} etc. go into the @emph{current +module} and @code{define-module} causes the newly defined module to be +current while the code that follows it is executed. + +Suppose we want to put the Bessel function @code{j0} from the example +extension into a module called @code{(math bessel)}. We would have to +write a Scheme file with this contents + +@smallexample +(define-module (math bessel)) + +(export j0) + +(load-extension "libguile-bessel" "init_bessel") +@end smallexample + +This file should of course be saved in the right place for +autoloading, for example as +@file{/usr/local/share/guile/math/bessel.scm}. + +When @code{init_bessel} is called, the new @code{(math bessel)} module +is the current one. Thus, the call to @code{scm_c_define_gsubr} will +put the new definition for @code{j0} into it, just as we want it. + +The definitions made in the C code are not automatically exported from +a module. You need to explicitely list the ones you want to export in +@code{export} statements or with the @code{:export} option of +@code{define-module}. + +There is also a way to manipulate the module system from C but only +Scheme files can be autoloaded. Thus, we recommend that you define +your modules in Scheme. + +@page +@node Reporting Bugs +@chapter Reporting Bugs + +Any problems with the installation should be reported to +@email{bug-guile@@gnu.org}. + +Whenever you have found a bug in Guile you are encouraged to report it +to the Guile developers, so they can fix it. They may also be able to +suggest workarounds when it is not possible for you to apply the bugfix +or install a new version of Guile yourself. + +Before sending in bug reports, please check with the following list that +you really have found a bug. + +@itemize @bullet +@item +Whenever documentation and actual behaviour differ, you have certainly +found a bug, either in the documentation or in the program. + +@item +When Guile crashes, it is a bug. + +@item +When Guile hangs or takes forever to complete a task, it is a bug. + +@item +When calculations produce wrong results, it is a bug. + +@item +When Guile signals an error for valid Scheme programs, it is a bug. + +@item +When Guile does not signal an error for invalid Scheme programs, it may +be a bug, unless this is explicitly documented. + +@item +When some part of the documentation is not clear and does not make sense +to you even after re-reading the section, it is a bug. +@end itemize + +When you write a bug report, please make sure to include as much of the +information described below in the report. If you can't figure out some +of the items, it is not a problem, but the more information we get, the +more likely we can diagnose and fix the bug. + +@itemize @bullet +@item +The version number of Guile. Without this, we won't know whether there +is any point in looking for the bug in the current version of Guile. + +You can get the version number by invoking the command + +@example +$ guile --version +Guile 1.4.1 +Copyright (c) 1995, 1996, 1997, 2000 Free Software Foundation +Guile may be distributed under the terms of the GNU General Public Licence; +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. +@end example + +@item +The type of machine you are using, and the operating system name and +version number. On GNU systems, you can get it with @file{uname}. + +@example +$ uname -a +Linux tortoise 2.2.17 #1 Thu Dec 21 17:29:05 CET 2000 i586 unknown +@end example + +@item +The operands given to the @file{configure} command when Guile was +installed. It's often useful to augment this with the output of the +command @code{guile-config info}. + +@item +A complete list of any modifications you have made to the Guile source. +(We may not have time to investigate the bug unless it happens in an +unmodified Guile. But if you've made modifications and you don't tell +us, you are sending us on a wild goose chase.) + +Be precise about these changes. A description in English is not +enough---send a context diff for them. + +Adding files of your own, or porting to another machine, is a +modification of the source. + +@item +Details of any other deviations from the standard procedure for +installing Guile. + +@item +The complete text of any source files needed to reproduce the bug. + +If you can tell us a way to cause the problem without loading any source +files, please do so. This makes it much easier to debug. If you do +need files, make sure you arrange for us to see their exact contents. + +@item +The precise Guile invocation command line we need to type to reproduce +the bug. + +@item +A description of what behavior you observe that you believe is +incorrect. For example, "The Guile process gets a fatal signal," or, +"The resulting output is as follows, which I think is wrong." + +Of course, if the bug is that Guile gets a fatal signal, then one can't +miss it. But if the bug is incorrect results, the maintainer might fail +to notice what is wrong. Why leave it to chance? + +If the manifestation of the bug is an Guile error message, it is +important to report the precise text of the error message, and a +backtrace showing how the Scheme program arrived at the error. + +This can be done using the procedure @code{backtrace} in the REPL. + +@item +Check whether any programs you have loaded into Guile, including your +@file{.guile} file, set any variables that may affect the functioning of +Guile. Also, see whether the problem happens in a freshly started Guile +without loading your @file{.guile} file (start Guile with the @code{-q} +switch to prevent loading the init file). If the problem does +@emph{not} occur then, you must report the precise contents of any +programs that you must load into Guile in order to cause the problem to +occur. + +@item +If the problem does depend on an init file or other Lisp programs that +are not part of the standard Guile distribution, then you should make +sure it is not a bug in those programs by complaining to their +maintainers first. After they verify that they are using Guile in a way +that is supposed to work, they should report the bug. + +@item +If you wish to mention something in the Guile source, show the line of +code with a few lines of context. Don't just give a line number. + +The line numbers in the development sources don't match those in your +sources. It would take extra work for the maintainers to determine what +code is in your version at a given line number, and we could not be +certain. + +@item +Additional information from a C debugger such as GDB might enable +someone to find a problem on a machine which he does not have available. +If you don't know how to use GDB, please read the GDB manual---it is not +very long, and using GDB is easy. You can find the GDB distribution, +including the GDB manual in online form, in most of the same places you +can find the Guile distribution. To run Guile under GDB, you should +switch to the @file{libguile} subdirectory in which Guile was compiled, then +do @code{gdb .libs/guile}. +@c fixme: libguile/.libs is for libtool-enabled systems -- what about rest? + +However, you need to think when you collect the additional information +if you want it to show what causes the bug. + +For example, many people send just a backtrace, but that is not very +useful by itself. A simple backtrace with arguments often conveys +little about what is happening inside Guile, because most of the +arguments listed in the backtrace are pointers to Scheme objects. The +numeric values of these pointers have no significance whatever; all that +matters is the contents of the objects they point to (and most of the +contents are themselves pointers). +@end itemize + + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/misc-modules.texi b/doc/ref/misc-modules.texi new file mode 100644 index 000000000..30f821937 --- /dev/null +++ b/doc/ref/misc-modules.texi @@ -0,0 +1,291 @@ +@page +@node Pretty Printing +@chapter Pretty Printing + +@c FIXME::martin: Review me! + +@cindex pretty printing +The module @code{(ice-9 pretty-print)} provides the procedure +@code{pretty-print}, which provides nicely formatted output of Scheme +objects. This is especially useful for deeply nested or complex data +structures, such as lists and vectors. + +The module is loaded by simply saying. + +@lisp +(use-modules (ice-9 pretty-print)) +@end lisp + +This makes the procedure @code{pretty-print} available. As an example +how @code{pretty-print} will format the output, see the following: + +@lisp +(pretty-print '(define (foo) (lambda (x) +(cond ((zero? x) #t) ((negative? x) -x) (else (if (= x 1) 2 (* x x x))))))) +@print{} +(define (foo) + (lambda (x) + (cond ((zero? x) #t) + ((negative? x) -x) + (else (if (= x 1) 2 (* x x x)))))) +@end lisp + +@deffn procedure pretty-print obj [port] +Print the textual representation of the Scheme object @var{obj} to +@var{port}. @var{port} defaults to the current output port, if not +given. +@end deffn + +Beware: Since @code{pretty-print} uses it's own write procedure, it's +output will not be the same as for example the output of @code{write}. +Consider the following example. + +@lisp +(write (lambda (x) x)) +@print{} +#<procedure #f (x)> + +(pretty-print (lambda (x) x)) +@print{} +#[procedure] +@end lisp + +The reason is that @code{pretty-print} does not know as much about +Guile's object types as the builtin procedures. This is particularly +important for smobs, for which a write procedure can be defined and be +used by @code{write}, but not by @code{pretty-print}. + +@page +@node Formatted Output +@chapter Formatted Output + +@c FIXME::martin: Review me! + +@cindex format +@cindex formatted output +Outputting messages or other texts which are composed of literal +strings, variable contents, newlines and other formatting can be +cumbersome, when only the standard procedures like @code{display}, +@code{write} and @code{newline} are available. Additionally, one +often wants to collect the output in strings. With the standard +routines, the user is required to set up a string port, add this port +as a parameter to the output procedure calls and then retrieve the +resulting string from the string port. + +The @code{format} procedure, to be found in module @code{(ice-9 +format)}, can do all this, and even more. If you are a C programmer, +you can think of this procedure as Guile's @code{fprintf}. + +@deffn procedure format destination format-string args @dots{} +The first parameter is the @var{destination}, it determines where the +output of @code{format} will go. + +@table @asis +@item @code{#t} +Send the formatted output to the current output port and return +@code{#t}. + +@item @code{#f} +Return the formatted output as a string. + +@item Any number value +Send the formatted output to the current error port and return +@code{#t}. + +@item A valid output port +Send the formatted output to the port @var{destination} and return +@code{#t}. +@end table + +The second parameter is the format string. It has a similar function +to the format string in calls to @code{printf} or @code{fprintf} in C. +It is output to the specified destination, but all escape sequences +are replaced by the results of formatting the corresponding sequence. + +Note that escape sequences are marked with the character @code{~} +(tilde), and not with a @code{%} (percent sign), as in C. + +The escape sequences in the following table are supported. When there +appears ``corresponding @var{arg}', that means any of the additional +arguments, after dropping all arguments which have been used up by +escape sequences which have been processed earlier. Some of the +format characters (the characters following the tilde) can be prefixed +by @code{:}, @code{@@}, or @code{:@@}, to modify the behaviour of the +format character. How the modified behaviour differs from the default +behaviour is described for every character in the table where +appropriate. + +@table @code +@item ~~ +Output a single @code{~} (tilde) character. + +@item ~% +Output a newline character, thus advancing to the next output line. + +@item ~& +Start a new line, that is, output a newline character if not already +at the statr of a line. + +@item ~_ +Output a single space character. + +@item ~/ +Output a single tabulator character. + +@item ~| +Output a page separator (formfeed) character. + +@item ~t +Advance to the next tabulator position. + +@item ~y +Pretty-print the correspinding @var{arg}. + +@item ~a +Output the corresponding @var{arg} like @code{display}. + +@item ~s +Output the corresponding @var{arg} like @code{write}. + +@item ~d +Output the corresponding @var{arg} as a decimal number. + +@item ~x +Output the corresponding @var{arg} as a hexadecimal number. + +@item ~o +Output the corresponding @var{arg} as an octal number. + +@item ~b +Output the corresponding @var{arg} as a binary number. + +@item ~r +Output the corresponding @var{arg} as a number word, e.g. 10 prints as +@code{ten}. If prefixed with @code{:}, @code{tenth} is printed, if +prefixed with @code{:@@}, roman numbers are printed. + +@item ~f +Output the corresponding @var{arg} as a fixed format floating point +number, such as @code{1.34}. + +@item ~e +Output the corresponding @var{arg} in exponential notation, such as +@code{1.34E+0}. + +@item ~g +%% FIXME::martin: There must be a difference. Does anybody know? +Like @code{~f}. + +@item ~$ +Like @code{~f}, but only with two digits after the decimal point. + +@item ~i +Output the corresponding @var{arg} as a complex number. + +@item ~c +Output the corresponding @var{arg} as a character. If prefixed with +@code{@@}, it is printed like with @code{write}. If prefixed with +@code{:}, control characters are treated specially, for example +@code{#\newline} will be printed as @code{^J}. + +@item ~p +``Plural''. If the corresponding @var{arg} is 1, nothing is printed +(or @code{y} if prefixed with @code{@@} or @code{:@@}), otherwise +@code{s} is printed (or @code{ies} if prefixed with @code{@@} or +@code{:@@}). + +@item ~?, ~k +Take the corresponding argument as a format string, and the following +argument as a list of values. Then format the values with respect to +the format string. + +@item ~! +Flush the output to the output port. + +@item ~#\newline (tilde-newline) +@c FIXME::martin: I don't understand this from the source. +Continuation lines. + +@item ~* +Argument jumping. Navigate in the argument list as specified by the +corresponding argument. If prefixed with @code{:}, jump backwards in +the argument list, if prefixed by @code{:@@}, jump to the parameter +with the absolute index, otherwise jump forward in the argument list. + +@item ~( +Case conversion begin. If prefixed by @code{:}, the following output +string will be capitalized, if prefixed by @code{@@}, the first +character will be capitalized, if prefixed by @code{:@@} it will be +upcased and otherwise it will be downcased. Conversion stops when the +``Case conversion end'' @code{~)}sequence is encountered. + +@item ~) +Case conversion end. Stop any case conversion currently in effect. + +@item ~[ +@c FIXME::martin: I don't understand this from the source. +Conditional begin. + +@item ~; +@c FIXME::martin: I don't understand this from the source. +Conditional separator. + +@item ~] +@c FIXME::martin: I don't understand this from the source. +Conditional end. + +@item ~@{ +@c FIXME::martin: I don't understand this from the source. +Iteration begin. + +@item ~@} +@c FIXME::martin: I don't understand this from the source. +Iteration end. + +@item ~^ +@c FIXME::martin: I don't understand this from the source. +Up and out. + +@item ~' +@c FIXME::martin: I don't understand this from the source. +Character parameter. + +@item ~0 @dots{} ~9, ~-, ~+ +@c FIXME::martin: I don't understand this from the source. +Numeric parameter. + +@item ~v +@c FIXME::martin: I don't understand this from the source. +Variable parameter from next argument. + +@item ~# +Parameter is number of remaining args. The number of the remaining +arguments is prepended to the list of unprocessed arguments. + +@item ~, +@c FIXME::martin: I don't understand this from the source. +Parameter separators. + +@item ~q +Inquiry message. Insert a copyright message into the output. +@end table + +If any type conversions should fail (for example when using an escape +sequence for number output, but the argument is a string), an error +will be signalled. +@end deffn + +You may have noticed that Guile contains a @code{format} procedure +even when the module @code{(ice-9 format)} is not loaded. The default +@code{format} procedure does not support all escape sequences +documented in this chapter, and will signal an error if you try to use +one of them. The reason for providing two versions of @code{format} +is that the full-featured module is fairly large and requires some +time to get loaded. So the Guile maintainers decided not to load the +large version of @code{format} by default, so that the start-up time +of the interpreter is not unnecessarily increased. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/new-docstrings.texi b/doc/ref/new-docstrings.texi new file mode 100644 index 000000000..8bce646e6 --- /dev/null +++ b/doc/ref/new-docstrings.texi @@ -0,0 +1,532 @@ + +@c module (guile) + +@deffn primitive environment? obj +Return @code{#t} if @var{obj} is an environment, or @code{#f} +otherwise. +@end deffn + +@deffn primitive environment-bound? env sym +Return @code{#t} if @var{sym} is bound in @var{env}, or +@code{#f} otherwise. +@end deffn + +@deffn primitive environment-ref env sym +Return the value of the location bound to @var{sym} in +@var{env}. If @var{sym} is unbound in @var{env}, signal an +@code{environment:unbound} error. +@end deffn + +@deffn primitive environment-fold env proc init +Iterate over all the bindings in @var{env}, accumulating some +value. +For each binding in @var{env}, apply @var{proc} to the symbol +bound, its value, and the result from the previous application +of @var{proc}. +Use @var{init} as @var{proc}'s third argument the first time +@var{proc} is applied. +If @var{env} contains no bindings, this function simply returns +@var{init}. +If @var{env} binds the symbol sym1 to the value val1, sym2 to +val2, and so on, then this procedure computes: +@lisp + (proc sym1 val1 + (proc sym2 val2 + ... + (proc symn valn + init))) +@end lisp +Each binding in @var{env} will be processed exactly once. +@code{environment-fold} makes no guarantees about the order in +which the bindings are processed. +Here is a function which, given an environment, constructs an +association list representing that environment's bindings, +using environment-fold: +@lisp + (define (environment->alist env) + (environment-fold env + (lambda (sym val tail) + (cons (cons sym val) tail)) + '())) +@end lisp +@end deffn + +@deffn primitive environment-define env sym val +Bind @var{sym} to a new location containing @var{val} in +@var{env}. If @var{sym} is already bound to another location +in @var{env} and the binding is mutable, that binding is +replaced. The new binding and location are both mutable. The +return value is unspecified. +If @var{sym} is already bound in @var{env}, and the binding is +immutable, signal an @code{environment:immutable-binding} error. +@end deffn + +@deffn primitive environment-undefine env sym +Remove any binding for @var{sym} from @var{env}. If @var{sym} +is unbound in @var{env}, do nothing. The return value is +unspecified. +If @var{sym} is already bound in @var{env}, and the binding is +immutable, signal an @code{environment:immutable-binding} error. +@end deffn + +@deffn primitive environment-set! env sym val +If @var{env} binds @var{sym} to some location, change that +location's value to @var{val}. The return value is +unspecified. +If @var{sym} is not bound in @var{env}, signal an +@code{environment:unbound} error. If @var{env} binds @var{sym} +to an immutable location, signal an +@code{environment:immutable-location} error. +@end deffn + +@deffn primitive environment-cell env sym for_write +Return the value cell which @var{env} binds to @var{sym}, or +@code{#f} if the binding does not live in a value cell. +The argument @var{for-write} indicates whether the caller +intends to modify the variable's value by mutating the value +cell. If the variable is immutable, then +@code{environment-cell} signals an +@code{environment:immutable-location} error. +If @var{sym} is unbound in @var{env}, signal an +@code{environment:unbound} error. +If you use this function, you should consider using +@code{environment-observe}, to be notified when @var{sym} gets +re-bound to a new value cell, or becomes undefined. +@end deffn + +@deffn primitive environment-observe env proc +Whenever @var{env}'s bindings change, apply @var{proc} to +@var{env}. +This function returns an object, token, which you can pass to +@code{environment-unobserve} to remove @var{proc} from the set +of procedures observing @var{env}. The type and value of +token is unspecified. +@end deffn + +@deffn primitive environment-observe-weak env proc +This function is the same as environment-observe, except that +the reference @var{env} retains to @var{proc} is a weak +reference. This means that, if there are no other live, +non-weak references to @var{proc}, it will be +garbage-collected, and dropped from @var{env}'s +list of observing procedures. +@end deffn + +@deffn primitive environment-unobserve token +Cancel the observation request which returned the value +@var{token}. The return value is unspecified. +If a call @code{(environment-observe env proc)} returns +@var{token}, then the call @code{(environment-unobserve token)} +will cause @var{proc} to no longer be called when @var{env}'s +bindings change. +@end deffn + +@deffn primitive make-leaf-environment +Create a new leaf environment, containing no bindings. +All bindings and locations created in the new environment +will be mutable. +@end deffn + +@deffn primitive leaf-environment? object +Return @code{#t} if object is a leaf environment, or @code{#f} +otherwise. +@end deffn + +@deffn primitive make-eval-environment local imported +Return a new environment object eval whose bindings are the +union of the bindings in the environments @var{local} and +@var{imported}, with bindings from @var{local} taking +precedence. Definitions made in eval are placed in @var{local}. +Applying @code{environment-define} or +@code{environment-undefine} to eval has the same effect as +applying the procedure to @var{local}. +Note that eval incorporates @var{local} and @var{imported} by +reference: +If, after creating eval, the program changes the bindings of +@var{local} or @var{imported}, those changes will be visible +in eval. +Since most Scheme evaluation takes place in eval environments, +they transparently cache the bindings received from @var{local} +and @var{imported}. Thus, the first time the program looks up +a symbol in eval, eval may make calls to @var{local} or +@var{imported} to find their bindings, but subsequent +references to that symbol will be as fast as references to +bindings in finite environments. +In typical use, @var{local} will be a finite environment, and +@var{imported} will be an import environment +@end deffn + +@deffn primitive eval-environment? object +Return @code{#t} if object is an eval environment, or @code{#f} +otherwise. +@end deffn + +@deffn primitive eval-environment-local env +Return the local environment of eval environment @var{env}. +@end deffn + +@deffn primitive eval-environment-set-local! env local +Change @var{env}'s local environment to @var{local}. +@end deffn + +@deffn primitive eval-environment-imported env +Return the imported environment of eval environment @var{env}. +@end deffn + +@deffn primitive eval-environment-set-imported! env imported +Change @var{env}'s imported environment to @var{imported}. +@end deffn + +@deffn primitive make-import-environment imports conflict_proc +Return a new environment @var{imp} whose bindings are the union +of the bindings from the environments in @var{imports}; +@var{imports} must be a list of environments. That is, +@var{imp} binds a symbol to a location when some element of +@var{imports} does. +If two different elements of @var{imports} have a binding for +the same symbol, the @var{conflict-proc} is called with the +following parameters: the import environment, the symbol and +the list of the imported environments that bind the symbol. +If the @var{conflict-proc} returns an environment @var{env}, +the conflict is considered as resolved and the binding from +@var{env} is used. If the @var{conflict-proc} returns some +non-environment object, the conflict is considered unresolved +and the symbol is treated as unspecified in the import +environment. +The checking for conflicts may be performed lazily, i. e. at +the moment when a value or binding for a certain symbol is +requested instead of the moment when the environment is +created or the bindings of the imports change. +All bindings in @var{imp} are immutable. If you apply +@code{environment-define} or @code{environment-undefine} to +@var{imp}, Guile will signal an + @code{environment:immutable-binding} error. However, +notice that the set of bindings in @var{imp} may still change, +if one of its imported environments changes. +@end deffn + +@deffn primitive import-environment? object +Return @code{#t} if object is an import environment, or +@code{#f} otherwise. +@end deffn + +@deffn primitive import-environment-imports env +Return the list of environments imported by the import +environment @var{env}. +@end deffn + +@deffn primitive import-environment-set-imports! env imports +Change @var{env}'s list of imported environments to +@var{imports}, and check for conflicts. +@end deffn + +@deffn primitive make-export-environment private signature +Return a new environment @var{exp} containing only those +bindings in private whose symbols are present in +@var{signature}. The @var{private} argument must be an +environment. + +The environment @var{exp} binds symbol to location when +@var{env} does, and symbol is exported by @var{signature}. + +@var{signature} is a list specifying which of the bindings in +@var{private} should be visible in @var{exp}. Each element of +@var{signature} should be a list of the form: + (symbol attribute ...) +where each attribute is one of the following: +@table @asis +@item the symbol @code{mutable-location} + @var{exp} should treat the + location bound to symbol as mutable. That is, @var{exp} + will pass calls to @code{environment-set!} or + @code{environment-cell} directly through to private. +@item the symbol @code{immutable-location} + @var{exp} should treat + the location bound to symbol as immutable. If the program + applies @code{environment-set!} to @var{exp} and symbol, or + calls @code{environment-cell} to obtain a writable value + cell, @code{environment-set!} will signal an + @code{environment:immutable-location} error. Note that, even + if an export environment treats a location as immutable, the + underlying environment may treat it as mutable, so its + value may change. +@end table +It is an error for an element of signature to specify both +@code{mutable-location} and @code{immutable-location}. If +neither is specified, @code{immutable-location} is assumed. + +As a special case, if an element of signature is a lone +symbol @var{sym}, it is equivalent to an element of the form +@code{(sym)}. + +All bindings in @var{exp} are immutable. If you apply +@code{environment-define} or @code{environment-undefine} to +@var{exp}, Guile will signal an +@code{environment:immutable-binding} error. However, +notice that the set of bindings in @var{exp} may still change, +if the bindings in private change. +@end deffn + +@deffn primitive export-environment? object +Return @code{#t} if object is an export environment, or +@code{#f} otherwise. +@end deffn + +@deffn primitive export-environment-private env +Return the private environment of export environment @var{env}. +@end deffn + +@deffn primitive export-environment-set-private! env private +Change the private environment of export environment @var{env}. +@end deffn + +@deffn primitive export-environment-signature env +Return the signature of export environment @var{env}. +@end deffn + +@deffn primitive export-environment-set-signature! env signature +Change the signature of export environment @var{env}. +@end deffn + +@deffn primitive %compute-slots class +Return a list consisting of the names of all slots belonging to +class @var{class}, i. e. the slots of @var{class} and of all of +its superclasses. +@end deffn + +@deffn primitive get-keyword key l default_value +Determine an associated value for the keyword @var{key} from +the list @var{l}. The list @var{l} has to consist of an even +number of elements, where, starting with the first, every +second element is a keyword, followed by its associated value. +If @var{l} does not hold a value for @var{key}, the value +@var{default_value} is returned. +@end deffn + +@deffn primitive slot-ref-using-class class obj slot_name +@end deffn + +@deffn primitive slot-set-using-class! class obj slot_name value +@end deffn + +@deffn primitive class-of x +Return the class of @var{x}. +@end deffn + +@deffn primitive %goops-loaded +Announce that GOOPS is loaded and perform initialization +on the C level which depends on the loaded GOOPS modules. +@end deffn + +@deffn primitive %method-more-specific? m1 m2 targs +@end deffn + +@deffn primitive find-method . l +@end deffn + +@deffn primitive primitive-generic-generic subr +@end deffn + +@deffn primitive enable-primitive-generic! . subrs +@end deffn + +@deffn primitive generic-capability? proc +@end deffn + +@deffn primitive %invalidate-method-cache! gf +@end deffn + +@deffn primitive %invalidate-class class +@end deffn + +@deffn primitive %modify-class old new +@end deffn + +@deffn primitive %modify-instance old new +@end deffn + +@deffn primitive %set-object-setter! obj setter +@end deffn + +@deffn primitive %allocate-instance class initargs +Create a new instance of class @var{class} and initialize it +from the arguments @var{initargs}. +@end deffn + +@deffn primitive slot-exists? obj slot_name +Return @code{#t} if @var{obj} has a slot named @var{slot_name}. +@end deffn + +@deffn primitive slot-bound? obj slot_name +Return @code{#t} if the slot named @var{slot_name} of @var{obj} +is bound. +@end deffn + +@deffn primitive slot-set! obj slot_name value +Set the slot named @var{slot_name} of @var{obj} to @var{value}. +@end deffn + +@deffn primitive slot-exists-using-class? class obj slot_name +@end deffn + +@deffn primitive slot-bound-using-class? class obj slot_name +@end deffn + +@deffn primitive %fast-slot-set! obj index value +Set the slot with index @var{index} in @var{obj} to +@var{value}. +@end deffn + +@deffn primitive %fast-slot-ref obj index +Return the slot value with index @var{index} from @var{obj}. +@end deffn + +@deffn primitive @@assert-bound-ref obj index +Like @code{assert-bound}, but use @var{index} for accessing +the value from @var{obj}. +@end deffn + +@deffn primitive assert-bound value obj +Return @var{value} if it is bound, and invoke the +@var{slot-unbound} method of @var{obj} if it is not. +@end deffn + +@deffn primitive unbound? obj +Return @code{#t} if @var{obj} is unbound. +@end deffn + +@deffn primitive make-unbound +Return the unbound value. +@end deffn + +@deffn primitive accessor-method-slot-definition obj +Return the slot definition of the accessor @var{obj}. +@end deffn + +@deffn primitive method-procedure obj +Return the procedure of the method @var{obj}. +@end deffn + +@deffn primitive method-specializers obj +Return specializers of the method @var{obj}. +@end deffn + +@deffn primitive method-generic-function obj +Return the generic function fot the method @var{obj}. +@end deffn + +@deffn primitive generic-function-methods obj +Return the methods of the generic function @var{obj}. +@end deffn + +@deffn primitive generic-function-name obj +Return the name of the generic function @var{obj}. +@end deffn + +@deffn primitive class-environment obj +Return the environment of the class @var{obj}. +@end deffn + +@deffn primitive class-slots obj +Return the slot list of the class @var{obj}. +@end deffn + +@deffn primitive class-precedence-list obj +Return the class precedence list of the class @var{obj}. +@end deffn + +@deffn primitive class-direct-methods obj +Return the direct methods of the class @var{obj} +@end deffn + +@deffn primitive class-direct-subclasses obj +Return the direct subclasses of the class @var{obj}. +@end deffn + +@deffn primitive class-direct-slots obj +Return the direct slots of the class @var{obj}. +@end deffn + +@deffn primitive class-direct-supers obj +Return the direct superclasses of the class @var{obj}. +@end deffn + +@deffn primitive class-name obj +Return the class name of @var{obj}. +@end deffn + +@deffn primitive instance? obj +Return @code{#t} if @var{obj} is an instance. +@end deffn + +@deffn primitive %inherit-magic! class dsupers +@end deffn + +@deffn primitive %prep-layout! class +@end deffn + +@deffn primitive %initialize-object obj initargs +Initialize the object @var{obj} with the given arguments +@var{initargs}. +@end deffn + +@deffn primitive make . args +Make a new object. @var{args} must contain the class and +all necessary initialization information. +@end deffn + +@deffn primitive slot-ref obj slot_name +Return the value from @var{obj}'s slot with the name +@var{slot_name}. +@end deffn + +@deffn primitive builtin-bindings +Create and return a copy of the global symbol table, removing all +unbound symbols. +@end deffn + +@deffn primitive %tag-body body +Internal GOOPS magic---don't use this function! +@end deffn + +@deffn primitive list* +scm_cons_star +@end deffn + +@deffn primitive set-current-module module +Set the current module to @var{module} and return +the previous current module. +@end deffn + +@deffn primitive current-module +Return the current module. +@end deffn + +@deffn primitive c-clear-registered-modules +Destroy the list of modules registered with the current Guile process. +The return value is unspecified. @strong{Warning:} this function does +not actually unlink or deallocate these modules, but only destroys the +records of which modules have been loaded. It should therefore be used +only by module bookkeeping operations. +@end deffn + +@deffn primitive c-registered-modules +Return a list of the object code modules that have been imported into +the current Guile process. Each element of the list is a pair whose +car is the name of the module, and whose cdr is the function handle +for that module's initializer function. The name is the string that +has been passed to scm_register_module_xxx. +@end deffn + +@deffn primitive include-deprecated-features +Return @code{#t} iff deprecated features should be included +in public interfaces. +@end deffn + +@deffn primitive issue-deprecation-warning . msgs +Output @var{msgs} to @code{(current-error-port)} when this +is the first call to @code{issue-deprecation-warning} with +this specific @var{msg}. Do nothing otherwise. +The argument @var{msgs} should be a list of strings; +they are printed in turn, each one followed by a newline. +@end deffn diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi new file mode 100644 index 000000000..4d4473422 --- /dev/null +++ b/doc/ref/posix.texi @@ -0,0 +1,2328 @@ +@node POSIX +@chapter POSIX System Calls and Networking + +@menu +* Conventions:: Conventions employed by the POSIX interface. +* Ports and File Descriptors:: Scheme ``ports'' and Unix file descriptors + have different representations. +* File System:: stat, chown, chmod, etc. +* User Information:: Retrieving a user's GECOS (/etc/passwd) entry. +* Time:: gettimeofday, localtime, strftime, etc. +* Runtime Environment:: Accessing and modifying Guile's environment. +* Processes:: getuid, getpid, etc. +* Signals:: sigaction, kill, pause, alarm, setitimer, etc. +* Terminals and Ptys:: ttyname, tcsetpgrp, etc. +* Pipes:: Communicating data between processes. +* Networking:: gethostbyaddr, getnetent, socket, bind, listen. +* System Identification:: Obtaining information about the system. +* Locales:: setlocale, etc. +* Encryption:: +@end menu + +@node Conventions +@section POSIX Interface Conventions + +These interfaces provide access to operating system facilities. +They provide a simple wrapping around the underlying C interfaces +to make usage from Scheme more convenient. They are also used +to implement the Guile port of @ref{The Scheme shell (scsh)}. + +Generally there is a single procedure for each corresponding Unix +facility. There are some exceptions, such as procedures implemented for +speed and convenience in Scheme with no primitive Unix equivalent, +e.g., @code{copy-file}. + +The interfaces are intended as far as possible to be portable across +different versions of Unix. In some cases procedures which can't be +implemented on particular systems may become no-ops, or perform limited +actions. In other cases they may throw errors. + +General naming conventions are as follows: + +@itemize @bullet +@item +The Scheme name is often identical to the name of the underlying Unix +facility. +@item +Underscores in Unix procedure names are converted to hyphens. +@item +Procedures which destructively modify Scheme data have exclaimation +marks appended, e.g., @code{recv!}. +@item +Predicates (returning only @code{#t} or @code{#f}) have question marks +appended, e.g., @code{access?}. +@item +Some names are changed to avoid conflict with dissimilar interfaces +defined by scsh, e.g., @code{primitive-fork}. +@item +Unix preprocessor names such as @code{EPERM} or @code{R_OK} are converted +to Scheme variables of the same name (underscores are not replaced +with hyphens). +@end itemize + +Unexpected conditions are generally handled by raising exceptions. +There are a few procedures which return a special value if they don't +succeed, e.g., @code{getenv} returns @code{#f} if it the requested +string is not found in the environment. These cases are noted in +the documentation. + +For ways to deal with exceptions, @ref{Exceptions}. + +Errors which the C-library would report by returning a NULL pointer or +through some other means are reported by raising a @code{system-error} +exception. The value of the Unix @code{errno} variable is available +in the data passed by the exception. + +It can be extracted with the function @code{system-error-errno}: + +@example +(catch + 'system-error + (lambda () + (mkdir "/this-ought-to-fail-if-I'm-not-root")) + (lambda stuff + (let ((errno (system-error-errno stuff))) + (cond + ((= errno EACCES) + (display "You're not allowed to do that.")) + ((= errno EEXIST) + (display "Already exists.")) + (#t + (display (strerror errno)))) + (newline)))) +@end example + +@node Ports and File Descriptors +@section Ports and File Descriptors + +Conventions generally follow those of scsh, @ref{The Scheme shell (scsh)}. + +File ports are implemented using low-level operating system I/O +facilities, with optional buffering to improve efficiency +@pxref{File Ports} + +Note that some procedures (e.g., @code{recv!}) will accept ports as +arguments, but will actually operate directly on the file descriptor +underlying the port. Any port buffering is ignored, including the +buffer which implements @code{peek-char} and @code{unread-char}. + +The @code{force-output} and @code{drain-input} procedures can be used +to clear the buffers. + +Each open file port has an associated operating system file descriptor. +File descriptors are generally not useful in Scheme programs; however +they may be needed when interfacing with foreign code and the Unix +environment. + +A file descriptor can be extracted from a port and a new port can be +created from a file descriptor. However a file descriptor is just an +integer and the garbage collector doesn't recognise it as a reference +to the port. If all other references to the port were dropped, then +it's likely that the garbage collector would free the port, with the +side-effect of closing the file descriptor prematurely. + +To assist the programmer in avoiding this problem, each port has an +associated "revealed count" which can be used to keep track of how many +times the underlying file descriptor has been stored in other places. +If a port's revealed count is greater than zero, the file descriptor +will not be closed when the port is gabage collected. A programmer +can therefore ensure that the revealed count will be greater than +zero if the file descriptor is needed elsewhere. + +For the simple case where a file descriptor is "imported" once to become +a port, it does not matter if the file descriptor is closed when the +port is garbage collected. There is no need to maintain a revealed +count. Likewise when "exporting" a file descriptor to the external +environment, setting the revealed count is not required provided the +port is kept open (i.e., is pointed to by a live Scheme binding) while +the file descriptor is in use. + +To correspond with traditional Unix behaviour, the three file +descriptors (0, 1 and 2) are automatically imported when a program +starts up and assigned to the initial values of the current input, +output and error ports. The revealed count for each is initially set to +one, so that dropping references to one of these ports will not result +in its garbage collection: it could be retrieved with fdopen or +fdes->ports. + +@deffn primitive port-revealed port +Return the revealed count for @var{port}. +@end deffn + +@deffn primitive set-port-revealed! port rcount +Sets the revealed count for a port to a given value. +The return value is unspecified. +@end deffn + +@deffn primitive fileno port +Return the integer file descriptor underlying @var{port}. Does +not change its revealed count. +@end deffn + +@deffn procedure port->fdes port +Returns the integer file descriptor underlying @var{port}. As a +side effect the revealed count of @var{port} is incremented. +@end deffn + +@deffn primitive fdopen fdes modes +Return a new port based on the file descriptor @var{fdes}. +Modes are given by the string @var{modes}. The revealed count +of the port is initialized to zero. The modes string is the +same as that accepted by @ref{File Ports, open-file}. +@end deffn + +@deffn primitive fdes->ports fd +Return a list of existing ports which have @var{fdes} as an +underlying file descriptor, without changing their revealed +counts. +@end deffn + +@deffn procedure fdes->inport fdes +Returns an existing input port which has @var{fdes} as its underlying file +descriptor, if one exists, and increments its revealed count. +Otherwise, returns a new input port with a revealed count of 1. +@end deffn + +@deffn procedure fdes->outport fdes +Returns an existing output port which has @var{fdes} as its underlying file +descriptor, if one exists, and increments its revealed count. +Otherwise, returns a new output port with a revealed count of 1. +@end deffn + +@deffn primitive primitive-move->fdes port fd +Moves the underlying file descriptor for @var{port} to the integer +value @var{fdes} without changing the revealed count of @var{port}. +Any other ports already using this descriptor will be automatically +shifted to new descriptors and their revealed counts reset to zero. +The return value is @code{#f} if the file descriptor already had the +required value or @code{#t} if it was moved. +@end deffn + +@deffn procedure move->fdes port fdes +Moves the underlying file descriptor for @var{port} to the integer +value @var{fdes} and sets its revealed count to one. Any other ports +already using this descriptor will be automatically +shifted to new descriptors and their revealed counts reset to zero. +The return value is unspecified. +@end deffn + +@deffn procedure release-port-handle port +Decrements the revealed count for a port. +@end deffn + +@deffn primitive fsync object +Copies any unwritten data for the specified output file descriptor to disk. +If @var{port/fd} is a port, its buffer is flushed before the underlying +file descriptor is fsync'd. +The return value is unspecified. +@end deffn + +@deffn primitive open path flags [mode] +Open the file named by @var{path} for reading and/or writing. +@var{flags} is an integer specifying how the file should be opened. +@var{mode} is an integer specifying the permission bits of the file, if +it needs to be created, before the umask is applied. The default is 666 +(Unix itself has no default). + +@var{flags} can be constructed by combining variables using @code{logior}. +Basic flags are: + +@defvar O_RDONLY +Open the file read-only. +@end defvar +@defvar O_WRONLY +Open the file write-only. +@end defvar +@defvar O_RDWR +Open the file read/write. +@end defvar +@defvar O_APPEND +Append to the file instead of truncating. +@end defvar +@defvar O_CREAT +Create the file if it does not already exist. +@end defvar + +See the Unix documentation of the @code{open} system call +for additional flags. +@end deffn + +@deffn primitive open-fdes path flags [mode] +Similar to @code{open} but return a file descriptor instead of +a port. +@end deffn + +@deffn primitive close fd_or_port +Similar to close-port (@pxref{Closing, close-port}), but also works on +file descriptors. A side effect of closing a file descriptor is that +any ports using that file descriptor are moved to a different file +descriptor and have their revealed counts set to zero. +@end deffn + +@deffn primitive close-fdes fd +A simple wrapper for the @code{close} system call. +Close file descriptor @var{fd}, which must be an integer. +Unlike close (@pxref{Ports and File Descriptors, close}), +the file descriptor will be closed even if a port is using it. +The return value is unspecified. +@end deffn + +@deffn primitive unread-char char [port] +Place @var{char} in @var{port} so that it will be read by the +next read operation. If called multiple times, the unread characters +will be read again in last-in first-out order. If @var{port} is +not supplied, the current input port is used. +@end deffn + +@deffn primitive unread-string str port +Place the string @var{str} in @var{port} so that its characters will be +read in subsequent read operations. If called multiple times, the +unread characters will be read again in last-in first-out order. If +@var{port} is not supplied, the current-input-port is used. +@end deffn + +@deffn primitive pipe +Return a newly created pipe: a pair of ports which are linked +together on the local machine. The @emph{car} is the input +port and the @emph{cdr} is the output port. Data written (and +flushed) to the output port can be read from the input port. +Pipes are commonly used for communication with a newly forked +child process. The need to flush the output port can be +avoided by making it unbuffered using @code{setvbuf}. + +Writes occur atomically provided the size of the data in bytes +is not greater than the value of @code{PIPE_BUF}. Note that +the output port is likely to block if too much data (typically +equal to @code{PIPE_BUF}) has been written but not yet read +from the input port. +@end deffn + +The next group of procedures perform a @code{dup2} +system call, if @var{newfd} (an +integer) is supplied, otherwise a @code{dup}. The file descriptor to be +duplicated can be supplied as an integer or contained in a port. The +type of value returned varies depending on which procedure is used. + +All procedures also have the side effect when performing @code{dup2} that any +ports using @var{newfd} are moved to a different file descriptor and have +their revealed counts set to zero. + +@deffn primitive dup->fdes fd_or_port [fd] +Return a new integer file descriptor referring to the open file +designated by @var{fd_or_port}, which must be either an open +file port or a file descriptor. +@end deffn + +@deffn procedure dup->inport port/fd [newfd] +Returns a new input port using the new file descriptor. +@end deffn + +@deffn procedure dup->outport port/fd [newfd] +Returns a new output port using the new file descriptor. +@end deffn + +@deffn procedure dup port/fd [newfd] +Returns a new port if @var{port/fd} is a port, with the same mode as the +supplied port, otherwise returns an integer file descriptor. +@end deffn + +@deffn procedure dup->port port/fd mode [newfd] +Returns a new port using the new file descriptor. @var{mode} supplies a +mode string for the port (@pxref{File Ports, open-file}). +@end deffn + +@deffn procedure duplicate-port port modes +Returns a new port which is opened on a duplicate of the file +descriptor underlying @var{port}, with mode string @var{modes} +as for @ref{File Ports, open-file}. The two ports +will share a file position and file status flags. + +Unexpected behaviour can result if both ports are subsequently used +and the original and/or duplicate ports are buffered. +The mode string can include @code{0} to obtain an unbuffered duplicate +port. + +This procedure is equivalent to @code{(dup->port @var{port} @var{modes})}. +@end deffn + +@deffn primitive redirect-port old new +This procedure takes two ports and duplicates the underlying file +descriptor from @var{old-port} into @var{new-port}. The +current file descriptor in @var{new-port} will be closed. +After the redirection the two ports will share a file position +and file status flags. + +The return value is unspecified. + +Unexpected behaviour can result if both ports are subsequently used +and the original and/or duplicate ports are buffered. + +This procedure does not have any side effects on other ports or +revealed counts. +@end deffn + +@deffn primitive dup2 oldfd newfd +A simple wrapper for the @code{dup2} system call. +Copies the file descriptor @var{oldfd} to descriptor +number @var{newfd}, replacing the previous meaning +of @var{newfd}. Both @var{oldfd} and @var{newfd} must +be integers. +Unlike for dup->fdes or primitive-move->fdes, no attempt +is made to move away ports which are using @var{newfd}. +The return value is unspecified. +@end deffn + +@deffn primitive port-mode port +Return the port modes associated with the open port @var{port}. +These will not necessarily be identical to the modes used when +the port was opened, since modes such as "append" which are +used only during port creation are not retained. +@end deffn + +@deffn primitive close-all-ports-except . ports +[DEPRECATED] Close all open file ports used by the interpreter +except for those supplied as arguments. This procedure +was intended to be used before an exec call to close file descriptors +which are not needed in the new process. However it has the +undesirable side-effect of flushing buffes, so it's deprecated. +Use port-for-each instead. +@end deffn + +@deffn primitive port-for-each proc +Apply @var{proc} to each port in the Guile port table +in turn. The return value is unspecified. More specifically, +@var{proc} is applied exactly once to every port that exists +in the system at the time @var{port-for-each} is invoked. +Changes to the port table while @var{port-for-each} is running +have no effect as far as @var{port-for-each} is concerned. +@end deffn + +@deffn primitive setvbuf port mode [size] +Set the buffering mode for @var{port}. @var{mode} can be: +@table @code +@item _IONBF +non-buffered +@item _IOLBF +line buffered +@item _IOFBF +block buffered, using a newly allocated buffer of @var{size} bytes. +If @var{size} is omitted, a default size will be used. +@end table +@end deffn + +@deffn primitive fcntl object cmd [value] +Apply @var{command} to the specified file descriptor or the underlying +file descriptor of the specified port. @var{value} is an optional +integer argument. + +Values for @var{command} are: + +@table @code +@item F_DUPFD +Duplicate a file descriptor +@item F_GETFD +Get flags associated with the file descriptor. +@item F_SETFD +Set flags associated with the file descriptor to @var{value}. +@item F_GETFL +Get flags associated with the open file. +@item F_SETFL +Set flags associated with the open file to @var{value} +@item F_GETOWN +Get the process ID of a socket's owner, for @code{SIGIO} signals. +@item F_SETOWN +Set the process that owns a socket to @var{value}, for @code{SIGIO} signals. +@item FD_CLOEXEC +The value used to indicate the "close on exec" flag with @code{F_GETFL} or +@code{F_SETFL}. +@end table +@end deffn + +@deffn primitive flock file operation +Apply or remove an advisory lock on an open file. +@var{operation} specifies the action to be done: +@table @code +@item LOCK_SH +Shared lock. More than one process may hold a shared lock +for a given file at a given time. +@item LOCK_EX +Exclusive lock. Only one process may hold an exclusive lock +for a given file at a given time. +@item LOCK_UN +Unlock the file. +@item LOCK_NB +Don't block when locking. May be specified by bitwise OR'ing +it to one of the other operations. +@end table +The return value is not specified. @var{file} may be an open +file descriptor or an open file descriptior port. +@end deffn + +@deffn primitive select reads writes excepts [secs [usecs]] +This procedure has a variety of uses: waiting for the ability +to provide input, accept output, or the existance of +exceptional conditions on a collection of ports or file +descriptors, or waiting for a timeout to occur. +It also returns if interrupted by a signal. + +@var{reads}, @var{writes} and @var{excepts} can be lists or +vectors, with each member a port or a file descriptor. +The value returned is a list of three corresponding +lists or vectors containing only the members which meet the +specified requirement. The ability of port buffers to +provide input or accept output is taken into account. +Ordering of the input lists or vectors is not preserved. + +The optional arguments @var{secs} and @var{usecs} specify the +timeout. Either @var{secs} can be specified alone, as +either an integer or a real number, or both @var{secs} and +@var{usecs} can be specified as integers, in which case +@var{usecs} is an additional timeout expressed in +microseconds. If @var{secs} is omitted or is @code{#f} then +select will wait for as long as it takes for one of the other +conditions to be satisfied. + +The scsh version of @code{select} differs as follows: +Only vectors are accepted for the first three arguments. +The @var{usecs} argument is not supported. +Multiple values are returned instead of a list. +Duplicates in the input vectors appear only once in output. +An additional @code{select!} interface is provided. +@end deffn + +@node File System +@section File System + +These procedures allow querying and setting file system attributes +(such as owner, +permissions, sizes and types of files); deleting, copying, renaming and +linking files; creating and removing directories and querying their +contents; syncing the file system and creating special files. + +@deffn primitive access? path how +Return @code{#t} if @var{path} corresponds to an existing file +and the current process has the type of access specified by +@var{how}, otherwise @code{#f}. @var{how} should be specified +using the values of the variables listed below. Multiple +values can be combined using a bitwise or, in which case +@code{#t} will only be returned if all accesses are granted. + +Permissions are checked using the real id of the current +process, not the effective id, although it's the effective id +which determines whether the access would actually be granted. + +@defvar R_OK +test for read permission. +@end defvar +@defvar W_OK +test for write permission. +@end defvar +@defvar X_OK +test for execute permission. +@end defvar +@defvar F_OK +test for existence of the file. +@end defvar +@end deffn + +@findex fstat +@deffn primitive stat object +Return an object containing various information about the file +determined by @var{obj}. @var{obj} can be a string containing +a file name or a port or integer file descriptor which is open +on a file (in which case @code{fstat} is used as the underlying +system call). + +The object returned by @code{stat} can be passed as a single +parameter to the following procedures, all of which return +integers: + +@table @code +@item stat:dev +The device containing the file. +@item stat:ino +The file serial number, which distinguishes this file from all +other files on the same device. +@item stat:mode +The mode of the file. This includes file type information and +the file permission bits. See @code{stat:type} and +@code{stat:perms} below. +@item stat:nlink +The number of hard links to the file. +@item stat:uid +The user ID of the file's owner. +@item stat:gid +The group ID of the file. +@item stat:rdev +Device ID; this entry is defined only for character or block +special files. +@item stat:size +The size of a regular file in bytes. +@item stat:atime +The last access time for the file. +@item stat:mtime +The last modification time for the file. +@item stat:ctime +The last modification time for the attributes of the file. +@item stat:blksize +The optimal block size for reading or writing the file, in +bytes. +@item stat:blocks +The amount of disk space that the file occupies measured in +units of 512 byte blocks. +@end table + +In addition, the following procedures return the information +from stat:mode in a more convenient form: + +@table @code +@item stat:type +A symbol representing the type of file. Possible values are +regular, directory, symlink, block-special, char-special, fifo, +socket and unknown +@item stat:perms +An integer representing the access permission bits. +@end table +@end deffn + +@deffn primitive lstat str +Similar to @code{stat}, but does not follow symbolic links, i.e., +it will return information about a symbolic link itself, not the +file it points to. @var{path} must be a string. +@end deffn + +@deffn primitive readlink path +Return the value of the symbolic link named by @var{path} (a +string), i.e., the file that the link points to. +@end deffn + +@findex fchown +@findex lchown +@deffn primitive chown object owner group +Change the ownership and group of the file referred to by @var{object} to +the integer values @var{owner} and @var{group}. @var{object} can be +a string containing a file name or, if the platform +supports fchown, a port or integer file descriptor +which is open on the file. The return value +is unspecified. + +If @var{object} is a symbolic link, either the +ownership of the link or the ownership of the referenced file will be +changed depending on the operating system (lchown is +unsupported at present). If @var{owner} or @var{group} is specified +as @code{-1}, then that ID is not changed. +@end deffn + +@findex fchmod +@deffn primitive chmod object mode +Changes the permissions of the file referred to by @var{obj}. +@var{obj} can be a string containing a file name or a port or integer file +descriptor which is open on a file (in which case @code{fchmod} is used +as the underlying system call). +@var{mode} specifies +the new permissions as a decimal number, e.g., @code{(chmod "foo" #o755)}. +The return value is unspecified. +@end deffn + +@deffn primitive utime pathname [actime [modtime]] +@code{utime} sets the access and modification times for the +file named by @var{path}. If @var{actime} or @var{modtime} is +not supplied, then the current time is used. @var{actime} and +@var{modtime} must be integer time values as returned by the +@code{current-time} procedure. +@lisp +(utime "foo" (- (current-time) 3600)) +@end lisp +will set the access time to one hour in the past and the +modification time to the current time. +@end deffn + +@findex unlink +@deffn primitive delete-file str +Deletes (or "unlinks") the file specified by @var{path}. +@end deffn + +@deffn primitive copy-file oldfile newfile +Copy the file specified by @var{path-from} to @var{path-to}. +The return value is unspecified. +@end deffn + +@findex rename +@deffn primitive rename-file oldname newname +Renames the file specified by @var{oldname} to @var{newname}. +The return value is unspecified. +@end deffn + +@deffn primitive link oldpath newpath +Creates a new name @var{newpath} in the file system for the +file named by @var{oldpath}. If @var{oldpath} is a symbolic +link, the link may or may not be followed depending on the +system. +@end deffn + +@deffn primitive symlink oldpath newpath +Create a symbolic link named @var{path-to} with the value (i.e., pointing to) +@var{path-from}. The return value is unspecified. +@end deffn + +@deffn primitive mkdir path [mode] +Create a new directory named by @var{path}. If @var{mode} is omitted +then the permissions of the directory file are set using the current +umask. Otherwise they are set to the decimal value specified with +@var{mode}. The return value is unspecified. +@end deffn + +@deffn primitive rmdir path +Remove the existing directory named by @var{path}. The directory must +be empty for this to succeed. The return value is unspecified. +@end deffn + +@deffn primitive opendir dirname +Open the directory specified by @var{path} and return a directory +stream. +@end deffn + +@deffn primitive directory-stream? obj +Return a boolean indicating whether @var{object} is a directory +stream as returned by @code{opendir}. +@end deffn + +@deffn primitive readdir port +Return (as a string) the next directory entry from the directory stream +@var{stream}. If there is no remaining entry to be read then the +end of file object is returned. +@end deffn + +@deffn primitive rewinddir port +Reset the directory port @var{stream} so that the next call to +@code{readdir} will return the first directory entry. +@end deffn + +@deffn primitive closedir port +Close the directory stream @var{stream}. +The return value is unspecified. +@end deffn + +@deffn primitive sync +Flush the operating system disk buffers. +The return value is unspecified. +@end deffn + +@deffn primitive mknod path type perms dev +Creates a new special file, such as a file corresponding to a device. +@var{path} specifies the name of the file. @var{type} should +be one of the following symbols: +regular, directory, symlink, block-special, char-special, +fifo, or socket. @var{perms} (an integer) specifies the file permissions. +@var{dev} (an integer) specifies which device the special file refers +to. Its exact interpretation depends on the kind of special file +being created. + +E.g., +@lisp +(mknod "/dev/fd0" 'block-special #o660 (+ (* 2 256) 2)) +@end lisp + +The return value is unspecified. +@end deffn + +@deffn primitive tmpnam +Return a name in the file system that does not match any +existing file. However there is no guarantee that another +process will not create the file after @code{tmpnam} is called. +Care should be taken if opening the file, e.g., use the +@code{O_EXCL} open flag or use @code{mkstemp!} instead. +@end deffn + +@deffn primitive mkstemp! tmpl +Create a new unique file in the file system and returns a new +buffered port open for reading and writing to the file. +@var{tmpl} is a string specifying where the file should be +created: it must end with @code{XXXXXX} and will be changed in +place to return the name of the temporary file. +@end deffn + +@deffn primitive dirname filename +Return the directory name component of the file name +@var{filename}. If @var{filename} does not contain a directory +component, @code{.} is returned. +@end deffn + +@deffn primitive basename filename [suffix] +Return the base name of the file name @var{filename}. The +base name is the file name without any directory components. +If @var{suffix} is privided, and is equal to the end of +@var{basename}, it is removed also. +@end deffn + + +@node User Information +@section User Information + +The facilities in this section provide an interface to the user and +group database. +They should be used with care since they are not reentrant. + +The following functions accept an object representing user information +and return a selected component: + +@table @code +@item passwd:name +The name of the userid. +@item passwd:passwd +The encrypted passwd. +@item passwd:uid +The user id number. +@item passwd:gid +The group id number. +@item passwd:gecos +The full name. +@item passwd:dir +The home directory. +@item passwd:shell +The login shell. +@end table + +@deffn procedure getpwuid uid +Look up an integer userid in the user database. +@end deffn + +@deffn procedure getpwnam name +Look up a user name string in the user database. +@end deffn + +@deffn procedure setpwent +Initializes a stream used by @code{getpwent} to read from the user database. +The next use of @code{getpwent} will return the first entry. The +return value is unspecified. +@end deffn + +@deffn procedure getpwent +Return the next entry in the user database, using the stream set by +@code{setpwent}. +@end deffn + +@deffn procedure endpwent +Closes the stream used by @code{getpwent}. The return value is unspecified. +@end deffn + +@deffn primitive setpw [arg] +If called with a true argument, initialize or reset the password data +stream. Otherwise, close the stream. The @code{setpwent} and +@code{endpwent} procedures are implemented on top of this. +@end deffn + +@deffn primitive getpw [user] +Look up an entry in the user database. @var{obj} can be an integer, +a string, or omitted, giving the behaviour of getpwuid, getpwnam +or getpwent respectively. +@end deffn + +The following functions accept an object representing group information +and return a selected component: + +@table @code +@item group:name +The group name. +@item group:passwd +The encrypted group password. +@item group:gid +The group id number. +@item group:mem +A list of userids which have this group as a supplimentary group. +@end table + +@deffn procedure getgrgid gid +Look up an integer groupid in the group database. +@end deffn + +@deffn procedure getgrnam name +Look up a group name in the group database. +@end deffn + +@deffn procedure setgrent +Initializes a stream used by @code{getgrent} to read from the group database. +The next use of @code{getgrent} will return the first entry. +The return value is unspecified. +@end deffn + +@deffn procedure getgrent +Return the next entry in the group database, using the stream set by +@code{setgrent}. +@end deffn + +@deffn procedure endgrent +Closes the stream used by @code{getgrent}. +The return value is unspecified. +@end deffn + +@deffn primitive setgr [arg] +If called with a true argument, initialize or reset the group data +stream. Otherwise, close the stream. The @code{setgrent} and +@code{endgrent} procedures are implemented on top of this. +@end deffn + +@deffn primitive getgr [name] +Look up an entry in the group database. @var{obj} can be an integer, +a string, or omitted, giving the behaviour of getgrgid, getgrnam +or getgrent respectively. +@end deffn + +In addition to the accessor procedures for the user database, the +following shortcut procedures are also available. + +@deffn primitive cuserid +Return a string containing a user name associated with the +effective user id of the process. Return @code{#f} if this +information cannot be obtained. +@end deffn + +@deffn primitive getlogin +Return a string containing the name of the user logged in on +the controlling terminal of the process, or @code{#f} if this +information cannot be obtained. +@end deffn + + +@node Time +@section Time + +@deffn primitive current-time +Return the number of seconds since 1970-01-01 00:00:00 UTC, +excluding leap seconds. +@end deffn + +@deffn primitive gettimeofday +Return a pair containing the number of seconds and microseconds +since 1970-01-01 00:00:00 UTC, excluding leap seconds. Note: +whether true microsecond resolution is available depends on the +operating system. +@end deffn + +The following procedures either accept an object representing a broken down +time and return a selected component, or accept an object representing +a broken down time and a value and set the component to the value. +The numbers in parentheses give the usual range. + +@table @code +@item tm:sec, set-tm:sec +Seconds (0-59). +@item tm:min, set-tm:min +Minutes (0-59). +@item tm:hour, set-tm:hour +Hours (0-23). +@item tm:mday, set-tm:mday +Day of the month (1-31). +@item tm:mon, set-tm:mon +Month (0-11). +@item tm:year, set-tm:year +Year (70-), the year minus 1900. +@item tm:wday, set-tm:wday +Day of the week (0-6) with Sunday represented as 0. +@item tm:yday, set-tm:yday +Day of the year (0-364, 365 in leap years). +@item tm:isdst, set-tm:isdst +Daylight saving indicator (0 for "no", greater than 0 for "yes", less than +0 for "unknown"). +@item tm:gmtoff, set-tm:gmtoff +Time zone offset in seconds west of UTC (-46800 to 43200). +@item tm:zone, set-tm:zone +Time zone label (a string), not necessarily unique. +@end table + +@deffn primitive localtime time [zone] +Return an object representing the broken down components of +@var{time}, an integer like the one returned by +@code{current-time}. The time zone for the calculation is +optionally specified by @var{zone} (a string), otherwise the +@code{TZ} environment variable or the system default is used. +@end deffn + +@deffn primitive gmtime time +Return an object representing the broken down components of +@var{time}, an integer like the one returned by +@code{current-time}. The values are calculated for UTC. +@end deffn + +@deffn primitive mktime sbd_time [zone] +@var{bd-time} is an object representing broken down time and @code{zone} +is an optional time zone specifier (otherwise the TZ environment variable +or the system default is used). + +Returns a pair: the car is a corresponding +integer time value like that returned +by @code{current-time}; the cdr is a broken down time object, similar to +as @var{bd-time} but with normalized values. +@end deffn + +@deffn primitive tzset +Initialize the timezone from the TZ environment variable +or the system default. It's not usually necessary to call this procedure +since it's done automatically by other procedures that depend on the +timezone. +@end deffn + +@deffn primitive strftime format stime +Formats a time specification @var{time} using @var{template}. @var{time} +is an object with time components in the form returned by @code{localtime} +or @code{gmtime}. @var{template} is a string which can include formatting +specifications introduced by a @code{%} character. The formatting of +month and day names is dependent on the current locale. The value returned +is the formatted string. +@xref{Formatting Date and Time, , , libc, The GNU C Library Reference Manual}.) +@end deffn + +@deffn primitive strptime format string +Performs the reverse action to @code{strftime}, parsing +@var{string} according to the specification supplied in +@var{template}. The interpretation of month and day names is +dependent on the current locale. The value returned is a pair. +The car has an object with time components +in the form returned by @code{localtime} or @code{gmtime}, +but the time zone components +are not usefully set. +The cdr reports the number of characters from @var{string} +which were used for the conversion. +@end deffn + +@defvar internal-time-units-per-second +The value of this variable is the number of time units per second +reported by the following procedures. +@end defvar + +@deffn primitive times +Return an object with information about real and processor +time. The following procedures accept such an object as an +argument and return a selected component: + +@table @code +@item tms:clock +The current real time, expressed as time units relative to an +arbitrary base. +@item tms:utime +The CPU time units used by the calling process. +@item tms:stime +The CPU time units used by the system on behalf of the calling +process. +@item tms:cutime +The CPU time units used by terminated child processes of the +calling process, whose status has been collected (e.g., using +@code{waitpid}). +@item tms:cstime +Similarly, the CPU times units used by the system on behalf of +terminated child processes. +@end table +@end deffn + +@deffn primitive get-internal-real-time +Return the number of time units since the interpreter was +started. +@end deffn + +@deffn primitive get-internal-run-time +Return the number of time units of processor time used by the +interpreter. Both @emph{system} and @emph{user} time are +included but subprocesses are not. +@end deffn + +@node Runtime Environment +@section Runtime Environment + +@deffn primitive program-arguments +@deffnx procedure command-line +Return the list of command line arguments passed to Guile, as a list of +strings. The list includes the invoked program name, which is usually +@code{"guile"}, but excludes switches and parameters for command line +options like @code{-e} and @code{-l}. +@end deffn + +@deffn primitive getenv nam +Looks up the string @var{name} in the current environment. The return +value is @code{#f} unless a string of the form @code{NAME=VALUE} is +found, in which case the string @code{VALUE} is returned. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "setenv") +@deffn procedure setenv name value +Modifies the environment of the current process, which is +also the default environment inherited by child processes. + +If @var{value} is @code{#f}, then @var{name} is removed from the +environment. Otherwise, the string @var{name}=@var{value} is added +to the environment, replacing any existing string with name matching +@var{name}. + +The return value is unspecified. +@end deffn + +@deffn primitive environ [env] +If @var{env} is omitted, return the current environment (in the +Unix sense) as a list of strings. Otherwise set the current +environment, which is also the default environment for child +processes, to the supplied list of strings. Each member of +@var{env} should be of the form @code{NAME=VALUE} and values of +@code{NAME} should not be duplicated. If @var{env} is supplied +then the return value is unspecified. +@end deffn + +@deffn primitive putenv str +Modifies the environment of the current process, which is +also the default environment inherited by child processes. + +If @var{string} is of the form @code{NAME=VALUE} then it will be written +directly into the environment, replacing any existing environment string +with +name matching @code{NAME}. If @var{string} does not contain an equal +sign, then any existing string with name matching @var{string} will +be removed. + +The return value is unspecified. +@end deffn + + +@node Processes +@section Processes + +@findex cd +@deffn primitive chdir str +Change the current working directory to @var{path}. +The return value is unspecified. +@end deffn + +@findex pwd +@deffn primitive getcwd +Return the name of the current working directory. +@end deffn + +@deffn primitive umask [mode] +If @var{mode} is omitted, retuns a decimal number representing the current +file creation mask. Otherwise the file creation mask is set to +@var{mode} and the previous value is returned. + +E.g., @code{(umask #o022)} sets the mask to octal 22, decimal 18. +@end deffn + +@deffn primitive chroot path +Change the root directory to that specified in @var{path}. +This directory will be used for path names beginning with +@file{/}. The root directory is inherited by all children +of the current process. Only the superuser may change the +root directory. +@end deffn + +@deffn primitive getpid +Return an integer representing the current process ID. +@end deffn + +@deffn primitive getgroups +Return a vector of integers representing the current +supplimentary group IDs. +@end deffn + +@deffn primitive getppid +Return an integer representing the process ID of the parent +process. +@end deffn + +@deffn primitive getuid +Return an integer representing the current real user ID. +@end deffn + +@deffn primitive getgid +Return an integer representing the current real group ID. +@end deffn + +@deffn primitive geteuid +Return an integer representing the current effective user ID. +If the system does not support effective IDs, then the real ID +is returned. @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +@end deffn + +@deffn primitive getegid +Return an integer representing the current effective group ID. +If the system does not support effective IDs, then the real ID +is returned. @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +@end deffn + +@deffn primitive setuid id +Sets both the real and effective user IDs to the integer @var{id}, provided +the process has appropriate privileges. +The return value is unspecified. +@end deffn + +@deffn primitive setgid id +Sets both the real and effective group IDs to the integer @var{id}, provided +the process has appropriate privileges. +The return value is unspecified. +@end deffn + +@deffn primitive seteuid id +Sets the effective user ID to the integer @var{id}, provided the process +has appropriate privileges. If effective IDs are not supported, the +real ID is set instead -- @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +The return value is unspecified. +@end deffn + +@deffn primitive setegid id +Sets the effective group ID to the integer @var{id}, provided the process +has appropriate privileges. If effective IDs are not supported, the +real ID is set instead -- @code{(feature? 'EIDs)} reports whether the +system supports effective IDs. +The return value is unspecified. +@end deffn + +@deffn primitive getpgrp +Return an integer representing the current process group ID. +This is the POSIX definition, not BSD. +@end deffn + +@deffn primitive setpgid pid pgid +Move the process @var{pid} into the process group @var{pgid}. @var{pid} or +@var{pgid} must be integers: they can be zero to indicate the ID of the +current process. +Fails on systems that do not support job control. +The return value is unspecified. +@end deffn + +@deffn primitive setsid +Creates a new session. The current process becomes the session leader +and is put in a new process group. The process will be detached +from its controlling terminal if it has one. +The return value is an integer representing the new process group ID. +@end deffn + +@deffn primitive waitpid pid [options] +This procedure collects status information from a child process which +has terminated or (optionally) stopped. Normally it will +suspend the calling process until this can be done. If more than one +child process is eligible then one will be chosen by the operating system. + +The value of @var{pid} determines the behaviour: + +@table @r +@item @var{pid} greater than 0 +Request status information from the specified child process. +@item @var{pid} equal to -1 or WAIT_ANY +Request status information for any child process. +@item @var{pid} equal to 0 or WAIT_MYPGRP +Request status information for any child process in the current process +group. +@item @var{pid} less than -1 +Request status information for any child process whose process group ID +is -@var{PID}. +@end table + +The @var{options} argument, if supplied, should be the bitwise OR of the +values of zero or more of the following variables: + +@defvar WNOHANG +Return immediately even if there are no child processes to be collected. +@end defvar + +@defvar WUNTRACED +Report status information for stopped processes as well as terminated +processes. +@end defvar + +The return value is a pair containing: + +@enumerate +@item +The process ID of the child process, or 0 if @code{WNOHANG} was +specified and no process was collected. +@item +The integer status value. +@end enumerate +@end deffn + +The following three +functions can be used to decode the process status code returned +by @code{waitpid}. + +@deffn primitive status:exit-val status +Return the exit status value, as would be set if a process +ended normally through a call to @code{exit} or @code{_exit}, +if any, otherwise @code{#f}. +@end deffn + +@deffn primitive status:term-sig status +Return the signal number which terminated the process, if any, +otherwise @code{#f}. +@end deffn + +@deffn primitive status:stop-sig status +Return the signal number which stopped the process, if any, +otherwise @code{#f}. +@end deffn + +@deffn primitive system [cmd] +Execute @var{cmd} using the operating system's "command +processor". Under Unix this is usually the default shell +@code{sh}. The value returned is @var{cmd}'s exit status as +returned by @code{waitpid}, which can be interpreted using the +functions above. + +If @code{system} is called without arguments, return a boolean +indicating whether the command processor is available. +@end deffn + +@deffn primitive primitive-exit [status] +Terminate the current process without unwinding the Scheme stack. +This is would typically be useful after a fork. The exit status +is @var{status} if supplied, otherwise zero. +@end deffn + +@deffn primitive execl filename . args +Executes the file named by @var{path} as a new process image. +The remaining arguments are supplied to the process; from a C program +they are accessable as the @code{argv} argument to @code{main}. +Conventionally the first @var{arg} is the same as @var{path}. +All arguments must be strings. + +If @var{arg} is missing, @var{path} is executed with a null +argument list, which may have system-dependent side-effects. + +This procedure is currently implemented using the @code{execv} system +call, but we call it @code{execl} because of its Scheme calling interface. +@end deffn + +@deffn primitive execlp filename . args +Similar to @code{execl}, however if +@var{filename} does not contain a slash +then the file to execute will be located by searching the +directories listed in the @code{PATH} environment variable. + +This procedure is currently implemented using the @code{execvp} system +call, but we call it @code{execlp} because of its Scheme calling interface. +@end deffn + +@deffn primitive execle filename env . args +Similar to @code{execl}, but the environment of the new process is +specified by @var{env}, which must be a list of strings as returned by the +@code{environ} procedure. + +This procedure is currently implemented using the @code{execve} system +call, but we call it @code{execle} because of its Scheme calling interface. +@end deffn + +@deffn primitive primitive-fork +Creates a new "child" process by duplicating the current "parent" process. +In the child the return value is 0. In the parent the return value is +the integer process ID of the child. + +This procedure has been renamed from @code{fork} to avoid a naming conflict +with the scsh fork. +@end deffn + +@deffn primitive nice incr +Increment the priority of the current process by @var{incr}. A higher +priority value means that the process runs less often. +The return value is unspecified. +@end deffn + +@deffn primitive setpriority which who prio +Set the scheduling priority of the process, process group +or user, as indicated by @var{which} and @var{who}. @var{which} +is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP} +or @code{PRIO_USER}, and @var{who} is interpreted relative to +@var{which} (a process identifier for @code{PRIO_PROCESS}, +process group identifier for @code{PRIO_PGRP}, and a user +identifier for @code{PRIO_USER}. A zero value of @var{who} +denotes the current process, process group, or user. +@var{prio} is a value in the range -20 and 20, the default +priority is 0; lower priorities cause more favorable +scheduling. Sets the priority of all of the specified +processes. Only the super-user may lower priorities. +The return value is not specified. +@end deffn + +@deffn primitive getpriority which who +Return the scheduling priority of the process, process group +or user, as indicated by @var{which} and @var{who}. @var{which} +is one of the variables @code{PRIO_PROCESS}, @code{PRIO_PGRP} +or @code{PRIO_USER}, and @var{who} is interpreted relative to +@var{which} (a process identifier for @code{PRIO_PROCESS}, +process group identifier for @code{PRIO_PGRP}, and a user +identifier for @code{PRIO_USER}. A zero value of @var{who} +denotes the current process, process group, or user. Return +the highest priority (lowest numerical value) of any of the +specified processes. +@end deffn + + +@node Signals +@section Signals + +Procedures to raise, handle and wait for signals. + +@deffn primitive kill pid sig +Sends a signal to the specified process or group of processes. + +@var{pid} specifies the processes to which the signal is sent: + +@table @r +@item @var{pid} greater than 0 +The process whose identifier is @var{pid}. +@item @var{pid} equal to 0 +All processes in the current process group. +@item @var{pid} less than -1 +The process group whose identifier is -@var{pid} +@item @var{pid} equal to -1 +If the process is privileged, all processes except for some special +system processes. Otherwise, all processes with the current effective +user ID. +@end table + +@var{sig} should be specified using a variable corresponding to +the Unix symbolic name, e.g., + +@defvar SIGHUP +Hang-up signal. +@end defvar + +@defvar SIGINT +Interrupt signal. +@end defvar +@end deffn + +@deffn primitive raise sig +Sends a specified signal @var{sig} to the current process, where +@var{sig} is as described for the kill procedure. +@end deffn + +@deffn primitive sigaction signum [handler [flags]] +Install or report the signal handler for a specified signal. + +@var{signum} is the signal number, which can be specified using the value +of variables such as @code{SIGINT}. + +If @var{action} is omitted, @code{sigaction} returns a pair: the +CAR is the current +signal hander, which will be either an integer with the value @code{SIG_DFL} +(default action) or @code{SIG_IGN} (ignore), or the Scheme procedure which +handles the signal, or @code{#f} if a non-Scheme procedure handles the +signal. The CDR contains the current @code{sigaction} flags for the handler. + +If @var{action} is provided, it is installed as the new handler for +@var{signum}. @var{action} can be a Scheme procedure taking one +argument, or the value of @code{SIG_DFL} (default action) or +@code{SIG_IGN} (ignore), or @code{#f} to restore whatever signal handler +was installed before @code{sigaction} was first used. Flags can +optionally be specified for the new handler (@code{SA_RESTART} will +always be added if it's available and the system is using restartable +system calls.) The return value is a pair with information about the +old handler as described above. + +This interface does not provide access to the "signal blocking" +facility. Maybe this is not needed, since the thread support may +provide solutions to the problem of consistent access to data +structures. +@end deffn + +@deffn primitive restore-signals +Return all signal handlers to the values they had before any call to +@code{sigaction} was made. The return value is unspecified. +@end deffn + +@deffn primitive alarm i +Set a timer to raise a @code{SIGALRM} signal after the specified +number of seconds (an integer). It's advisable to install a signal +handler for +@code{SIGALRM} beforehand, since the default action is to terminate +the process. + +The return value indicates the time remaining for the previous alarm, +if any. The new value replaces the previous alarm. If there was +no previous alarm, the return value is zero. +@end deffn + +@deffn primitive pause +Pause the current process (thread?) until a signal arrives whose +action is to either terminate the current process or invoke a +handler procedure. The return value is unspecified. +@end deffn + +@deffn primitive sleep i +Wait for the given number of seconds (an integer) or until a signal +arrives. The return value is zero if the time elapses or the number +of seconds remaining otherwise. +@end deffn + +@deffn primitive usleep i +Sleep for I microseconds. @code{usleep} is not available on +all platforms. +@end deffn + +@deffn primitive setitimer which_timer interval_seconds interval_microseconds value_seconds value_microseconds + +Set the timer specified by @var{which_timer} according to the given +@var{interval_seconds}, @var{interval_microseconds}, +@var{value_seconds}, and @var{value_microseconds} values, and return +information about the timer's previous setting. The timers available +are: @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, and @code{ITIMER_PROF}, +and the return value will be a list of two cons pairs representing the +current state of the given timer. The first pair is the seconds and +microseconds of the timer @code{it_interval}, and the second pair is the +seconds and microseconds of the timer @code{it_value}. +@end deffn + +@deffn primitive getitimer which_timer +Return information about the timer specified by @var{which_timer}. The +timers available are: @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, and +@code{ITIMER_PROF}, and the return value will be a list of two cons +pairs representing the current state of the given timer. The first pair +is the seconds and microseconds of the timer @code{it_interval}, and the +second pair is the seconds and microseconds of the timer +@code{it_value}. +@end deffn + + +@node Terminals and Ptys +@section Terminals and Ptys + +@deffn primitive isatty? port +Return @code{#t} if @var{port} is using a serial non--file +device, otherwise @code{#f}. +@end deffn + +@deffn primitive ttyname port +Return a string with the name of the serial terminal device +underlying @var{port}. +@end deffn + +@deffn primitive ctermid +Return a string containing the file name of the controlling +terminal for the current process. +@end deffn + +@deffn primitive tcgetpgrp port +Return the process group ID of the foreground process group +associated with the terminal open on the file descriptor +underlying @var{port}. + +If there is no foreground process group, the return value is a +number greater than 1 that does not match the process group ID +of any existing process group. This can happen if all of the +processes in the job that was formerly the foreground job have +terminated, and no other job has yet been moved into the +foreground. +@end deffn + +@deffn primitive tcsetpgrp port pgid +Set the foreground process group ID for the terminal used by the file +descriptor underlying @var{port} to the integer @var{pgid}. +The calling process +must be a member of the same session as @var{pgid} and must have the same +controlling terminal. The return value is unspecified. +@end deffn + +@node Pipes +@section Pipes + +The following procedures provide an interface to the @code{popen} and +@code{pclose} system routines. The code is in a separate "popen" +module: + +@smalllisp +(use-modules (ice-9 popen)) +@end smalllisp + +@findex popen +@deffn procedure open-pipe command modes +Executes the shell command @var{command} (a string) in a subprocess. +A pipe to the process is created and returned. @var{modes} specifies +whether an input or output pipe to the process is created: it should +be the value of @code{OPEN_READ} or @code{OPEN_WRITE}. +@end deffn + +@deffn procedure open-input-pipe command +Equivalent to @code{open-pipe} with mode @code{OPEN_READ}. +@end deffn + +@deffn procedure open-output-pipe command +Equivalent to @code{open-pipe} with mode @code{OPEN_WRITE}. +@end deffn + +@findex pclose +@deffn procedure close-pipe port +Closes the pipe created by @code{open-pipe}, then waits for the process +to terminate and returns its status value, @xref{Processes, waitpid}, for +information on how to interpret this value. + +@code{close-port} (@pxref{Closing, close-port}) can also be used to +close a pipe, but doesn't return the status. +@end deffn + +@node Networking +@section Networking + +@menu +* Network Address Conversion:: +* Network Databases:: +* Network Sockets and Communication:: +@end menu + +@node Network Address Conversion +@subsection Network Address Conversion + +This section describes procedures which convert internet addresses +between numeric and string formats. + +@subsubsection IPv4 Address Conversion + +@deffn primitive inet-aton address +Convert an IPv4 Internet address from printable string +(dotted decimal notation) to an integer. E.g., + +@lisp +(inet-aton "127.0.0.1") @result{} 2130706433 +@end lisp +@end deffn + +@deffn primitive inet-ntoa inetid +Convert an IPv4 Internet address to a printable +(dotted decimal notation) string. E.g., + +@lisp +(inet-ntoa 2130706433) @result{} "127.0.0.1" +@end lisp +@end deffn + +@deffn primitive inet-netof address +Return the network number part of the given IPv4 +Internet address. E.g., + +@lisp +(inet-netof 2130706433) @result{} 127 +@end lisp +@end deffn + +@deffn primitive inet-lnaof address +Return the local-address-with-network part of the given +IPv4 Internet address, using the obsolete class A/B/C system. +E.g., + +@lisp +(inet-lnaof 2130706433) @result{} 1 +@end lisp +@end deffn + +@deffn primitive inet-makeaddr net lna +Make an IPv4 Internet address by combining the network number +@var{net} with the local-address-within-network number +@var{lna}. E.g., + +@lisp +(inet-makeaddr 127 1) @result{} 2130706433 +@end lisp +@end deffn + +@subsubsection IPv6 Address Conversion + +@deffn primitive inet-ntop family address +Convert a network address into a printable string. +Note that unlike the C version of this function, +the input is an integer with normal host byte ordering. +@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g., + +@lisp +(inet-ntop AF_INET 2130706433) @result{} "127.0.0.1" +(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{} +ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +@end lisp +@end deffn + +@deffn primitive inet-pton family address +Convert a string containing a printable network address to +an integer address. Note that unlike the C version of this +function, +the result is an integer with normal host byte ordering. +@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g., + +@lisp +(inet-pton AF_INET "127.0.0.1") @result{} 2130706433 +(inet-pton AF_INET6 "::1") @result{} 1 +@end lisp +@end deffn + + +@node Network Databases +@subsection Network Databases + +This section describes procedures which query various network databases. +Care should be taken when using the database routines since they are not +reentrant. + +@subsubsection The Host Database + +A @dfn{host object} is a structure that represents what is known about a +network host, and is the usual way of representing a system's network +identity inside software. + +The following functions accept a host object and return a selected +component: + +@deffn procedure hostent:name host +The "official" hostname for @var{host}. +@end deffn +@deffn procedure hostent:aliases host +A list of aliases for @var{host}. +@end deffn +@deffn procedure hostent:addrtype host +The host address type. For hosts with Internet addresses, this will +return @code{AF_INET}. +@end deffn +@deffn procedure hostent:length host +The length of each address for @var{host}, in bytes. +@end deffn +@deffn procedure hostent:addr-list host +The list of network addresses associated with @var{host}. +@end deffn + +The following procedures are used to search the host database: + +@deffn primitive gethost [host] +@deffnx procedure gethostbyname hostname +@deffnx procedure gethostbyaddr address +Look up a host by name or address, returning a host object. The +@code{gethost} procedure will accept either a string name or an integer +address; if given no arguments, it behaves like @code{gethostent} (see +below). If a name or address is supplied but the address can not be +found, an error will be thrown to one of the keys: +@code{host-not-found}, @code{try-again}, @code{no-recovery} or +@code{no-data}, corresponding to the equivalent @code{h_error} values. +Unusual conditions may result in errors thrown to the +@code{system-error} or @code{misc_error} keys. +@end deffn + +The following procedures may be used to step through the host +database from beginning to end. + +@deffn procedure sethostent [stayopen] +Initialize an internal stream from which host objects may be read. This +procedure must be called before any calls to @code{gethostent}, and may +also be called afterward to reset the host entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{gethostbyname} or @code{gethostbyaddr} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure gethostent +Return the next host object from the host database, or @code{#f} if +there are no more hosts to be found (or an error has been encountered). +This procedure may not be used before @code{sethostent} has been called. +@end deffn + +@deffn procedure endhostent +Close the stream used by @code{gethostent}. The return value is unspecified. +@end deffn + +@deffn primitive sethost [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endhostent}. +Otherwise it is equivalent to @code{sethostent stayopen}. +@end deffn +@subsubsection The Network Database + +The following functions accept an object representing a network +and return a selected component: + +@deffn procedure netent:name net +The "official" network name. +@end deffn +@deffn procedure netent:aliases net +A list of aliases for the network. +@end deffn +@deffn procedure netent:addrtype net +The type of the network number. Currently, this returns only +@code{AF_INET}. +@end deffn +@deffn procedure netent:net net +The network number. +@end deffn + +The following procedures are used to search the network database: + +@deffn primitive getnet [net] +@deffnx procedure getnetbyname net-name +@deffnx procedure getnetbyaddr net-number +Look up a network by name or net number in the network database. The +@var{net-name} argument must be a string, and the @var{net-number} +argument must be an integer. @code{getnet} will accept either type of +argument, behaving like @code{getnetent} (see below) if no arguments are +given. +@end deffn + +The following procedures may be used to step through the network +database from beginning to end. + +@deffn procedure setnetent [stayopen] +Initialize an internal stream from which network objects may be read. This +procedure must be called before any calls to @code{getnetent}, and may +also be called afterward to reset the net entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{getnetbyname} or @code{getnetbyaddr} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure getnetent +Return the next entry from the network database. +@end deffn + +@deffn procedure endnetent +Close the stream used by @code{getnetent}. The return value is unspecified. +@end deffn + +@deffn primitive setnet [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endnetent}. +Otherwise it is equivalent to @code{setnetent stayopen}. +@end deffn + +@subsubsection The Protocol Database + +The following functions accept an object representing a protocol +and return a selected component: + +@deffn procedure protoent:name protocol +The "official" protocol name. +@end deffn +@deffn procedure protoent:aliases protocol +A list of aliases for the protocol. +@end deffn +@deffn procedure protoent:proto protocol +The protocol number. +@end deffn + +The following procedures are used to search the protocol database: + +@deffn primitive getproto [protocol] +@deffnx procedure getprotobyname name +@deffnx procedure getprotobynumber number +Look up a network protocol by name or by number. @code{getprotobyname} +takes a string argument, and @code{getprotobynumber} takes an integer +argument. @code{getproto} will accept either type, behaving like +@code{getprotoent} (see below) if no arguments are supplied. +@end deffn + +The following procedures may be used to step through the protocol +database from beginning to end. + +@deffn procedure setprotoent [stayopen] +Initialize an internal stream from which protocol objects may be read. This +procedure must be called before any calls to @code{getprotoent}, and may +also be called afterward to reset the protocol entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{getprotobyname} or @code{getprotobynumber} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure getprotoent +Return the next entry from the protocol database. +@end deffn + +@deffn procedure endprotoent +Close the stream used by @code{getprotoent}. The return value is unspecified. +@end deffn + +@deffn primitive setproto [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}. +Otherwise it is equivalent to @code{setprotoent stayopen}. +@end deffn + +@subsubsection The Service Database + +The following functions accept an object representing a service +and return a selected component: + +@deffn procedure servent:name serv +The "official" name of the network service. +@end deffn +@deffn procedure servent:aliases serv +A list of aliases for the network service. +@end deffn +@deffn procedure servent:port serv +The Internet port used by the service. +@end deffn +@deffn procedure servent:proto serv +The protocol used by the service. A service may be listed many times +in the database under different protocol names. +@end deffn + +The following procedures are used to search the service database: + +@deffn primitive getserv [name [protocol]] +@deffnx procedure getservbyname name protocol +@deffnx procedure getservbyport port protocol +Look up a network service by name or by service number, and return a +network service object. The @var{protocol} argument specifies the name +of the desired protocol; if the protocol found in the network service +database does not match this name, a system error is signalled. + +The @code{getserv} procedure will take either a service name or number +as its first argument; if given no arguments, it behaves like +@code{getservent} (see below). +@end deffn + +The following procedures may be used to step through the service +database from beginning to end. + +@deffn procedure setservent [stayopen] +Initialize an internal stream from which service objects may be read. This +procedure must be called before any calls to @code{getservent}, and may +also be called afterward to reset the service entry stream. If +@var{stayopen} is supplied and is not @code{#f}, the database is not +closed by subsequent @code{getservbyname} or @code{getservbyport} calls, +possibly giving an efficiency gain. +@end deffn + +@deffn procedure getservent +Return the next entry from the services database. +@end deffn + +@deffn procedure endservent +Close the stream used by @code{getservent}. The return value is unspecified. +@end deffn + +@deffn primitive setserv [stayopen] +If @var{stayopen} is omitted, this is equivalent to @code{endservent}. +Otherwise it is equivalent to @code{setservent stayopen}. +@end deffn + +@node Network Sockets and Communication +@subsection Network Sockets and Communication + +Socket ports can be created using @code{socket} and @code{socketpair}. +The ports are initially unbuffered, to make reading and writing to the +same port more reliable. A buffer can be added to the port using +@code{setvbuf}, @xref{Ports and File Descriptors}. + +The convention used for "host" vs "network" addresses is that addresses +are always held in host order at the Scheme level. The procedures in +this section automatically convert between host and network order when +required. The arguments and return values are thus in host order. + +@deffn primitive socket family style proto +Return a new socket port of the type specified by @var{family}, +@var{style} and @var{proto}. All three parameters are +integers. Supported values for @var{family} are +@code{AF_UNIX}, @code{AF_INET} and @code{AF_INET6}. +Typical values for @var{style} are @code{SOCK_STREAM}, +@code{SOCK_DGRAM} and @code{SOCK_RAW}. + +@var{proto} can be obtained from a protocol name using +@code{getprotobyname}. A value of zero specifies the default +protocol, which is usually right. + +A single socket port cannot by used for communication until it +has been connected to another socket. +@end deffn + +@deffn primitive socketpair family style proto +Return a pair of connected (but unnamed) socket ports of the +type specified by @var{family}, @var{style} and @var{proto}. +Many systems support only socket pairs of the @code{AF_UNIX} +family. Zero is likely to be the only meaningful value for +@var{proto}. +@end deffn + +@deffn primitive getsockopt sock level optname +Return the value of a particular socket option for the socket +port @var{sock}. @var{level} is an integer code for type of +option being requested, e.g., @code{SOL_SOCKET} for +socket-level options. @var{optname} is an integer code for the +option required and should be specified using one of the +symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc. + +The returned value is typically an integer but @code{SO_LINGER} +returns a pair of integers. +@end deffn + +@deffn primitive setsockopt sock level optname value +Set the value of a particular socket option for the socket +port @var{sock}. @var{level} is an integer code for type of option +being set, e.g., @code{SOL_SOCKET} for socket-level options. +@var{optname} is an +integer code for the option to set and should be specified using one of +the symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc. +@var{value} is the value to which the option should be set. For +most options this must be an integer, but for @code{SO_LINGER} it must +be a pair. + +The return value is unspecified. +@end deffn + +@deffn primitive shutdown sock how +Sockets can be closed simply by using @code{close-port}. The +@code{shutdown} procedure allows reception or tranmission on a +connection to be shut down individually, according to the parameter +@var{how}: + +@table @asis +@item 0 +Stop receiving data for this socket. If further data arrives, reject it. +@item 1 +Stop trying to transmit data from this socket. Discard any +data waiting to be sent. Stop looking for acknowledgement of +data already sent; don't retransmit it if it is lost. +@item 2 +Stop both reception and transmission. +@end table + +The return value is unspecified. +@end deffn + +@deffn primitive connect sock fam address . args +Initiate a connection from a socket using a specified address +family to the address +specified by @var{address} and possibly @var{args}. +The format required for @var{address} +and @var{args} depends on the family of the socket. + +For a socket of family @code{AF_UNIX}, +only @var{address} is specified and must be a string with the +filename where the socket is to be created. + +For a socket of family @code{AF_INET}, +@var{address} must be an integer IPv4 host address and +@var{args} must be a single integer port number. + +For a socket of family @code{AF_INET6}, +@var{address} must be an integer IPv6 host address and +@var{args} may be up to three integers: +port [flowinfo] [scope_id], +where flowinfo and scope_id default to zero. + +The return value is unspecified. +@end deffn + +@deffn primitive bind sock fam address . args +Assign an address to the socket port @var{sock}. +Generally this only needs to be done for server sockets, +so they know where to look for incoming connections. A socket +without an address will be assigned one automatically when it +starts communicating. + +The format of @var{address} and @var{args} depends +on the family of the socket. + +For a socket of family @code{AF_UNIX}, only @var{address} +is specified and must be a string with the filename where +the socket is to be created. + +For a socket of family @code{AF_INET}, @var{address} +must be an integer IPv4 address and @var{args} +must be a single integer port number. + +The values of the following variables can also be used for +@var{address}: + +@defvar INADDR_ANY +Allow connections from any address. +@end defvar + +@defvar INADDR_LOOPBACK +The address of the local host using the loopback device. +@end defvar + +@defvar INADDR_BROADCAST +The broadcast address on the local network. +@end defvar + +@defvar INADDR_NONE +No address. +@end defvar + +For a socket of family @code{AF_INET6}, @var{address} +must be an integer IPv6 address and @var{args} +may be up to three integers: +port [flowinfo] [scope_id], +where flowinfo and scope_id default to zero. + +The return value is unspecified. +@end deffn + +@deffn primitive listen sock backlog +Enable @var{sock} to accept connection +requests. @var{backlog} is an integer specifying +the maximum length of the queue for pending connections. +If the queue fills, new clients will fail to connect until +the server calls @code{accept} to accept a connection from +the queue. + +The return value is unspecified. +@end deffn + +@deffn primitive accept sock +Accept a connection on a bound, listening socket. +If there +are no pending connections in the queue, wait until +one is available unless the non-blocking option has been +set on the socket. + +The return value is a +pair in which the @emph{car} is a new socket port for the +connection and +the @emph{cdr} is an object with address information about the +client which initiated the connection. + +@var{sock} does not become part of the +connection and will continue to accept new requests. +@end deffn + +The following functions take a socket address object, as returned +by @code{accept} and other procedures, and return a selected component. + +@table @code +@item sockaddr:fam +The socket family, typically equal to the value of @code{AF_UNIX} or +@code{AF_INET}. +@item sockaddr:path +If the socket family is @code{AF_UNIX}, returns the path of the +filename the socket is based on. +@item sockaddr:addr +If the socket family is @code{AF_INET}, returns the Internet host +address. +@item sockaddr:port +If the socket family is @code{AF_INET}, returns the Internet port +number. +@end table + +@deffn primitive getsockname sock +Return the address of @var{sock}, in the same form as the +object returned by @code{accept}. On many systems the address +of a socket in the @code{AF_FILE} namespace cannot be read. +@end deffn + +@deffn primitive getpeername sock +Return the address that @var{sock} +is connected to, in the same form as the object returned by +@code{accept}. On many systems the address of a socket in the +@code{AF_FILE} namespace cannot be read. +@end deffn + +@deffn primitive recv! sock buf [flags] +Receive data from a socket port. +@var{sock} must already +be bound to the address from which data is to be received. +@var{buf} is a string into which +the data will be written. The size of @var{buf} limits +the amount of +data which can be received: in the case of packet +protocols, if a packet larger than this limit is encountered +then some data +will be irrevocably lost. + +The optional @var{flags} argument is a value or +bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc. + +The value returned is the number of bytes read from the +socket. + +Note that the data is read directly from the socket file +descriptor: +any unread buffered port data is ignored. +@end deffn + +@deffn primitive send sock message [flags] +Transmit the string @var{message} on a socket port @var{sock}. +@var{sock} must already be bound to a destination address. The +value returned is the number of bytes transmitted -- +it's possible for +this to be less than the length of @var{message} +if the socket is +set to be non-blocking. The optional @var{flags} argument +is a value or +bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc. + +Note that the data is written directly to the socket +file descriptor: +any unflushed buffered port data is ignored. +@end deffn + +@deffn primitive recvfrom! sock str [flags [start [end]]] +Return data from the socket port @var{sock} and also +information about where the data was received from. +@var{sock} must already be bound to the address from which +data is to be received. @code{str}, is a string into which the +data will be written. The size of @var{str} limits the amount +of data which can be received: in the case of packet protocols, +if a packet larger than this limit is encountered then some +data will be irrevocably lost. + +The optional @var{flags} argument is a value or bitwise OR of +@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc. + +The value returned is a pair: the @emph{car} is the number of +bytes read from the socket and the @emph{cdr} an address object +in the same form as returned by @code{accept}. The address +will given as @code{#f} if not available, as is usually the +case for stream sockets. + +The @var{start} and @var{end} arguments specify a substring of +@var{str} to which the data should be written. + +Note that the data is read directly from the socket file +descriptor: any unread buffered port data is ignored. +@end deffn + +@deffn primitive sendto sock message fam address . args_and_flags +Transmit the string @var{message} on the socket port +@var{sock}. The +destination address is specified using the @var{fam}, +@var{address} and +@var{args_and_flags} arguments, in a similar way to the +@code{connect} procedure. @var{args_and_flags} contains +the usual connection arguments optionally followed by +a flags argument, which is a value or +bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc. + +The value returned is the number of bytes transmitted -- +it's possible for +this to be less than the length of @var{message} if the +socket is +set to be non-blocking. +Note that the data is written directly to the socket +file descriptor: +any unflushed buffered port data is ignored. +@end deffn + +The following functions can be used to convert short and long integers +between "host" and "network" order. Although the procedures above do +this automatically for addresses, the conversion will still need to +be done when sending or receiving encoded integer data from the network. + +@deffn primitive htons value +Convert a 16 bit quantity from host to network byte ordering. +@var{value} is packed into 2 bytes, which are then converted +and returned as a new integer. +@end deffn + +@deffn primitive ntohs value +Convert a 16 bit quantity from network to host byte ordering. +@var{value} is packed into 2 bytes, which are then converted +and returned as a new integer. +@end deffn + +@deffn primitive htonl value +Convert a 32 bit quantity from host to network byte ordering. +@var{value} is packed into 4 bytes, which are then converted +and returned as a new integer. +@end deffn + +@deffn primitive ntohl value +Convert a 32 bit quantity from network to host byte ordering. +@var{value} is packed into 4 bytes, which are then converted +and returned as a new integer. +@end deffn + +These procedures are inconvenient to use at present, but consider: + +@example +(define write-network-long + (lambda (value port) + (let ((v (make-uniform-vector 1 1 0))) + (uniform-vector-set! v 0 (htonl value)) + (uniform-vector-write v port)))) + +(define read-network-long + (lambda (port) + (let ((v (make-uniform-vector 1 1 0))) + (uniform-vector-read! v port) + (ntohl (uniform-vector-ref v 0))))) +@end example + +@node System Identification +@section System Identification + +This section lists the various procedures Guile provides for accessing +information about the system it runs on. + +@deffn primitive uname +Return an object with some information about the computer +system the program is running on. +@end deffn + +The following procedures accept an object as returned by @code{uname} +and return a selected component. + +@table @code +@item utsname:sysname +The name of the operating system. +@item utsname:nodename +The network name of the computer. +@item utsname:release +The current release level of the operating system implementation. +@item utsname:version +The current version level within the release of the operating system. +@item utsname:machine +A description of the hardware. +@end table + +@deffn primitive gethostname +Return the host name of the current processor. +@end deffn + +@deffn primitive sethostname name +Set the host name of the current processor to @var{name}. May +only be used by the superuser. The return value is not +specified. +@end deffn + +@c FIXME::martin: Not in libguile! +@deffn primitive software-type +Return a symbol describing the current platform's operating system. +This may be one of AIX, VMS, UNIX, COHERENT, WINDOWS, MS-DOS, OS/2, +THINKC, AMIGA, ATARIST, MACH, or ACORN. + +Note that most varieties of Unix are considered to be simply "UNIX". +That is because when a program depends on features that are not present +on every operating system, it is usually better to test for the presence +or absence of that specific feature. The return value of +@code{software-type} should only be used for this purpose when there is +no other easy or unambiguous way of detecting such features. +@end deffn + +@node Locales +@section Locales + +@deffn primitive setlocale category [locale] +If @var{locale} is omitted, return the current value of the +specified locale category as a system-dependent string. +@var{category} should be specified using the values +@code{LC_COLLATE}, @code{LC_ALL} etc. + +Otherwise the specified locale category is set to the string +@var{locale} and the new value is returned as a +system-dependent string. If @var{locale} is an empty string, +the locale will be set using envirionment variables. +@end deffn + +@node Encryption +@section Encryption + +Please note that the procedures in this section are not suited for +strong encryption, they are only interfaces to the well-known and +common system library functions of the same name. They are just as good +(or bad) as the underlying functions, so you should refer to your system +documentation before using them. + +@deffn primitive crypt key salt +Encrypt @var{key} using @var{salt} as the salt value to the +crypt(3) library call +@end deffn + +@code{getpass} is no encryption procedure at all, but it is often used +in compination with @code{crypt}, that is why it appears in this +section. + +@deffn primitive getpass prompt +Display @var{prompt} to the standard error output and read +a password from @file{/dev/tty}. If this file is not +accessible, it reads from standard input. The password may be +up to 127 characters in length. Additional characters and the +terminating newline character are discarded. While reading +the password, echoing and the generation of signals by special +characters is disabled. +@end deffn diff --git a/doc/ref/preface.texi b/doc/ref/preface.texi new file mode 100644 index 000000000..90e53e9ac --- /dev/null +++ b/doc/ref/preface.texi @@ -0,0 +1,182 @@ +@iftex +@page +@unnumbered 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 1.0 of the reference manual, and corresponds to Guile +version @value{VERSION}. +@end iftex + + +@iftex +@section The Guile License +@end iftex + +@ifnottex +@node Guile License +@chapter The Guile License +@end ifnottex + +The license of Guile consists of the GNU GPL plus a special statement +giving blanket permission to link with non-free software. This is the +license statement as found in any individual file that it applies to: + +@quotation +This program 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 (at your option) any +later version. + +This program 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. + +You should have received a copy of the GNU General Public License along +with this software; see the file COPYING. If not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA + +As a special exception, the Free Software Foundation gives permission +for additional uses of the text contained in its release of GUILE. + +The exception is that, if you link the GUILE library with other files to +produce an executable, this does not by itself cause the resulting +executable to be covered by the GNU General Public License. Your use of +that executable is in no way restricted on account of linking the GUILE +library code into it. + +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. + +This exception applies only to the code released by the Free Software +Foundation under the name GUILE. If you copy code from other Free +Software Foundation releases into a copy of GUILE, as the General Public +License permits, the exception does not apply to the code that you add +in this way. To avoid misleading anyone as to the status of such +modified files, you must delete this exception notice from them. + +If you write modifications of your own for GUILE, it is your choice +whether to permit this exception to apply to your modifications. If you +do not wish that, delete this exception notice. +@end quotation + + +@iftex +@section Layout of this Manual +@end iftex + +@ifnottex +@node Manual Layout +@chapter Layout of this Manual +@end ifnottex + +This manual is divided into five parts. + +@strong{Part I: Introduction to Guile} provides an overview of what +Guile is and how you can use it. A whirlwind tour shows how Guile can +be used interactively and as a script interpreter, how to link Guile +into your own applications, and how to write modules of interpreted and +compiled code for use with Guile. All of the ideas introduced here are +documented in full by the later parts of the manual. + +@strong{Part II: Guile Scheme} documents the core Scheme language and +features that Guile implements. Although the basis for this is the +Scheme language described in R5RS, this part of the manual does not +assume any prior familiarity with R5RS in particular, or with Scheme in +general. Basic Scheme concepts, standard aspects of the Scheme language +and Guile extensions on top of R5RS are all documented from scratch, and +organized by functionality rather than by the defining standards. + +@strong{Part III: Guile Modules} describes some important modules, +distributed as part of the Guile distribution, that extend the +functionality provided by the Guile Scheme core, most notably: + +@itemize @bullet +@item +the POSIX module, which provides Scheme level procedures for system and +network programming, conforming to the POSIX standard + +@item +the SLIB module, which makes Aubrey Jaffer's portable Scheme library +available for use in Guile. +@end itemize + +@strong{Part IV: Guile Scripting} documents the use of Guile as a script +interpreter, and illustrates this with a series of examples. + +@strong{Part V: Extending Applications Using Guile} explains the options +available for using Guile as a application extension language. At the +simpler end of the scale, an application might use Guile to define some +application-specific primitives in C and then load an application Scheme +file. In this case most of the application code is written on the +Scheme level, and uses the application-specific primitives as an +extension to standard Scheme. At the other end of the scale, an +application might be predominantly written in C --- with its main +control loop implemented in C --- but make occasional forays into Scheme +to, say, read configuration data or run user-defined customization code. +This part of the manual covers the complete range of application +extension options. + +Finally, the appendices explain how to obtain the latest version of +Guile, how to install it, where to find modules to work with Guile, and +how to use the Guile debugger. + + +@iftex +@section Manual Conventions +@end iftex + +@ifnottex +@node Manual Conventions +@chapter Conventions used in this Manual +@end ifnottex + +We use some conventions in this manual. + +@itemize @bullet + +@item +For some procedures, notably type predicates, we use @dfn{iff} to +mean `if and only if'. The construct is usually something like: +`Return @var{val} iff @var{condition}', where @var{val} is usually +`@code{#t}' or `non-@code{#f}'. This typically means that @var{val} +is returned if @var{condition} holds, and that @samp{#f} is returned +otherwise. +@cindex iff + +@item +In examples and procedure descriptions and all other places where the +evaluation of Scheme expression is shown, we use some notation for +denoting the output and evaluation results of expressions. + +The symbol @code{@result{}} is used to tell which value is returned by +an evaluation: + +@lisp +(+ 1 2) +@result{} +3 +@end lisp + +Some procedures produce some output besides returning a value. This +is denoted by the symbol @code{@print{}}. + +@lisp +(begin (display 1) (newline) 'hooray) +@print{} 1 +@result{} +hooray +@end lisp + +@c Add other conventions here. + +@end itemize + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/repl-modules.texi b/doc/ref/repl-modules.texi new file mode 100644 index 000000000..fdefbf755 --- /dev/null +++ b/doc/ref/repl-modules.texi @@ -0,0 +1,131 @@ +@page +@node Readline Support +@chapter Readline Support + +@c FIXME::martin: Review me! + +@cindex readline +@cindex command line history +Guile comes with an interface module to the readline library. This +makes interactive use much more convenient, because of the command-line +editing features of readline. Using @code{(ice-9 readline)}, you can +navigate through the current input line with the cursor keys, retrieve +older command lines from the input history and even search through the +history entries. + +@menu +* Loading Readline Support:: How to load readline support into Guile. +* Readline Options:: How to modify readline's behaviour. +@end menu + + +@node Loading Readline Support +@section Loading Readline Support + +The module is not loaded by default and so has to be loaded and +activated explicitly. This is done with two simple lines of code: + +@lisp +(use-modules (ice-9 readline)) +(activate-readline) +@end lisp + +@c FIXME::martin: Review me! + +The first line will load the necessary code, and the second will +activate readline's features for the REPL. If you plan to use this +module often, you should save these to lines to your @file{.guile} +personal startup file. + +You will notice that the REPL's behaviour changes a bit when you have +loaded the readline module. For examle, when you press Enter before +typing in the closing parentheses of a list, you will see the +@dfn{continuation} prompt, three dots: @code{...} This gives you a nice +visual feedback when trying to match parentheses. To make this even +easier, @dfn{bouncing parentheses} are implemented. That means that +when you type in a closing parentheses, the cursor will jump to the +corresponding opening paren for a short time, making it trivial to make +them match. + +Once the readline module is activated, all lines entered interactively +will be stored in a history and can be recalled later using the +cursor-up and -down keys. Readline also understands the Emacs keys for +navigating through the command line and history. + +When you quit your Guile session by evaluating @code{(quit)} or pressing +Ctrl-D, the history will be saved to the file @file{.guile_history} and +read in when you start Guile for the next time. Thus you can start a +new Guile session and still have the (probably long-winded) definition +expressions available. + + +@node Readline Options +@section Readline Options + +@c FIXME::martin: Review me! + +@cindex readline options +The readline interface module can be configured in several ways to +better suit the user's needs. Configuration is done via the readline +module's options interface, in a similar way to the evaluator and +debugging options (@pxref{General option interface}.) + +Here is the list of readline options generated by typing +@code{(readline-options 'full)} in Guile. You can also see the +default values. + +@smalllisp +bounce-parens 500 Time (ms) to show matching opening parenthesis (0 = off). +history-length 200 History length. +history-file yes Use history file. +@end smalllisp + +The history length specifies how many input lines will be remembered. +If the history contains that many lines and additional lines are +entered, the oldest lines will be lost. You can switch on/off the +usage of the history file using the following call. + +@lisp +(readline-disable 'history) +@end lisp + +The readline options interface can only be used @emph{after} loading +the readline module, because it is defined in that module. + + +@page +@node Value History +@chapter Value History + +@c FIXME::martin: Review me! + +@cindex value history +Another module which makes command line usage more convenient is +@code{(ice-9 history)}. This module will change the REPL so that each +value which is evaluated and printed will be remembered under a name +constructed from the dollar character (@code{$}) and the number of the +evaluated expression. + +Consider an example session. + +@example +guile> (use-modules (ice-9 history)) +guile> 1 +$1 = 1 +guile> (+ $1 $1) +$2 = 2 +guile> (* $2 $2) +$3 = 4 +@end example + +After loading the value history module @code{(ice-9 history)}, one +(trivial) expression is evaluated. The result is stored into the +variable @code{$1}. This fact is indicated by the output @code{$1 = }, +which is also caused by @code{(ice-9 history)}. In the next line, this +variable is used two times, to produce the value @code{$2}, which in +turn is used in the calculation for @code{$3}. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-binding.texi b/doc/ref/scheme-binding.texi new file mode 100644 index 000000000..b37bced03 --- /dev/null +++ b/doc/ref/scheme-binding.texi @@ -0,0 +1,242 @@ +@page +@node Binding Constructs +@chapter Definitions and Variable Bindings + +@c FIXME::martin: Review me! + +Scheme supports the definition of variables in different contexts. +Variables can be defined at the top level, so that they are visible in +the entire program, and variables can be defined locally to procedures +and expressions. This is important for modularity and data abstraction. + +@menu +* Top Level:: Top level variable definitions. +* Local Bindings:: Local variable bindings. +* Internal Definitions:: Internal definitions. +* Binding Reflection:: Querying variable bindings. +@end menu + + +@node Top Level +@section Top Level Variable Definitions + +@c FIXME::martin: Review me! + +@cindex variable definition + +On the top level of a program (e.g. when not inside of a procedure +definition or a @code{let}, @code{let*} or @code{letrec} expression), a +definition of the form + +@lisp +(define a 1) +@end lisp + +@noindent +defines a variable called @var{a} and sets it to the value 1. When the +variable already was bound with a @code{define} expression, the above +form is completely equivalent to + +@lisp +(set! a 1) +@end lisp + +@noindent +that means that @code{define} can be used interchangeably with +@code{set!} when at the top level of the REPL or a Scheme source file. +But note that a @code{set!} is not allowed if the variable was not bound +before. + +Attention: definitions inside local binding constructs (@pxref{Local +Bindings}) act differently (@pxref{Internal Definitions}). + + +@node Local Bindings +@section Local Variable Bindings + +@c FIXME::martin: Review me! + +@cindex local bindings +@cindex local variables + +As opposed to definitions at the top level, which are visible in the +whole program (or current module, when Guile modules are used), it is +also possible to define variables which are only visible in a +well-defined part of the program. Normally, this part of a program +will be a procedure or a subexpression of a procedure. + +With the constructs for local binding (@code{let}, @code{let*} and +@code{letrec}), the Scheme language has a block structure like most +other programming languages since the days of @sc{Algol 60}. Readers +familiar to languages like C or Java should already be used to this +concept, but the family of @code{let} expressions has a few properties +which are well worth knowing. + +The first local binding construct is @code{let}. The other constructs +@code{let*} and @code{letrec} are specialized versions for usage where +using plain @code{let} is a bit inconvenient. + +@deffn syntax let bindings body +@var{bindings} has the form + +@lisp +((@var{variable1} @var{init1}) @dots{}) +@end lisp + +that is zero or more two-element lists of a variable and an arbitrary +expression each. All @var{variable} names must be distinct. + +A @code{let} expression is evaluated as follows. + +@itemize @bullet +@item +All @var{init} expressions are evaluated. + +@item +New storage is allocated for the @var{variables}. + +@item +The values of the @var{init} expressions are stored into the variables. + +@item +The expressions in @var{body} are evaluated in order, and the value of +the last expression is returned as the value of the @code{let} +expression. + +@item +The storage for the @var{variables} is freed. +@end itemize + +The @var{init} expressions are not allowed to refer to any of the +@var{variables}. +@end deffn + +@deffn syntax let* bindings body +Similar to @code{let}, but the variable bindings are performed +sequentially, that means that all @var{init} expression are allowed to +use the variables defined on their left in the binding list. + +A @code{let*} expression can always be expressed with nested @code{let} +expressions. + +@lisp +(let* ((a 1) (b a)) + b) +@equiv{} +(let ((a 1)) + (let ((b a)) + b)) +@end lisp +@end deffn + +@deffn syntax letrec bindings body +Similar to @code{let}, but it is possible to refer to the @var{variable} +from lambda expression created in any of the @var{inits}. That is, +procedures created in the @var{init} expression can recursively refer to +the defined variables. + +@lisp +(letrec ((even? + (lambda (n) + (if (zero? n) + #t + (odd? (- n 1))))) + (odd? + (lambda (n) + (if (zero? n) + #f + (even? (- n 1)))))) + (even? 88)) +@result{} +#t +@end lisp +@end deffn + +There is also an alternative form of the @code{let} form, which is used +for expressing iteration. Because of the use as a looping construct, +this form (the @dfn{named let}) is documented in the section about +iteration (@pxref{while do, Iteration}) + +@node Internal Definitions +@section Internal definitions + +@c FIXME::martin: Review me! + +A @code{define} form which appears inside the body of a @code{lambda}, +@code{let}, @code{let*}, @code{letrec} or equivalent expression is +called an @dfn{internal definition}. An internal definition differs +from a top level definition (@pxref{Top Level}), because the definition +is only visible inside the complete body of the enclosing form. Let us +examine the following example. + +@lisp +(let ((frumble "froz")) + (define banana (lambda () (apple 'peach))) + (define apple (lambda (x) x)) + (banana)) +@result{} +peach +@end lisp + +Here the enclosing form is a @code{let}, so the @code{define}s in the +@code{let}-body are internal definitions. Because the scope of the +internal definitions is the @strong{complete} body of the +@code{let}-expression, the @code{lambda}-expression which gets bound +to the variable @code{banana} may refer to the variable @code{apple}, +even thogh it's definition appears lexically @emph{after} the definition +of @code{banana}. This is because a sequence of internal definition +acts as if it were a @code{letrec} expression. + +@lisp +(let () + (define a 1) + (define b 2) + (+ a b)) +@end lisp + +@noindent +is equivalent to + +@lisp +(let () + (letrec ((a 1) (b 2)) + (+ a b))) +@end lisp + +Another noteworthy difference to top level definitions is that within +one group of internal definitions all variable names must be distinct. +That means where on the top level a second define for a given variable +acts like a @code{set!}, an exception is thrown for internal definitions +with duplicate bindings. + +@c FIXME::martin: The following is required by R5RS, but Guile does not +@c signal an error. Document it anyway, saying that Guile is sloppy? + +@c Internal definitions are only allowed at the beginning of the body of an +@c enclosing expression. They may not be mixed with other expressions. + +@c @lisp +@c (let () +@c (define a 1) +@c a +@c (define b 2) +@c b) +@c @end lisp + +@node Binding Reflection +@section Querying variable bindings + +Guile provides a procedure for checking wehther a symbol is bound in the +top level environment. If you want to test whether a symbol is locally +bound in expression, you can use the @code{bound?} macro from the module +@code{(ice-9 optargs)}, documented in @ref{Optional Arguments}. + +@c NJFIXME explain [env] +@deffn primitive defined? sym [env] +Return @code{#t} if @var{sym} is defined in the top-level environment. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-control.texi b/doc/ref/scheme-control.texi new file mode 100644 index 000000000..dd5f9be53 --- /dev/null +++ b/doc/ref/scheme-control.texi @@ -0,0 +1,823 @@ +@page +@node Control Mechanisms +@chapter Controlling the Flow of Program Execution + +@menu +* begin:: Evaluating a sequence of expressions. +* if cond case:: Simple conditional evaluation. +* and or:: Conditional evaluation of a sequence. +* while do:: Iteration mechanisms. +* Continuations:: Continuations. +* Multiple Values:: Returning and accepting multiple values. +* Exceptions:: Throwing and catching exceptions. +* Error Reporting:: Procedures for signaling errors. +* Dynamic Wind:: Guarding against non-local entrance/exit. +@end menu + + +@node begin +@section Evaluating a Sequence of Expressions + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@cindex begin +@cindex sequencing +@cindex expression sequencing + +@code{begin} is used for grouping several expression together so that +they syntactically are treated as if they were one expression. This is +particularly important when syntactic expressions are used which only +allow one expression, but the programmer wants to use more than one +expression in that place. As an example, consider the conditional +expression below: + +@lisp +(if (> x 0) + (begin (display "greater") (newline))) +@end lisp + +If the two calls to @code{display} and @code{newline} were not embedded +in a @code{begin}-statement, the call to @code{newline} would get +misinterpreted as the else-branch of the @code{if}-expression. + +@deffn syntax begin expr1 expr2 @dots{} +The expression(s) are evaluated in left-to-right order and the value +of the last expression is returned as the value of the +@code{begin}-expression. This expression type is used when the +expressions before the last one are evaluated for their side effects. +@end deffn + +@node if cond case +@section Simple Conditional Evaluation + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@cindex conditional evaluation +@cindex if +@cindex case +@cindex cond + +Guile provides three syntactic constructs for conditional evaluation. +@code{if} is the normal if-then-else expression (with an optional else +branch), @code{cond} is a conditional expression with multiple branches +and @code{case} branches if an expression has one of a set of constant +values. + +@deffn syntax if test consequent [alternate] +All arguments may be arbitrary expressions. First, @var{test} is +evaluated. If it returns a true value, the expression @var{consequent} +is evaluated and @var{alternate} is ignoret. If @var{test} evaluates to +@code{#f}, @var{alternate} is evaluated instead. The value of the +evaluated branch (@var{consequent} or @var{alternate}) is returned as +the value of the @code{if} expression. + +When @var{alternate} is omitted and the @var{test} evaluates to +@code{#f}, the value of the expression is not specified. +@end deffn + +@deffn syntax cond clause1 clause2 @dots{} +Each @code{cond}-clause must look like this: + +@lisp +(@var{test} @var{expression} @dots{}) +@end lisp + +where @var{test} and @var{expression} are arbitrary expression, or like +this + +@lisp +(@var{test} => @var{expression} +@end lisp + +where @var{expression} must evaluate to a procedure. + +The @var{test}s of the clauses are evaluated in order and as soon as one +of them evaluates to a true values, the corresponding @var{expression}s +are evaluated in order and the last value is returned as the value of +the @code{cond}-expression. For the @code{=>} clause type, +@var{expression} is evaluated and the resulting procedure is applied to +the value of @var{test}. The result of this procedure application is +then the result of the @code{cond}-expression. + +The @var{test} of the last @var{clause} may be the keyword @code{else}. +Then, if none of the preceding @var{test}s is true, the @var{expression}s following the @code{else} are evaluated to produce the result of the @code{cond}-expression. +@end deffn + +@deffn syntax case key clause1 clause2 @dots{} +@var{key} may be any expression, the @var{clause}s must have the form + +@lisp +((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{}) +@end lisp + +and the last @var{clause} may have the form + +@lisp +(else @var{expr1} @var{expr2} @dots{}) +@end lisp + +All @var{datum}s must be distinct. First, @var{key} is evaluated. The +the result of this evaluation is compared against all @var{datum}s using +@code{eqv?}. When this comparison succeeds, the epression(s) following +the @var{datum} are evaluated from left to right, returning the value of +the last expression as the result of the @code{case} expression. + +If the @var{key} matches no @var{datum} and there is an +@code{else}-clause, the expressions following the @code{else} are +evaluated. If there is no such clause, the result of the expression is +unspecified. +@end deffn + + +@node and or +@section Conditional Evaluation of a Sequence of Expressions + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@code{and} and @code{or} evaluate all their arguments, similar to +@code{begin}, but evaluation stops as soon as one of the expressions +evaluates to false or true, respectively. + +@deffn syntax and expr @dots{} +Evaluate the @var{expr}s from left to right and stop evaluation as soon +as one expression evaluates to @code{#f}; the remaining expressions are +not evaluated. The value of the last evaluated expression is returned. +If no expression evaluates to @code{#f}, the value of the last +expression is returned. + +If used without expressions, @code{#t} is returned. +@end deffn + +@deffn syntax or expr @dots{} +Evaluate the @var{expr}s from left to right and stop evaluation as soon +as one expression evaluates to a true value (that is, a value different +from @code{#f}); the remaining expressions are not evaluated. The value +of the last evaluated expression is returned. If all expressions +evaluate to @code{#f}, @code{#f} is returned. + +If used without expressions, @code{#f} is returned. +@end deffn + + +@node while do +@section Iteration mechanisms + +@c FIXME::martin: Review me! + +@c FIXME::martin: Maybe add examples? + +@cindex iteration +@cindex looping +@cindex named let + +Scheme has only few iteration mechanisms, mainly because iteration in +Scheme programs is normally expressed using recursion. Nevertheless, +R5RS defines a construct for programming loops, calling @code{do}. In +addition, Guile has an explicit looping syntax called @code{while}. + +@deffn syntax do ((variable1 init1 step1) @dots{}) (test expr @dots{}) command @dots{} +The @var{init} expressions are evaluated and the @var{variables} are +bound to their values. Then looping starts with testing the @var{test} +expression. If @var{test} evaluates to a true value, the @var{expr} +following the @var{test} are evaluated and the value of the last +@var{expr} is returned as the value of the @code{do} expression. If +@var{test} evaluates to false, the @var{command}s are evaluated in +order, the @var{step}s are evaluated and stored into the @var{variables} +and the next iteration starts. + +Any of the @var{step} expressions may be omitted, so that the +corresponding variable is not changed during looping. +@end deffn + +@deffn syntax while cond body @dots{} +Evaluate all expressions in @var{body} in order, as long as @var{cond} +evaluates to a true value. The @var{cond} expression is tested before +every iteration, so that the body is not evaluated at all if @var{cond} +is @code{#f} right from the start. +@end deffn + +@cindex named let +Another very common way of expressing iteration in Scheme programs is +the use of the so-called @dfn{named let}. + +Named let is a variant of @code{let} which creates a procedure and calls +it in one step. Because of the newly created procedure, named let is +more powerful than @code{do}--it can be used for iteration, but also +for arbitrary recursion. + +@deffn syntax let variable bindings body +For the definition of @var{bindings} see the documentation about +@code{let} (@pxref{Local Bindings}). + +Named @code{let} works as follows: + +@itemize @bullet +@item +A new procedure which accepts as many arguments as are in @var{bindings} +is created and bound locally (using @code{let}) to @var{variable}. The +new procedure's formal argument names are the name of the +@var{variables}. + +@item +The @var{body} expressions are inserted into the newly created procedure. + +@item +The procedure is called with the @var{init} expressions as the formal +arguments. +@end itemize + +The next example implements a loop which iterates (by recursion) 1000 +times. + +@lisp +(let lp ((x 1000)) + (if (positive? x) + (lp (- x 1)) + x)) +@result{} +0 +@end lisp +@end deffn + + +@node Continuations +@section Continuations + +@cindex call/cc +@cindex call-with-current-continuation +The ability to explicitly capture continuations using +@code{call-with-current-continuation} (also often called @code{call/cc} +for short), and to invoke such continuations later any number of times, +and from any other point in a program, provides maybe the most powerful +control structure known. All other control structures, such as loops +and coroutines, can be emulated using continuations. + +@c NJFIXME - need a little something here about what continuations are +@c and what they do for you. + +The implementation of continuations in Guile is not as efficient as one +might hope, because it is constrained by the fact that Guile is designed +to cooperate with programs written in other languages, such as C, which +do not know about continuations. So continuations should be used when +there is no other simple way of achieving the desired behaviour, or +where the advantages of the elegant continuation mechanism outweigh the +need for optimum performance. If you find yourself using @code{call/cc} +for escape procedures and your program is running too slow, you might +want to use exceptions (@pxref{Exceptions}) instead. + +@rnindex call-with-current-continuation +@deffn primitive call-with-current-continuation proc +Capture the current continuation and call @var{proc} with the captured +continuation as the single argument. This continuation can then be +called with arbitrarily many arguments. Such a call will work like a +goto to the invocation location of +@code{call-with-current-continuation}, passing the arguments in a way +that they are returned by the call to +@code{call-with-current-continuation}. Since it is legal to store the +captured continuation in a variable or to pass it to other procedures, +it is possible that a procedure returns more than once, even if it is +called only one time. This can be confusing at times. +@end deffn + +@c FIXME::martin: Better example needed. +@lisp +(define kont #f) +(call-with-current-continuation + (lambda (k) + (set! kont k) + 1)) +@result{} +1 + +(kont 2) +@result{} +2 +@end lisp + + +@node Multiple Values +@section Returning and Accepting Multiple Values + +@c FIXME::martin: Review me! +@cindex multiple values +@cindex receive + +Scheme allows a procedure to return more than one value to its caller. +This is quite different to other languages which only allow +single-value returns. Returning multiple values is different from +returning a list (or pair or vector) of values to the caller, because +conceptionally not @emph{one} compound object is returned, but several +distinct values. + +The primitive procedures for handling multiple values are @code{values} +and @code{call-with-values}. @code{values} is used for returning +multiple values from a procedure. This is done by placing a call to +@code{values} with zero or more arguments in tail position in a +procedure body. @code{call-with-values} combines a procedure returning +multiple values with a procedure which accepts these values as +parameters. + +@rnindex values +@deffn primitive values expr @dots{} +Delivers all of its arguments to its continuation. Except for +continuations created by the @code{call-with-values} procedure, +all continuations take exactly one value. The effect of +passing no value or more than one value to continuations that +were not created by @code{call-with-values} is unspecified. +@end deffn + +@rnindex call-with-values +@deffn primitive call-with-values producer consumer +Calls its @var{producer} argument with no values and a +continuation that, when passed some values, calls the +@var{consumer} procedure with those values as arguments. The +continuation for the call to @var{consumer} is the continuation +of the call to @code{call-with-values}. + +@example +(call-with-values (lambda () (values 4 5)) + (lambda (a b) b)) + ==> 5 + +@end example +@example +(call-with-values * -) ==> -1 +@end example +@end deffn + +In addition to the fundamental procedures described above, Guile has a +module which exports a syntax called @code{receive}, which is much more +convenient. If you want to use it in your programs, you have to load +the module @code{(ice-9 receive)} with the statement + +@lisp +(use-modules (ice-9 receive)) +@end lisp + +@deffn {library syntax} receive formals expr body @dots{} +Evaluate the expression @var{expr}, and bind the result values (zero or +more) to the formal arguments in the formal argument list @var{formals}. +@var{formals} must have the same syntax like the formal argument list +used in @code{lambda} (@pxref{Lambda}). After binding the variables, +the expressions in @var{body} @dots{} are evaluated in order. +@end deffn + + +@node Exceptions +@section Exceptions +@cindex error handling +@cindex exception handling + +A common requirement in applications is to want to jump +@dfn{non-locally} from the depths of a computation back to, say, the +application's main processing loop. Usually, the place that is the +target of the jump is somewhere in the calling stack of procedures that +called the procedure that wants to jump back. For example, typical +logic for a key press driven application might look something like this: + +@example +main-loop: + read the next key press and call dispatch-key + +dispatch-key: + lookup the key in a keymap and call an appropriate procedure, + say find-file + +find-file: + interactively read the required file name, then call + find-specified-file + +find-specified-file: + check whether file exists; if not, jump back to main-loop + @dots{} +@end example + +The jump back to @code{main-loop} could be achieved by returning through +the stack one procedure at a time, using the return value of each +procedure to indicate the error condition, but Guile (like most modern +programming languages) provides an additional mechanism called +@dfn{exception handling} that can be used to implement such jumps much +more conveniently. + +@menu +* Exception Terminology:: Different ways to say the same thing. +* Catch:: Setting up to catch exceptions. +* Throw:: Throwing an exception. +* Lazy Catch:: Catch without unwinding the stack. +* Exception Implementation:: How Guile implements exceptions. +@end menu + + +@node Exception Terminology +@subsection Exception Terminology + +There are several variations on the terminology for dealing with +non-local jumps. It is useful to be aware of them, and to realize +that they all refer to the same basic mechanism. + +@itemize @bullet +@item +Actually making a non-local jump may be called @dfn{raising an +exception}, @dfn{raising a signal}, @dfn{throwing an exception} or +@dfn{doing a long jump}. When the jump indicates an error condition, +people may talk about @dfn{signalling}, @dfn{raising} or @dfn{throwing} +@dfn{an error}. + +@item +Handling the jump at its target may be referred to as @dfn{catching} or +@dfn{handling} the @dfn{exception}, @dfn{signal} or, where an error +condition is involved, @dfn{error}. +@end itemize + +Where @dfn{signal} and @dfn{signalling} are used, special care is needed +to avoid the risk of confusion with POSIX signals. (Especially +considering that Guile handles POSIX signals by throwing a corresponding +kind of exception: REFFIXME.) + +This manual prefers to speak of throwing and catching exceptions, since +this terminology matches the corresponding Guile primitives. + + +@node Catch +@subsection Catching Exceptions + +@code{catch} is used to set up a target for a possible non-local jump. +The arguments of a @code{catch} expression are a @dfn{key}, which +restricts the set of exceptions to which this @code{catch} applies, a +thunk that specifies the @dfn{normal case} code --- i.e. what should +happen if no exceptions are thrown --- and a @dfn{handler} procedure +that says what to do if an exception is thrown. Note that if the +@dfn{normal case} thunk executes @dfn{normally}, which means without +throwing any exceptions, the handler procedure is not executed at all. + +When an exception is thrown using the @code{throw} primitive, the first +argument of the @code{throw} is a symbol that indicates the type of the +exception. For example, Guile throws an exception using the symbol +@code{numerical-overflow} to indicate numerical overflow errors such as +division by zero: + +@lisp +(/ 1 0) +@result{} +ABORT: (numerical-overflow) +@end lisp + +The @var{key} argument in a @code{catch} expression corresponds to this +symbol. @var{key} may be a specific symbol, such as +@code{numerical-overflow}, in which case the @code{catch} applies +specifically to exceptions of that type; or it may be @code{#t}, which +means that the @code{catch} applies to all exceptions, irrespective of +their type. + +The second argument of a @code{catch} expression should be a thunk +(i.e. a procedure that accepts no arguments) that specifies the normal +case code. The @code{catch} is active for the execution of this thunk, +including any code called directly or indirectly by the thunk's body. +Evaluation of the @code{catch} expression activates the catch and then +calls this thunk. + +The third argument of a @code{catch} expression is a handler procedure. +If an exception is thrown, this procedure is called with exactly the +arguments specified by the @code{throw}. Therefore, the handler +procedure must be designed to accept a number of arguments that +corresponds to the number of arguments in all @code{throw} expressions +that can be caught by this @code{catch}. + +@deffn primitive catch key thunk handler +Invoke @var{thunk} in the dynamic context of @var{handler} for +exceptions matching @var{key}. If thunk throws to the symbol +@var{key}, then @var{handler} is invoked this way: +@lisp +(handler key args ...) +@end lisp + +@var{key} is a symbol or @code{#t}. + +@var{thunk} takes no arguments. If @var{thunk} returns +normally, that is the return value of @code{catch}. + +Handler is invoked outside the scope of its own @code{catch}. +If @var{handler} again throws to the same key, a new handler +from further up the call chain is invoked. + +If the key is @code{#t}, then a throw to @emph{any} symbol will +match this call to @code{catch}. +@end deffn + +If the handler procedure needs to match a variety of @code{throw} +expressions with varying numbers of arguments, you should write it like +this: + +@lisp +(lambda (key . args) + @dots{}) +@end lisp + +@noindent +The @var{key} argument is guaranteed always to be present, because a +@code{throw} without a @var{key} is not valid. The number and +interpretation of the @var{args} varies from one type of exception to +another, but should be specified by the documentation for each exception +type. + +Note that, once the handler procedure is invoked, the catch that led to +the handler procedure being called is no longer active. Therefore, if +the handler procedure itself throws an exception, that exception can +only be caught by another active catch higher up the call stack, if +there is one. + + +@node Throw +@subsection Throwing Exceptions + +The @code{throw} primitive is used to throw an exception. One argument, +the @var{key}, is mandatory, and must be a symbol; it indicates the type +of exception that is being thrown. Following the @var{key}, +@code{throw} accepts any number of additional arguments, whose meaning +depends on the exception type. The documentation for each possible type +of exception should specify the additional arguments that are expected +for that kind of exception. + +@deffn primitive throw key . args +Invoke the catch form matching @var{key}, passing @var{args} to the +@var{handler}. + +@var{key} is a symbol. It will match catches of the same symbol or of +@code{#t}. + +If there is no handler at all, Guile prints an error and then exits. +@end deffn + +When an exception is thrown, it will be caught by the innermost +@code{catch} expression that applies to the type of the thrown +exception; in other words, the innermost @code{catch} whose @var{key} is +@code{#t} or is the same symbol as that used in the @code{throw} +expression. Once Guile has identified the appropriate @code{catch}, it +handles the exception by applying that @code{catch} expression's handler +procedure to the arguments of the @code{throw}. + +If there is no appropriate @code{catch} for a thrown exception, Guile +prints an error to the current error port indicating an uncaught +exception, and then exits. In practice, it is quite difficult to +observe this behaviour, because Guile when used interactively installs a +top level @code{catch} handler that will catch all exceptions and print +an appropriate error message @emph{without} exiting. For example, this +is what happens if you try to throw an unhandled exception in the +standard Guile REPL; note that Guile's command loop continues after the +error message: + +@lisp +guile> (throw 'badex) +<unnamed port>:3:1: In procedure gsubr-apply @dots{} +<unnamed port>:3:1: unhandled-exception: badex +ABORT: (misc-error) +guile> +@end lisp + +The default uncaught exception behaviour can be observed by evaluating a +@code{throw} expression from the shell command line: + +@example +$ guile -c "(begin (throw 'badex) (display \"here\\n\"))" +guile: uncaught throw to badex: () +$ +@end example + +@noindent +That Guile exits immediately following the uncaught exception +is shown by the absence of any output from the @code{display} +expression, because Guile never gets to the point of evaluating that +expression. + + +@node Lazy Catch +@subsection Catch Without Unwinding + +A @dfn{lazy catch} is used in the same way as a normal @code{catch}, +with @var{key}, @var{thunk} and @var{handler} arguments specifying the +exception type, normal case code and handler procedure, but differs in +one important respect: the handler procedure is executed without +unwinding the call stack from the context of the @code{throw} expression +that caused the handler to be invoked. + +@deffn primitive lazy-catch key thunk handler +This behaves exactly like @code{catch}, except that it does +not unwind the stack before invoking @var{handler}. +The @var{handler} procedure is not allowed to return: +it must throw to another catch, or otherwise exit non-locally. +@end deffn + +Typically, @var{handler} should save any desired state associated with +the stack at the point where the corresponding @code{throw} occurred, +and then throw an exception itself --- usually the same exception as the +one it caught. If @var{handler} is invoked and does @emph{not} throw an +exception, Guile itself throws an exception with key @code{misc-error}. + +Not unwinding the stack means that throwing an exception that is caught +by a @code{lazy-catch} is @emph{almost} equivalent to calling the +@code{lazy-catch}'s handler inline instead of each @code{throw}, and +then omitting the surrounding @code{lazy-catch}. In other words, + +@lisp +(lazy-catch 'key + (lambda () @dots{} (throw 'key args @dots{}) @dots{}) + handler) +@end lisp + +@noindent +is @emph{almost} equivalent to + +@lisp +((lambda () @dots{} (handler 'key args @dots{}) @dots{})) +@end lisp + +@noindent +But why only @emph{almost}? The difference is that with +@code{lazy-catch} (as with normal @code{catch}), the dynamic context is +unwound back to just outside the @code{lazy-catch} expression before +invoking the handler. (For an introduction to what is meant by dynamic +context, @xref{Dynamic Wind}.) + +Then, when the handler @emph{itself} throws an exception, that exception +must be caught by some kind of @code{catch} (including perhaps another +@code{lazy-catch}) higher up the call stack. + +The dynamic context also includes @code{with-fluids} blocks (REFFIXME), +so the effect of unwinding the dynamic context can also be seen in fluid +variable values. This is illustrated by the following code, in which +the normal case thunk uses @code{with-fluids} to temporarily change the +value of a fluid: + +@lisp +(define f (make-fluid)) +(fluid-set! f "top level value") + +(define (handler . args) + (cons (fluid-ref f) args)) + +(lazy-catch 'foo + (lambda () + (with-fluids ((f "local value")) + (throw 'foo))) + handler) +@result{} +("top level value" foo) + +((lambda () + (with-fluids ((f "local value")) + (handler 'foo)))) +@result{} +("local value" foo) +@end lisp + +@noindent +In the @code{lazy-catch} version, the unwinding of dynamic context +restores @code{f} to its value outside the @code{with-fluids} block +before the handler is invoked, so the handler's @code{(fluid-ref f)} +returns the external value. + +@code{lazy-catch} is useful because it permits the implementation of +debuggers and other reflective programming tools that need to access the +state of the call stack at the exact point where an exception or an +error is thrown. For an example of this, see REFFIXME:stack-catch. + + +@node Exception Implementation +@subsection How Guile Implements Exceptions + +It is traditional in Scheme to implement exception systems using +@code{call-with-current-continuation}. Continuations +(@pxref{Continuations}) are such a powerful concept that any other +control mechanism --- including @code{catch} and @code{throw} --- can be +implemented in terms of them. + +Guile does not implement @code{catch} and @code{throw} like this, +though. Why not? Because Guile is specifically designed to be easy to +integrate with applications written in C. In a mixed Scheme/C +environment, the concept of @dfn{continuation} must logically include +``what happens next'' in the C parts of the application as well as the +Scheme parts, and it turns out that the only reasonable way of +implementing continuations like this is to save and restore the complete +C stack. + +So Guile's implementation of @code{call-with-current-continuation} is a +stack copying one. This allows it to interact well with ordinary C +code, but means that creating and calling a continuation is slowed down +by the time that it takes to copy the C stack. + +The more targeted mechanism provided by @code{catch} and @code{throw} +does not need to save and restore the C stack because the @code{throw} +always jumps to a location higher up the stack of the code that executes +the @code{throw}. Therefore Guile implements the @code{catch} and +@code{throw} primitives independently of +@code{call-with-current-continuation}, in a way that takes advantage of +this @emph{upwards only} nature of exceptions. + + +@node Error Reporting +@section Procedures for Signaling Errors + +Guile provides a set of convenience procedures for signaling error +conditions that are implemented on top of the exception primitives just +described. + +@deffn procedure error msg args @dots{} +Raise an error with key @code{misc-error} and a message constructed by +displaying @var{msg} and writing @var{args}. +@end deffn + +@deffn primitive scm-error key subr message args data +Raise an error with key @var{key}. @var{subr} can be a string +naming the procedure associated with the error, or @code{#f}. +@var{message} is the error message string, possibly containing +@code{~S} and @code{~A} escapes. When an error is reported, +these are replaced by formatting the corresponding members of +@var{args}: @code{~A} (was @code{%s} in older versions of +Guile) formats using @code{display} and @code{~S} (was +@code{%S}) formats using @code{write}. @var{data} is a list or +@code{#f} depending on @var{key}: if @var{key} is +@code{system-error} then it should be a list containing the +Unix @code{errno} value; If @var{key} is @code{signal} then it +should be a list containing the Unix signal number; otherwise +it will usually be @code{#f}. +@end deffn + +@deffn primitive strerror err +Return the Unix error message corresponding to @var{err}, which +must be an integer value. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "false-if-exception") +@deffn syntax false-if-exception expr +Returns the result of evaluating its argument; however +if an exception occurs then @code{#f} is returned instead. +@end deffn +@c end + + +@node Dynamic Wind +@section Dynamic Wind + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +@rnindex dynamic-wind +@deffn primitive dynamic-wind in_guard thunk out_guard +All three arguments must be 0-argument procedures. +@var{in_guard} is called, then @var{thunk}, then +@var{out_guard}. + +If, any time during the execution of @var{thunk}, the +continuation of the @code{dynamic_wind} expression is escaped +non-locally, @var{out_guard} is called. If the continuation of +the dynamic-wind is re-entered, @var{in_guard} is called. Thus +@var{in_guard} and @var{out_guard} may be called any number of +times. +@lisp +(define x 'normal-binding) +@result{} x +(define a-cont (call-with-current-continuation + (lambda (escape) + (let ((old-x x)) + (dynamic-wind + ;; in-guard: + ;; + (lambda () (set! x 'special-binding)) + + ;; thunk + ;; + (lambda () (display x) (newline) + (call-with-current-continuation escape) + (display x) (newline) + x) + + ;; out-guard: + ;; + (lambda () (set! x old-x))))))) + +;; Prints: +special-binding +;; Evaluates to: +@result{} a-cont +x +@result{} normal-binding +(a-cont #f) +;; Prints: +special-binding +;; Evaluates to: +@result{} a-cont ;; the value of the (define a-cont...) +x +@result{} normal-binding +a-cont +@result{} special-binding +@end lisp +@end deffn +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-data.texi b/doc/ref/scheme-data.texi new file mode 100755 index 000000000..3303881ec --- /dev/null +++ b/doc/ref/scheme-data.texi @@ -0,0 +1,5230 @@ +@page +@node Data Types +@chapter Data Types for Generic Use + +This chapter describes all the data types that Guile provides for +``generic use''. + +One of the great strengths of Scheme is that there is no straightforward +distinction between ``data'' and ``functionality''. For example, +Guile's support for dynamic linking could be described + +@itemize @bullet +@item +either in a ``data-centric'' way, as the behaviour and properties of the +``dynamically linked object'' data type, and the operations that may be +applied to instances of this type + +@item +or in a ``functionality-centric'' way, as the set of procedures that +constitute Guile's support for dynamic linking, in the context of the +module system. +@end itemize + +The contents of this chapter are, therefore, a matter of judgement. By +``generic use'', we mean to select those data types whose typical use as +@emph{data} in a wide variety of programming contexts is more important +than their use in the implementation of a particular piece of +@emph{functionality}. + +@ifinfo +The following menu +@end ifinfo +@iftex +The table of contents for this chapter +@end iftex +@ifhtml +The following table of contents +@end ifhtml +shows the data types that are documented in this chapter. The final +section of this chapter lists all the core Guile data types that are not +documented here, and provides links to the ``functionality-centric'' +sections of this manual that cover them. + +@menu +* Booleans:: True/false values. +* Numbers:: Numerical data types. +* Characters:: New character names. +* Strings:: Special things about strings. +* Regular Expressions:: Pattern matching and substitution. +* Symbols and Variables:: Manipulating the Scheme symbol table. +* Keywords:: Self-quoting, customizable display keywords. +* Pairs:: Scheme's basic building block. +* Lists:: Special list functions supported by Guile. +* Vectors:: One-dimensional arrays of Scheme objects. +* Records:: +* Structures:: +* Arrays:: Arrays of values. +* Association Lists and Hash Tables:: Dictionary data types. +* Hooks:: User-customizable event lists. +* Other Data Types:: Data types that are documented elsewhere. +@end menu + + +@node Booleans +@section Booleans +@tpindex Booleans + +The two boolean values are @code{#t} for true and @code{#f} for false. + +Boolean values are returned by predicate procedures, such as the general +equality predicates @code{eq?}, @code{eqv?} and @code{equal?} +(@pxref{Equality}) and numerical and string comparison operators like +@code{string=?} (@pxref{String Comparison}) and @code{<=} +(@pxref{Comparison}). + +@lisp +(<= 3 8) +@result{} +#t + +(<= 3 -3) +@result{} +#f + +(equal? "house" "houses") +@result{} +#f + +(eq? #f #f) +@result{} +#t +@end lisp + +In test condition contexts like @code{if} and @code{cond} (@pxref{if +cond case}), where a group of subexpressions will be evaluated only if a +@var{condition} expression evaluates to ``true'', ``true'' means any +value at all except @code{#f}. + +@lisp +(if #t "yes" "no") +@result{} +"yes" + +(if 0 "yes" "no") +@result{} +"yes" + +(if #f "yes" "no") +@result{} +"no" +@end lisp + +A result of this asymmetry is that typical Scheme source code more often +uses @code{#f} explicitly than @code{#t}: @code{#f} is necessary to +represent an @code{if} or @code{cond} false value, whereas @code{#t} is +not necessary to represent an @code{if} or @code{cond} true value. + +It is important to note that @code{#f} is @strong{not} equivalent to any +other Scheme value. In particular, @code{#f} is not the same as the +number 0 (like in C and C++), and not the same as the ``empty list'' +(like in some Lisp dialects). + +The @code{not} procedure returns the boolean inverse of its argument: + +@rnindex not +@deffn primitive not x +Return @code{#t} iff @var{x} is @code{#f}, else return @code{#f}. +@end deffn + +The @code{boolean?} procedure is a predicate that returns @code{#t} if +its argument is one of the boolean values, otherwise @code{#f}. + +@rnindex boolean? +@deffn primitive boolean? obj +Return @code{#t} iff @var{obj} is either @code{#t} or @code{#f}. +@end deffn + + +@node Numbers +@section Numerical data types +@tpindex Numbers + +Guile supports a rich ``tower'' of numerical types --- integer, +rational, real and complex --- and provides an extensive set of +mathematical and scientific functions for operating on numerical +data. This section of the manual documents those types and functions. + +You may also find it illuminating to read R5RS's presentation of numbers +in Scheme, which is particularly clear and accessible: see +@xref{Numbers,,,r5rs}. + +@menu +* Numerical Tower:: Scheme's numerical "tower". +* Integers:: Whole numbers. +* Reals and Rationals:: Real and rational numbers. +* Complex Numbers:: Complex numbers. +* Exactness:: Exactness and inexactness. +* Number Syntax:: Read syntax for numerical data. +* Integer Operations:: Operations on integer values. +* Comparison:: Comparison predicates. +* Conversion:: Converting numbers to and from strings. +* Complex:: Complex number operations. +* Arithmetic:: Arithmetic functions. +* Scientific:: Scientific functions. +* Primitive Numerics:: Primitive numeric functions. +* Bitwise Operations:: Logical AND, OR, NOT, and so on. +* Random:: Random number generation. +@end menu + + +@node Numerical Tower +@subsection Scheme's Numerical ``Tower'' +@rnindex number? + +Scheme's numerical ``tower'' consists of the following categories of +numbers: + +@itemize @bullet +@item +integers (whole numbers) + +@item +rationals (the set of numbers that can be expressed as P/Q where P and Q +are integers) + +@item +real numbers (the set of numbers that describes all possible positions +along a one dimensional line) + +@item +complex numbers (the set of numbers that describes all possible +positions in a two dimensional space) +@end itemize + +It is called a tower because each category ``sits on'' the one that +follows it, in the sense that every integer is also a rational, every +rational is also real, and every real number is also a complex number +(but with zero imaginary part). + +Of these, Guile implements integers, reals and complex numbers as +distinct types. Rationals are implemented as regards the read syntax +for rational numbers that is specified by R5RS, but are immediately +converted by Guile to the corresponding real number. + +The @code{number?} predicate may be applied to any Scheme value to +discover whether the value is any of the supported numerical types. + +@deffn primitive number? obj +Return @code{#t} if @var{obj} is any kind of number, @code{#f} else. +@end deffn + +For example: + +@lisp +(number? 3) +@result{} +#t + +(number? "hello there!") +@result{} +#f + +(define pi 3.141592654) +(number? pi) +@result{} +#t +@end lisp + +The next few subsections document each of Guile's numerical data types +in detail. + +@node Integers +@subsection Integers + +@tpindex Integer numbers + +@rnindex integer? + +Integers are whole numbers, that is numbers with no fractional part, +such as 2, 83 and -3789. + +Integers in Guile can be arbitrarily big, as shown by the following +example. + +@lisp +(define (factorial n) + (let loop ((n n) (product 1)) + (if (= n 0) + product + (loop (- n 1) (* product n))))) + +(factorial 3) +@result{} +6 + +(factorial 20) +@result{} +2432902008176640000 + +(- (factorial 45)) +@result{} +-119622220865480194561963161495657715064383733760000000000 +@end lisp + +Readers whose background is in programming languages where integers are +limited by the need to fit into just 4 or 8 bytes of memory may find +this surprising, or suspect that Guile's representation of integers is +inefficient. In fact, Guile achieves a near optimal balance of +convenience and efficiency by using the host computer's native +representation of integers where possible, and a more general +representation where the required number does not fit in the native +form. Conversion between these two representations is automatic and +completely invisible to the Scheme level programmer. + +@c REFFIXME Maybe point here to discussion of handling immediates/bignums +@c on the C level, where the conversion is not so automatic - NJ + +@deffn primitive integer? x +Return @code{#t} if @var{x} is an integer number, @code{#f} else. + +@lisp +(integer? 487) +@result{} +#t + +(integer? -3.4) +@result{} +#f +@end lisp +@end deffn + + +@node Reals and Rationals +@subsection Real and Rational Numbers +@tpindex Real numbers +@tpindex Rational numbers + +@rnindex real? +@rnindex rational? + +Mathematically, the real numbers are the set of numbers that describe +all possible points along a continuous, infinite, one-dimensional line. +The rational numbers are the set of all numbers that can be written as +fractions P/Q, where P and Q are integers. All rational numbers are +also real, but there are real numbers that are not rational, for example +the square root of 2, and pi. + +Guile represents both real and rational numbers approximately using a +floating point encoding with limited precision. Even though the actual +encoding is in binary, it may be helpful to think of it as a decimal +number with a limited number of significant figures and a decimal point +somewhere, since this corresponds to the standard notation for non-whole +numbers. For example: + +@lisp +0.34 +-0.00000142857931198 +-5648394822220000000000.0 +4.0 +@end lisp + +The limited precision of Guile's encoding means that any ``real'' number +in Guile can be written in a rational form, by multiplying and then dividing +by sufficient powers of 10 (or in fact, 2). For example, +@code{-0.00000142857931198} is the same as @code{142857931198} divided by +@code{100000000000000000}. In Guile's current incarnation, therefore, +the @code{rational?} and @code{real?} predicates are equivalent. + +Another aspect of this equivalence is that Guile currently does not +preserve the exactness that is possible with rational arithmetic. +If such exactness is needed, it is of course possible to implement +exact rational arithmetic at the Scheme level using Guile's arbitrary +size integers. + +A planned future revision of Guile's numerical tower will make it +possible to implement exact representations and arithmetic for both +rational numbers and real irrational numbers such as square roots, +and in such a way that the new kinds of number integrate seamlessly +with those that are already implemented. + +@deffn primitive real? obj +Return @code{#t} if @var{obj} is a real number, @code{#f} else. +Note that the sets of integer and rational values form subsets +of the set of real numbers, so the predicate will also be fulfilled +if @var{obj} is an integer number or a rational number. +@end deffn + +@deffn primitive rational? x +Return @code{#t} if @var{x} is a rational number, @code{#f} +else. Note that the set of integer values forms a subset of +the set of rational numbers, i. e. the predicate will also be +fulfilled if @var{x} is an integer number. Real numbers +will also satisfy this predicate, because of their limited +precision. +@end deffn + + +@node Complex Numbers +@subsection Complex Numbers +@tpindex Complex numbers + +@rnindex complex? + +Complex numbers are the set of numbers that describe all possible points +in a two-dimensional space. The two coordinates of a particular point +in this space are known as the @dfn{real} and @dfn{imaginary} parts of +the complex number that describes that point. + +In Guile, complex numbers are written in rectangular form as the sum of +their real and imaginary parts, using the symbol @code{i} to indicate +the imaginary part. + +@lisp +3+4i +@result{} +3.0+4.0i + +(* 3-8i 2.3+0.3i) +@result{} +9.3-17.5i +@end lisp + +Guile represents a complex number as a pair of numbers both of which are +real, so the real and imaginary parts of a complex number have the same +properties of inexactness and limited precision as single real numbers. + +@deffn primitive complex? x +Return @code{#t} if @var{x} is a complex number, @code{#f} +else. Note that the sets of real, rational and integer +values form subsets of the set of complex numbers, i. e. the +predicate will also be fulfilled if @var{x} is a real, +rational or integer number. +@end deffn + + +@node Exactness +@subsection Exact and Inexact Numbers +@tpindex Exact numbers +@tpindex Inexact numbers + +@rnindex exact? +@rnindex inexact? +@rnindex exact->inexact +@rnindex inexact->exact + +R5RS requires that a calculation involving inexact numbers always +produces an inexact result. To meet this requirement, Guile +distinguishes between an exact integer value such as @code{5} and the +corresponding inexact real value which, to the limited precision +available, has no fractional part, and is printed as @code{5.0}. Guile +will only convert the latter value to the former when forced to do so by +an invocation of the @code{inexact->exact} procedure. + +@deffn primitive exact? x +Return @code{#t} if @var{x} is an exact number, @code{#f} +otherwise. +@end deffn + +@deffn primitive inexact? x +Return @code{#t} if @var{x} is an inexact number, @code{#f} +else. +@end deffn + +@deffn primitive inexact->exact z +Return an exact number that is numerically closest to @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "exact->inexact") +@deffn primitive exact->inexact z +Convert the number @var{z} to its inexact representation. +@end deffn + + +@node Number Syntax +@subsection Read Syntax for Numerical Data + +The read syntax for integers is a string of digits, optionally +preceded by a minus or plus character, a code indicating the +base in which the integer is encoded, and a code indicating whether +the number is exact or inexact. The supported base codes are: + +@itemize @bullet +@item +@code{#b}, @code{#B} --- the integer is written in binary (base 2) + +@item +@code{#o}, @code{#O} --- the integer is written in octal (base 8) + +@item +@code{#d}, @code{#D} --- the integer is written in decimal (base 10) + +@item +@code{#x}, @code{#X} --- the integer is written in hexadecimal (base 16). +@end itemize + +If the base code is omitted, the integer is assumed to be decimal. The +following examples show how these base codes are used. + +@lisp +-13 +@result{} +-13 + +#d-13 +@result{} +-13 + +#x-13 +@result{} +-19 + +#b+1101 +@result{} +13 + +#o377 +@result{} +255 +@end lisp + +The codes for indicating exactness (which can, incidentally, be applied +to all numerical values) are: + +@itemize @bullet +@item +@code{#e}, @code{#E} --- the number is exact + +@item +@code{#i}, @code{#I} --- the number is inexact. +@end itemize + +If the exactness indicator is omitted, the integer is assumed to be exact, +since Guile's internal representation for integers is always exact. +Real numbers have limited precision similar to the precision of the +@code{double} type in C. A consequence of the limited precision is that +all real numbers in Guile are also rational, since any number R with a +limited number of decimal places, say N, can be made into an integer by +multiplying by 10^N. + + +@node Integer Operations +@subsection Operations on Integer Values +@rnindex odd? +@rnindex even? +@rnindex quotient +@rnindex remainder +@rnindex modulo +@rnindex gcd +@rnindex lcm + +@deffn primitive odd? n +Return @code{#t} if @var{n} is an odd number, @code{#f} +otherwise. +@end deffn + +@deffn primitive even? n +Return @code{#t} if @var{n} is an even number, @code{#f} +otherwise. +@end deffn + +@c begin (texi-doc-string "guile" "quotient") +@deffn primitive quotient +Return the quotient of the numbers @var{x} and @var{y}. +@end deffn + +@c begin (texi-doc-string "guile" "remainder") +@deffn primitive remainder +Return the remainder of the numbers @var{x} and @var{y}. +@lisp +(remainder 13 4) @result{} 1 +(remainder -13 4) @result{} -1 +@end lisp +@end deffn + +@c begin (texi-doc-string "guile" "modulo") +@deffn primitive modulo +Return the modulo of the numbers @var{x} and @var{y}. +@lisp +(modulo 13 4) @result{} 1 +(modulo -13 4) @result{} 3 +@end lisp +@end deffn + +@c begin (texi-doc-string "guile" "gcd") +@deffn primitive gcd +Return the greatest common divisor of all arguments. +If called without arguments, 0 is returned. +@end deffn + +@c begin (texi-doc-string "guile" "lcm") +@deffn primitive lcm +Return the least common multiple of the arguments. +If called without arguments, 1 is returned. +@end deffn + + +@node Comparison +@subsection Comparison Predicates +@rnindex zero? +@rnindex positive? +@rnindex negative? + +@c begin (texi-doc-string "guile" "=") +@deffn primitive = +Return @code{#t} if all parameters are numerically equal. +@end deffn + +@c begin (texi-doc-string "guile" "<") +@deffn primitive < +Return @code{#t} if the list of parameters is monotonically +increasing. +@end deffn + +@c begin (texi-doc-string "guile" ">") +@deffn primitive > +Return @code{#t} if the list of parameters is monotonically +decreasing. +@end deffn + +@c begin (texi-doc-string "guile" "<=") +@deffn primitive <= +Return @code{#t} if the list of parameters is monotonically +non-decreasing. +@end deffn + +@c begin (texi-doc-string "guile" ">=") +@deffn primitive >= +Return @code{#t} if the list of parameters is monotonically +non-increasing. +@end deffn + +@c begin (texi-doc-string "guile" "zero?") +@deffn primitive zero? +Return @code{#t} if @var{z} is an exact or inexact number equal to +zero. +@end deffn + +@c begin (texi-doc-string "guile" "positive?") +@deffn primitive positive? +Return @code{#t} if @var{x} is an exact or inexact number greater than +zero. +@end deffn + +@c begin (texi-doc-string "guile" "negative?") +@deffn primitive negative? +Return @code{#t} if @var{x} is an exact or inexact number less than +zero. +@end deffn + + +@node Conversion +@subsection Converting Numbers To and From Strings +@rnindex number->string +@rnindex string->number + +@deffn primitive number->string n [radix] +Return a string holding the external representation of the +number @var{n} in the given @var{radix}. If @var{n} is +inexact, a radix of 10 will be used. +@end deffn + +@deffn primitive string->number string [radix] +Return a number of the maximally precise representation +expressed by the given @var{string}. @var{radix} must be an +exact integer, either 2, 8, 10, or 16. If supplied, @var{radix} +is a default radix that may be overridden by an explicit radix +prefix in @var{string} (e.g. "#o177"). If @var{radix} is not +supplied, then the default radix is 10. If string is not a +syntactically valid notation for a number, then +@code{string->number} returns @code{#f}. +@end deffn + + +@node Complex +@subsection Complex Number Operations +@rnindex make-rectangular +@rnindex make-polar +@rnindex real-part +@rnindex imag-part +@rnindex magnitude +@rnindex angle + +@deffn primitive make-rectangular real imaginary +Return a complex number constructed of the given @var{real} and +@var{imaginary} parts. +@end deffn + +@deffn primitive make-polar x y +Return the complex number @var{x} * e^(i * @var{y}). +@end deffn + +@c begin (texi-doc-string "guile" "real-part") +@deffn primitive real-part +Return the real part of the number @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "imag-part") +@deffn primitive imag-part +Return the imaginary part of the number @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "magnitude") +@deffn primitive magnitude +Return the magnitude of the number @var{z}. This is the same as +@code{abs} for real arguments, but also allows complex numbers. +@end deffn + +@c begin (texi-doc-string "guile" "angle") +@deffn primitive angle +Return the angle of the complex number @var{z}. +@end deffn + + +@node Arithmetic +@subsection Arithmetic Functions +@rnindex max +@rnindex min +@rnindex + +@rnindex * +@rnindex - +@rnindex / +@rnindex abs +@rnindex floor +@rnindex ceiling +@rnindex truncate +@rnindex round + +@c begin (texi-doc-string "guile" "+") +@deffn primitive + z1 @dots{} +Return the sum of all parameter values. Return 0 if called without any +parameters. +@end deffn + +@c begin (texi-doc-string "guile" "-") +@deffn primitive - z1 z2 @dots{} +If called with one argument @var{z1}, -@var{z1} is returned. Otherwise +the sum of all but the first argument are subtracted from the first +argument. +@end deffn + +@c begin (texi-doc-string "guile" "*") +@deffn primitive * z1 @dots{} +Return the product of all arguments. If called without arguments, 1 is +returned. +@end deffn + +@c begin (texi-doc-string "guile" "/") +@deffn primitive / z1 z2 @dots{} +Divide the first argument by the product of the remaining arguments. If +called with one argument @var{z1}, 1/@var{z1} is returned. +@end deffn + +@c begin (texi-doc-string "guile" "abs") +@deffn primitive abs x +Return the absolute value of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "max") +@deffn primitive max x1 x2 @dots{} +Return the maximum of all parameter values. +@end deffn + +@c begin (texi-doc-string "guile" "min") +@deffn primitive min x1 x2 @dots{} +Return the minium of all parameter values. +@end deffn + +@c begin (texi-doc-string "guile" "truncate") +@deffn primitive truncate +Round the inexact number @var{x} towards zero. +@end deffn + +@c begin (texi-doc-string "guile" "round") +@deffn primitive round x +Round the inexact number @var{x} towards zero. +@end deffn + +@c begin (texi-doc-string "guile" "floor") +@deffn primitive floor x +Round the number @var{x} towards minus infinity. +@end deffn + +@c begin (texi-doc-string "guile" "ceiling") +@deffn primitive ceiling x +Round the number @var{x} towards infinity. +@end deffn + + +@node Scientific +@subsection Scientific Functions + +The following procedures accept any kind of number as arguments, +including complex numbers. + +@rnindex sqrt +@c begin (texi-doc-string "guile" "sqrt") +@deffn procedure sqrt z +Return the square root of @var{z}. +@end deffn + +@rnindex expt +@c begin (texi-doc-string "guile" "expt") +@deffn procedure expt z1 z2 +Return @var{z1} raised to the power of @var{z2}. +@end deffn + +@rnindex sin +@c begin (texi-doc-string "guile" "sin") +@deffn procedure sin z +Return the sine of @var{z}. +@end deffn + +@rnindex cos +@c begin (texi-doc-string "guile" "cos") +@deffn procedure cos z +Return the cosine of @var{z}. +@end deffn + +@rnindex tan +@c begin (texi-doc-string "guile" "tan") +@deffn procedure tan z +Return the tangent of @var{z}. +@end deffn + +@rnindex asin +@c begin (texi-doc-string "guile" "asin") +@deffn procedure asin z +Return the arcsine of @var{z}. +@end deffn + +@rnindex acos +@c begin (texi-doc-string "guile" "acos") +@deffn procedure acos z +Return the arccosine of @var{z}. +@end deffn + +@rnindex atan +@c begin (texi-doc-string "guile" "atan") +@deffn procedure atan z +Return the arctangent of @var{z}. +@end deffn + +@rnindex exp +@c begin (texi-doc-string "guile" "exp") +@deffn procedure exp z +Return e to the power of @var{z}, where e is the base of natural +logarithms (2.71828@dots{}). +@end deffn + +@rnindex log +@c begin (texi-doc-string "guile" "log") +@deffn procedure log z +Return the natural logarithm of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "log10") +@deffn procedure log10 z +Return the base 10 logarithm of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "sinh") +@deffn procedure sinh z +Return the hyperbolic sine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "cosh") +@deffn procedure cosh z +Return the hyperbolic cosine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "tanh") +@deffn procedure tanh z +Return the hyperbolic tangent of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "asinh") +@deffn procedure asinh z +Return the hyperbolic arcsine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "acosh") +@deffn procedure acosh z +Return the hyperbolic arccosine of @var{z}. +@end deffn + +@c begin (texi-doc-string "guile" "atanh") +@deffn procedure atanh z +Return the hyperbolic arctangent of @var{z}. +@end deffn + + +@node Primitive Numerics +@subsection Primitive Numeric Functions + +Many of Guile's numeric procedures which accept any kind of numbers as +arguments, including complex numbers, are implemented as Scheme +procedures that use the following real number-based primitives. These +primitives signal an error if they are called with complex arguments. + +@c begin (texi-doc-string "guile" "$abs") +@deffn primitive $abs x +Return the absolute value of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$sqrt") +@deffn primitive $sqrt x +Return the square root of @var{x}. +@end deffn + +@deffn primitive $expt x y +Return @var{x} raised to the power of @var{y}. This +procedure does not accept complex arguments. +@end deffn + +@c begin (texi-doc-string "guile" "$sin") +@deffn primitive $sin x +Return the sine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$cos") +@deffn primitive $cos x +Return the cosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$tan") +@deffn primitive $tan x +Return the tangent of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$asin") +@deffn primitive $asin x +Return the arcsine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$acos") +@deffn primitive $acos x +Return the arccosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$atan") +@deffn primitive $atan x +Return the arctangent of @var{x} in the range -PI/2 to PI/2. +@end deffn + +@deffn primitive $atan2 x y +Return the arc tangent of the two arguments @var{x} and +@var{y}. This is similar to calculating the arc tangent of +@var{x} / @var{y}, except that the signs of both arguments +are used to determine the quadrant of the result. This +procedure does not accept complex arguments. +@end deffn + +@c begin (texi-doc-string "guile" "$exp") +@deffn primitive $exp x +Return e to the power of @var{x}, where e is the base of natural +logarithms (2.71828@dots{}). +@end deffn + +@c begin (texi-doc-string "guile" "$log") +@deffn primitive $log x +Return the natural logarithm of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$sinh") +@deffn primitive $sinh x +Return the hyperbolic sine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$cosh") +@deffn primitive $cosh x +Return the hyperbolic cosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$tanh") +@deffn primitive $tanh x +Return the hyperbolic tangent of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$asinh") +@deffn primitive $asinh x +Return the hyperbolic arcsine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$acosh") +@deffn primitive $acosh x +Return the hyperbolic arccosine of @var{x}. +@end deffn + +@c begin (texi-doc-string "guile" "$atanh") +@deffn primitive $atanh x +Return the hyperbolic arctangent of @var{x}. +@end deffn + + +@node Bitwise Operations +@subsection Bitwise Operations + +@deffn primitive logand n1 n2 +Return the integer which is the bit-wise AND of the two integer +arguments. + +@lisp +(number->string (logand #b1100 #b1010) 2) + @result{} "1000" +@end lisp +@end deffn + +@deffn primitive logior n1 n2 +Return the integer which is the bit-wise OR of the two integer +arguments. + +@lisp +(number->string (logior #b1100 #b1010) 2) + @result{} "1110" +@end lisp +@end deffn + +@deffn primitive logxor n1 n2 +Return the integer which is the bit-wise XOR of the two integer +arguments. + +@lisp +(number->string (logxor #b1100 #b1010) 2) + @result{} "110" +@end lisp +@end deffn + +@deffn primitive lognot n +Return the integer which is the 2s-complement of the integer +argument. + +@lisp +(number->string (lognot #b10000000) 2) + @result{} "-10000001" +(number->string (lognot #b0) 2) + @result{} "-1" +@end lisp +@end deffn + +@deffn primitive logtest j k +@lisp +(logtest j k) @equiv{} (not (zero? (logand j k))) + +(logtest #b0100 #b1011) @result{} #f +(logtest #b0100 #b0111) @result{} #t +@end lisp +@end deffn + +@deffn primitive logbit? index j +@lisp +(logbit? index j) @equiv{} (logtest (integer-expt 2 index) j) + +(logbit? 0 #b1101) @result{} #t +(logbit? 1 #b1101) @result{} #f +(logbit? 2 #b1101) @result{} #t +(logbit? 3 #b1101) @result{} #t +(logbit? 4 #b1101) @result{} #f +@end lisp +@end deffn + +@deffn primitive ash n cnt +The function ash performs an arithmetic shift left by @var{cnt} +bits (or shift right, if @var{cnt} is negative). 'Arithmetic' +means, that the function does not guarantee to keep the bit +structure of @var{n}, but rather guarantees that the result +will always be rounded towards minus infinity. Therefore, the +results of ash and a corresponding bitwise shift will differ if +@var{n} is negative. + +Formally, the function returns an integer equivalent to +@code{(inexact->exact (floor (* @var{n} (expt 2 @var{cnt}))))}. + +@lisp +(number->string (ash #b1 3) 2) @result{} "1000" +(number->string (ash #b1010 -1) 2) @result{} "101" +@end lisp +@end deffn + +@deffn primitive logcount n +Return the number of bits in integer @var{n}. If integer is +positive, the 1-bits in its binary representation are counted. +If negative, the 0-bits in its two's-complement binary +representation are counted. If 0, 0 is returned. + +@lisp +(logcount #b10101010) + @result{} 4 +(logcount 0) + @result{} 0 +(logcount -2) + @result{} 1 +@end lisp +@end deffn + +@deffn primitive integer-length n +Return the number of bits neccessary to represent @var{n}. + +@lisp +(integer-length #b10101010) + @result{} 8 +(integer-length 0) + @result{} 0 +(integer-length #b1111) + @result{} 4 +@end lisp +@end deffn + +@deffn primitive integer-expt n k +Return @var{n} raised to the non-negative integer exponent +@var{k}. + +@lisp +(integer-expt 2 5) + @result{} 32 +(integer-expt -3 3) + @result{} -27 +@end lisp +@end deffn + +@deffn primitive bit-extract n start end +Return the integer composed of the @var{start} (inclusive) +through @var{end} (exclusive) bits of @var{n}. The +@var{start}th bit becomes the 0-th bit in the result. + +@lisp +(number->string (bit-extract #b1101101010 0 4) 2) + @result{} "1010" +(number->string (bit-extract #b1101101010 4 9) 2) + @result{} "10110" +@end lisp +@end deffn + + +@node Random +@subsection Random Number Generation + +@deffn primitive copy-random-state [state] +Return a copy of the random state @var{state}. +@end deffn + +@deffn primitive random n [state] +Return a number in [0,N). + +Accepts a positive integer or real n and returns a +number of the same type between zero (inclusive) and +N (exclusive). The values returned have a uniform +distribution. + +The optional argument @var{state} must be of the type produced +by @code{seed->random-state}. It defaults to the value of the +variable @var{*random-state*}. This object is used to maintain +the state of the pseudo-random-number generator and is altered +as a side effect of the random operation. +@end deffn + +@deffn primitive random:exp [state] +Return an inexact real in an exponential distribution with mean +1. For an exponential distribution with mean u use (* u +(random:exp)). +@end deffn + +@deffn primitive random:hollow-sphere! v [state] +Fills vect with inexact real random numbers +the sum of whose squares is equal to 1.0. +Thinking of vect as coordinates in space of +dimension n = (vector-length vect), the coordinates +are uniformly distributed over the surface of the +unit n-shere. +@end deffn + +@deffn primitive random:normal [state] +Return an inexact real in a normal distribution. The +distribution used has mean 0 and standard deviation 1. For a +normal distribution with mean m and standard deviation d use +@code{(+ m (* d (random:normal)))}. +@end deffn + +@deffn primitive random:normal-vector! v [state] +Fills vect with inexact real random numbers that are +independent and standard normally distributed +(i.e., with mean 0 and variance 1). +@end deffn + +@deffn primitive random:solid-sphere! v [state] +Fills vect with inexact real random numbers +the sum of whose squares is less than 1.0. +Thinking of vect as coordinates in space of +dimension n = (vector-length vect), the coordinates +are uniformly distributed within the unit n-shere. +The sum of the squares of the numbers is returned. +@end deffn + +@deffn primitive random:uniform [state] +Return a uniformly distributed inexact real random number in +[0,1). +@end deffn + +@deffn primitive seed->random-state seed +Return a new random state using @var{seed}. +@end deffn + + +@node Characters +@section Characters +@tpindex Characters + +Most of the characters in the ASCII character set may be referred to by +name: for example, @code{#\tab}, @code{#\esc}, @code{#\stx}, and so on. +The following table describes the ASCII names for each character. + +@multitable @columnfractions .25 .25 .25 .25 +@item 0 = @code{#\nul} + @tab 1 = @code{#\soh} + @tab 2 = @code{#\stx} + @tab 3 = @code{#\etx} +@item 4 = @code{#\eot} + @tab 5 = @code{#\enq} + @tab 6 = @code{#\ack} + @tab 7 = @code{#\bel} +@item 8 = @code{#\bs} + @tab 9 = @code{#\ht} + @tab 10 = @code{#\nl} + @tab 11 = @code{#\vt} +@item 12 = @code{#\np} + @tab 13 = @code{#\cr} + @tab 14 = @code{#\so} + @tab 15 = @code{#\si} +@item 16 = @code{#\dle} + @tab 17 = @code{#\dc1} + @tab 18 = @code{#\dc2} + @tab 19 = @code{#\dc3} +@item 20 = @code{#\dc4} + @tab 21 = @code{#\nak} + @tab 22 = @code{#\syn} + @tab 23 = @code{#\etb} +@item 24 = @code{#\can} + @tab 25 = @code{#\em} + @tab 26 = @code{#\sub} + @tab 27 = @code{#\esc} +@item 28 = @code{#\fs} + @tab 29 = @code{#\gs} + @tab 30 = @code{#\rs} + @tab 31 = @code{#\us} +@item 32 = @code{#\sp} +@end multitable + +The @code{delete} character (octal 177) may be referred to with the name +@code{#\del}. + +Several characters have more than one name: + +@itemize @bullet +@item +@code{#\space}, @code{#\sp} +@item +@code{#\newline}, @code{#\nl} +@item +@code{#\tab}, @code{#\ht} +@item +@code{#\backspace}, @code{#\bs} +@item +@code{#\return}, @code{#\cr} +@item +@code{#\page}, @code{#\np} +@item +@code{#\null}, @code{#\nul} +@end itemize + +@rnindex char? +@deffn primitive char? x +Return @code{#t} iff @var{x} is a character, else @code{#f}. +@end deffn + +@rnindex char=? +@deffn primitive char=? x y +Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}. +@end deffn + +@rnindex char<? +@deffn primitive char<? x y +Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence, +else @code{#f}. +@end deffn + +@rnindex char<=? +@deffn primitive char<=? x y +Return @code{#t} iff @var{x} is less than or equal to @var{y} in the +ASCII sequence, else @code{#f}. +@end deffn + +@rnindex char>? +@deffn primitive char>? x y +Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII +sequence, else @code{#f}. +@end deffn + +@rnindex char>=? +@deffn primitive char>=? x y +Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the +ASCII sequence, else @code{#f}. +@end deffn + +@rnindex char-ci=? +@deffn primitive char-ci=? x y +Return @code{#t} iff @var{x} is the same character as @var{y} ignoring +case, else @code{#f}. +@end deffn + +@rnindex char-ci<? +@deffn primitive char-ci<? x y +Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence +ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci<=? +@deffn primitive char-ci<=? x y +Return @code{#t} iff @var{x} is less than or equal to @var{y} in the +ASCII sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci>? +@deffn primitive char-ci>? x y +Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII +sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-ci>=? +@deffn primitive char-ci>=? x y +Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the +ASCII sequence ignoring case, else @code{#f}. +@end deffn + +@rnindex char-alphabetic? +@deffn primitive char-alphabetic? chr +Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}. +Alphabetic means the same thing as the isalpha C library function. +@end deffn + +@rnindex char-numeric? +@deffn primitive char-numeric? chr +Return @code{#t} iff @var{chr} is numeric, else @code{#f}. +Numeric means the same thing as the isdigit C library function. +@end deffn + +@rnindex char-whitespace? +@deffn primitive char-whitespace? chr +Return @code{#t} iff @var{chr} is whitespace, else @code{#f}. +Whitespace means the same thing as the isspace C library function. +@end deffn + +@rnindex char-upper-case? +@deffn primitive char-upper-case? chr +Return @code{#t} iff @var{chr} is uppercase, else @code{#f}. +Uppercase means the same thing as the isupper C library function. +@end deffn + +@rnindex char-lower-case? +@deffn primitive char-lower-case? chr +Return @code{#t} iff @var{chr} is lowercase, else @code{#f}. +Lowercase means the same thing as the islower C library function. +@end deffn + +@deffn primitive char-is-both? chr +Return @code{#t} iff @var{chr} is either uppercase or lowercase, else @code{#f}. +Uppercase and lowercase are as defined by the isupper and islower +C library functions. +@end deffn + +@rnindex char->integer +@deffn primitive char->integer chr +Return the number corresponding to ordinal position of @var{chr} in the +ASCII sequence. +@end deffn + +@rnindex integer->char +@deffn primitive integer->char n +Return the character at position @var{n} in the ASCII sequence. +@end deffn + +@rnindex char-upcase +@deffn primitive char-upcase chr +Return the uppercase character version of @var{chr}. +@end deffn + +@rnindex char-downcase +@deffn primitive char-downcase chr +Return the lowercase character version of @var{chr}. +@end deffn + + +@node Strings +@section Strings +@tpindex Strings + +Strings are fixed-length sequences of characters. They can be created +by calling constructor procedures, but they can also literally get +entered at the REPL or in Scheme source files. + +Guile provides a rich set of string processing procedures, because text +handling is very important when Guile is used as a scripting language. + +Strings always carry the information about how many characters they are +composed of with them, so there is no special end-of-string character, +like in C. That means that Scheme strings can contain any character, +even the NUL character @code{'\0'}. But note: Since most operating +system calls dealing with strings (such as for file operations) expect +strings to be zero-terminated, they might do unexpected things when +called with string containing unusal characters. + +@menu +* String Syntax:: Read syntax for strings. +* String Predicates:: Testing strings for certain properties. +* String Constructors:: Creating new string objects. +* List/String Conversion:: Converting from/to lists of characters. +* String Selection:: Select portions from strings. +* String Modification:: Modify parts or whole strings. +* String Comparison:: Lexicographic ordering predicates. +* String Searching:: Searching in strings. +* Alphabetic Case Mapping:: Convert the alphabetic case of strings. +* Appending Strings:: Appending strings to form a new string. +* String Miscellanea:: Miscellaneous string procedures. +@end menu + +@node String Syntax +@subsection String Read Syntax + +The read syntax for strings is an arbitrarily long sequence of +characters enclosed in double quotes (@code{"}). @footnote{Actually, the +current implementation restricts strings to a length of 2^24 +characters.} If you want to insert a double quote character into a +string literal, it must be prefixed with a backslash @code{\} character +(called an @emph{escape character}). + +The following are examples of string literals: + +@lisp +"foo" +"bar plonk" +"Hello World" +"\"Hi\", he said." +@end lisp + +@c FIXME::martin: What about escape sequences like \r, \n etc.? + +@node String Predicates +@subsection String Predicates + +The following procedures can be used to check whether a given string +fulfills some specified property. + +@rnindex string? +@deffn primitive string? obj +Return @code{#t} iff @var{obj} is a string, else returns +@code{#f}. +@end deffn + +@deffn primitive string-null? str +Return @code{#t} if @var{str}'s length is nonzero, and +@code{#f} otherwise. +@lisp +(string-null? "") @result{} #t +y @result{} "foo" +(string-null? y) @result{} #f +@end lisp +@end deffn + +@node String Constructors +@subsection String Constructors + +The string constructor procedures create new string objects, possibly +initializing them with some specified character data. + +@c FIXME::martin: list->string belongs into `List/String Conversion' + +@rnindex string +@rnindex list->string +@deffn primitive string . chrs +@deffnx primitive list->string chrs +Return a newly allocated string composed of the arguments, +@var{chrs}. +@end deffn + +@rnindex make-string +@deffn primitive make-string k [chr] +Return a newly allocated string of +length @var{k}. If @var{chr} is given, then all elements of +the string are initialized to @var{chr}, otherwise the contents +of the @var{string} are unspecified. +@end deffn + +@node List/String Conversion +@subsection List/String conversion + +When processing strings, it is often convenient to first convert them +into a list representation by using the procedure @code{string->list}, +work with the resulting list, and then convert it back into a string. +These procedures are useful for similar tasks. + +@rnindex string->list +@deffn primitive string->list str +Return a newly allocated list of the characters that make up +the given string @var{str}. @code{string->list} and +@code{list->string} are inverses as far as @samp{equal?} is +concerned. +@end deffn + +@deffn primitive string-split str chr +Split the string @var{str} into the a list of the substrings delimited +by appearances of the character @var{chr}. Note that an empty substring +between separator characters will result in an empty string in the +result list. +@lisp +(string-split "root:x:0:0:root:/root:/bin/bash" #\:) +@result{} +("root" "x" "0" "0" "root" "/root" "/bin/bash") + +(string-split "::" #\:) +@result{} +("" "" "") + +(string-split "" #\:) +@result{} +("") +@end lisp +@end deffn + + +@node String Selection +@subsection String Selection + +Portions of strings can be extracted by these procedures. +@code{string-ref} delivers individual characters whereas +@code{substring} can be used to extract substrings from longer strings. + +@rnindex string-length +@deffn primitive string-length string +Return the number of characters in @var{string}. +@end deffn + +@rnindex string-ref +@deffn primitive string-ref str k +Return character @var{k} of @var{str} using zero-origin +indexing. @var{k} must be a valid index of @var{str}. +@end deffn + +@rnindex string-copy +@deffn primitive string-copy str +Return a newly allocated copy of the given @var{string}. +@end deffn + +@rnindex substring +@deffn primitive substring str start [end] +Return a newly allocated string formed from the characters +of @var{str} beginning with index @var{start} (inclusive) and +ending with index @var{end} (exclusive). +@var{str} must be a string, @var{start} and @var{end} must be +exact integers satisfying: + +0 <= @var{start} <= @var{end} <= (string-length @var{str}). +@end deffn + +@node String Modification +@subsection String Modification + +These procedures are for modifying strings in-place. That means, that +not a new string is the result of a string operation, but that the +actual memory representation of a string is modified. + +@rnindex string-set! +@deffn primitive string-set! str k chr +Store @var{chr} in element @var{k} of @var{str} and return +an unspecified value. @var{k} must be a valid index of +@var{str}. +@end deffn + +@rnindex string-fill! +@deffn primitive string-fill! str chr +Store @var{char} in every element of the given @var{string} and +return an unspecified value. +@end deffn + +@deffn primitive substring-fill! str start end fill +Change every character in @var{str} between @var{start} and +@var{end} to @var{fill}. + +@lisp +(define y "abcdefg") +(substring-fill! y 1 3 #\r) +y +@result{} "arrdefg" +@end lisp +@end deffn + +@deffn primitive substring-move! str1 start1 end1 str2 start2 +@deffnx primitive substring-move-left! str1 start1 end1 str2 start2 +@deffnx primitive substring-move-right! str1 start1 end1 str2 start2 +Copy the substring of @var{str1} bounded by @var{start1} and @var{end1} +into @var{str2} beginning at position @var{end2}. +@code{substring-move-right!} begins copying from the rightmost character +and moves left, and @code{substring-move-left!} copies from the leftmost +character moving right. + +It is useful to have two functions that copy in different directions so +that substrings can be copied back and forth within a single string. If +you wish to copy text from the left-hand side of a string to the +right-hand side of the same string, and the source and destination +overlap, you must be careful to copy the rightmost characters of the +text first, to avoid clobbering your data. Hence, when @var{str1} and +@var{str2} are the same string, you should use +@code{substring-move-right!} when moving text from left to right, and +@code{substring-move-left!} otherwise. If @code{str1} and @samp{str2} +are different strings, it does not matter which function you use. + +@example +(define x (make-string 10 #\a)) +(define y "bcd") +(substring-move-left! x 2 5 y 0) +y +@result{} "aaa" + +x +@result{} "aaaaaaaaaa" + +(define y "bcdefg") +(substring-move-left! x 2 5 y 0) +y +@result{} "aaaefg" + +(define y "abcdefg") +(substring-move-left! y 2 5 y 3) +y +@result{} "abccccg" + +(define y "abcdefg") +(substring-move-right! y 2 5 y 0) +y +@result{} "ededefg" + +(define y "abcdefg") +(substring-move-right! y 2 5 y 3) +y +@result{} "abccdeg" +@end example +@end deffn + + +@node String Comparison +@subsection String Comparison + +The procedures in this section are similar to the character ordering +predicates (@pxref{Characters}), but are defined on character sequences. +They all return @code{#t} on success and @code{#f} on failure. The +predicates ending in @code{-ci} ignore the character case when comparing +strings. + + +@rnindex string=? +@deffn primitive string=? s1 s2 +Lexicographic equality predicate; return @code{#t} if the two +strings are the same length and contain the same characters in +the same positions, otherwise return @code{#f}. + +The procedure @code{string-ci=?} treats upper and lower case +letters as though they were the same character, but +@code{string=?} treats upper and lower case as distinct +characters. +@end deffn + +@rnindex string<? +@deffn primitive string<? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically less than @var{s2}. +@end deffn + +@rnindex string<=? +@deffn primitive string<=? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically less than or equal to @var{s2}. +@end deffn + +@rnindex string>? +@deffn primitive string>? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically greater than @var{s2}. +@end deffn + +@rnindex string>=? +@deffn primitive string>=? s1 s2 +Lexicographic ordering predicate; return @code{#t} if @var{s1} +is lexicographically greater than or equal to @var{s2}. +@end deffn + +@rnindex string-ci=? +@deffn primitive string-ci=? s1 s2 +Case-insensitive string equality predicate; return @code{#t} if +the two strings are the same length and their component +characters match (ignoring case) at each position; otherwise +return @code{#f}. +@end deffn + +@rnindex string-ci< +@deffn primitive string-ci<? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically less than @var{s2} +regardless of case. +@end deffn + +@rnindex string<=? +@deffn primitive string-ci<=? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically less than or equal +to @var{s2} regardless of case. +@end deffn + +@rnindex string-ci>? +@deffn primitive string-ci>? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically greater than +@var{s2} regardless of case. +@end deffn + +@rnindex string-ci>=? +@deffn primitive string-ci>=? s1 s2 +Case insensitive lexicographic ordering predicate; return +@code{#t} if @var{s1} is lexicographically greater than or +equal to @var{s2} regardless of case. +@end deffn + + +@node String Searching +@subsection String Searching + +When searching the index of a character in a string, these procedures +can be used. + +@deffn primitive string-index str chr [frm [to]] +Return the index of the first occurrence of @var{chr} in +@var{str}. The optional integer arguments @var{frm} and +@var{to} limit the search to a portion of the string. This +procedure essentially implements the @code{index} or +@code{strchr} functions from the C library. + +@lisp +(string-index "weiner" #\e) +@result{} 1 + +(string-index "weiner" #\e 2) +@result{} 4 + +(string-index "weiner" #\e 2 4) +@result{} #f +@end lisp +@end deffn + +@deffn primitive string-rindex str chr [frm [to]] +Like @code{string-index}, but search from the right of the +string rather than from the left. This procedure essentially +implements the @code{rindex} or @code{strrchr} functions from +the C library. + +@lisp +(string-rindex "weiner" #\e) +@result{} 4 + +(string-rindex "weiner" #\e 2 4) +@result{} #f + +(string-rindex "weiner" #\e 2 5) +@result{} 4 +@end lisp +@end deffn + +@node Alphabetic Case Mapping +@subsection Alphabetic Case Mapping + +These are procedures for mapping strings to their upper- or lower-case +equivalents, respectively, or for capitalizing strings. + +@deffn primitive string-upcase str +Return a freshly allocated string containing the characters of +@var{str} in upper case. +@end deffn + +@deffn primitive string-upcase! str +Destructively upcase every character in @var{str} and return +@var{str}. +@lisp +y @result{} "arrdefg" +(string-upcase! y) @result{} "ARRDEFG" +y @result{} "ARRDEFG" +@end lisp +@end deffn + +@deffn primitive string-downcase str +Return a freshly allocation string containing the characters in +@var{str} in lower case. +@end deffn + +@deffn primitive string-downcase! str +Destructively downcase every character in @var{str} and return +@var{str}. +@lisp +y @result{} "ARRDEFG" +(string-downcase! y) @result{} "arrdefg" +y @result{} "arrdefg" +@end lisp +@end deffn + +@deffn primitive string-capitalize str +Return a freshly allocated string with the characters in +@var{str}, where the first character of every word is +capitalized. +@end deffn + +@deffn primitive string-capitalize! str +Upcase the first character of every word in @var{str} +destructively and return @var{str}. + +@lisp +y @result{} "hello world" +(string-capitalize! y) @result{} "Hello World" +y @result{} "Hello World" +@end lisp +@end deffn + + +@node Appending Strings +@subsection Appending Strings + +The procedure @code{string-append} appends several strings together to +form a longer result string. + +@rnindex string-append +@deffn primitive string-append string1 @dots{} +Return a newly allocated string whose characters form the +concatenation of the given strings. +@end deffn + + +@node String Miscellanea +@subsection String Miscellanea + +This section contains all remaining string procedures. + +@deffn primitive string-ci->symbol str +Return the symbol whose name is @var{str}. @var{str} is +converted to lowercase before the conversion is done, if Guile +is currently reading symbols case-insensitively. +@end deffn + + +@node Regular Expressions +@section Regular Expressions +@tpindex Regular expressions + +@cindex regular expressions +@cindex regex +@cindex emacs regexp + +A @dfn{regular expression} (or @dfn{regexp}) is a pattern that +describes a whole class of strings. A full description of regular +expressions and their syntax is beyond the scope of this manual; +an introduction can be found in the Emacs manual (@pxref{Regexps, +, Syntax of Regular Expressions, emacs, The GNU Emacs Manual}, or +in many general Unix reference books. + +If your system does not include a POSIX regular expression library, and +you have not linked Guile with a third-party regexp library such as Rx, +these functions will not be available. You can tell whether your Guile +installation includes regular expression support by checking whether the +@code{*features*} list includes the @code{regex} symbol. + +@menu +* Regexp Functions:: Functions that create and match regexps. +* Match Structures:: Finding what was matched by a regexp. +* Backslash Escapes:: Removing the special meaning of regexp metacharacters. +* Rx Interface:: Tom Lord's Rx library does things differently. +@end menu + +[FIXME: it may be useful to include an Examples section. Parts of this +interface are bewildering on first glance.] + +@node Regexp Functions +@subsection Regexp Functions + +By default, Guile supports POSIX extended regular expressions. +That means that the characters @samp{(}, @samp{)}, @samp{+} and +@samp{?} are special, and must be escaped if you wish to match the +literal characters. + +This regular expression interface was modeled after that +implemented by SCSH, the Scheme Shell. It is intended to be +upwardly compatible with SCSH regular expressions. + +@c begin (scm-doc-string "regex.scm" "string-match") +@deffn procedure string-match pattern str [start] +Compile the string @var{pattern} into a regular expression and compare +it with @var{str}. The optional numeric argument @var{start} specifies +the position of @var{str} at which to begin matching. + +@code{string-match} returns a @dfn{match structure} which +describes what, if anything, was matched by the regular +expression. @xref{Match Structures}. If @var{str} does not match +@var{pattern} at all, @code{string-match} returns @code{#f}. +@end deffn + +Each time @code{string-match} is called, it must compile its +@var{pattern} argument into a regular expression structure. This +operation is expensive, which makes @code{string-match} inefficient if +the same regular expression is used several times (for example, in a +loop). For better performance, you can compile a regular expression in +advance and then match strings against the compiled regexp. + +@deffn primitive make-regexp pat . flags +Compile the regular expression described by @var{pat}, and +return the compiled regexp structure. If @var{pat} does not +describe a legal regular expression, @code{make-regexp} throws +a @code{regular-expression-syntax} error. + +The @var{flags} arguments change the behavior of the compiled +regular expression. The following flags may be supplied: + +@table @code +@item regexp/icase +Consider uppercase and lowercase letters to be the same when +matching. +@item regexp/newline +If a newline appears in the target string, then permit the +@samp{^} and @samp{$} operators to match immediately after or +immediately before the newline, respectively. Also, the +@samp{.} and @samp{[^...]} operators will never match a newline +character. The intent of this flag is to treat the target +string as a buffer containing many lines of text, and the +regular expression as a pattern that may match a single one of +those lines. +@item regexp/basic +Compile a basic (``obsolete'') regexp instead of the extended +(``modern'') regexps that are the default. Basic regexps do +not consider @samp{|}, @samp{+} or @samp{?} to be special +characters, and require the @samp{@{...@}} and @samp{(...)} +metacharacters to be backslash-escaped (@pxref{Backslash +Escapes}). There are several other differences between basic +and extended regular expressions, but these are the most +significant. +@item regexp/extended +Compile an extended regular expression rather than a basic +regexp. This is the default behavior; this flag will not +usually be needed. If a call to @code{make-regexp} includes +both @code{regexp/basic} and @code{regexp/extended} flags, the +one which comes last will override the earlier one. +@end table +@end deffn + +@deffn primitive regexp-exec rx str [start [flags]] +Match the compiled regular expression @var{rx} against +@code{str}. If the optional integer @var{start} argument is +provided, begin matching from that position in the string. +Return a match structure describing the results of the match, +or @code{#f} if no match could be found. +@end deffn + +@deffn primitive regexp? obj +Return @code{#t} if @var{obj} is a compiled regular expression, +or @code{#f} otherwise. +@end deffn + +Regular expressions are commonly used to find patterns in one string and +replace them with the contents of another string. + +@c begin (scm-doc-string "regex.scm" "regexp-substitute") +@deffn procedure regexp-substitute port match [item@dots{}] +Write to the output port @var{port} selected contents of the match +structure @var{match}. Each @var{item} specifies what should be +written, and may be one of the following arguments: + +@itemize @bullet +@item +A string. String arguments are written out verbatim. + +@item +An integer. The submatch with that number is written. + +@item +The symbol @samp{pre}. The portion of the matched string preceding +the regexp match is written. + +@item +The symbol @samp{post}. The portion of the matched string following +the regexp match is written. +@end itemize + +@var{port} may be @code{#f}, in which case nothing is written; instead, +@code{regexp-substitute} constructs a string from the specified +@var{item}s and returns that. +@end deffn + +@c begin (scm-doc-string "regex.scm" "regexp-substitute") +@deffn procedure regexp-substitute/global port regexp target [item@dots{}] +Similar to @code{regexp-substitute}, but can be used to perform global +substitutions on @var{str}. Instead of taking a match structure as an +argument, @code{regexp-substitute/global} takes two string arguments: a +@var{regexp} string describing a regular expression, and a @var{target} +string which should be matched against this regular expression. + +Each @var{item} behaves as in @var{regexp-substitute}, with the +following exceptions: + +@itemize @bullet +@item +A function may be supplied. When this function is called, it will be +passed one argument: a match structure for a given regular expression +match. It should return a string to be written out to @var{port}. + +@item +The @samp{post} symbol causes @code{regexp-substitute/global} to recurse +on the unmatched portion of @var{str}. This @emph{must} be supplied in +order to perform global search-and-replace on @var{str}; if it is not +present among the @var{item}s, then @code{regexp-substitute/global} will +return after processing a single match. +@end itemize +@end deffn + +@node Match Structures +@subsection Match Structures + +@cindex match structures + +A @dfn{match structure} is the object returned by @code{string-match} and +@code{regexp-exec}. It describes which portion of a string, if any, +matched the given regular expression. Match structures include: a +reference to the string that was checked for matches; the starting and +ending positions of the regexp match; and, if the regexp included any +parenthesized subexpressions, the starting and ending positions of each +submatch. + +In each of the regexp match functions described below, the @code{match} +argument must be a match structure returned by a previous call to +@code{string-match} or @code{regexp-exec}. Most of these functions +return some information about the original target string that was +matched against a regular expression; we will call that string +@var{target} for easy reference. + +@c begin (scm-doc-string "regex.scm" "regexp-match?") +@deffn procedure regexp-match? obj +Return @code{#t} if @var{obj} is a match structure returned by a +previous call to @code{regexp-exec}, or @code{#f} otherwise. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:substring") +@deffn procedure match:substring match [n] +Return the portion of @var{target} matched by subexpression number +@var{n}. Submatch 0 (the default) represents the entire regexp match. +If the regular expression as a whole matched, but the subexpression +number @var{n} did not match, return @code{#f}. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:start") +@deffn procedure match:start match [n] +Return the starting position of submatch number @var{n}. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:end") +@deffn procedure match:end match [n] +Return the ending position of submatch number @var{n}. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:prefix") +@deffn procedure match:prefix match +Return the unmatched portion of @var{target} preceding the regexp match. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:suffix") +@deffn procedure match:suffix match +Return the unmatched portion of @var{target} following the regexp match. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:count") +@deffn procedure match:count match +Return the number of parenthesized subexpressions from @var{match}. +Note that the entire regular expression match itself counts as a +subexpression, and failed submatches are included in the count. +@end deffn + +@c begin (scm-doc-string "regex.scm" "match:string") +@deffn procedure match:string match +Return the original @var{target} string. +@end deffn + +@node Backslash Escapes +@subsection Backslash Escapes + +Sometimes you will want a regexp to match characters like @samp{*} or +@samp{$} exactly. For example, to check whether a particular string +represents a menu entry from an Info node, it would be useful to match +it against a regexp like @samp{^* [^:]*::}. However, this won't work; +because the asterisk is a metacharacter, it won't match the @samp{*} at +the beginning of the string. In this case, we want to make the first +asterisk un-magic. + +You can do this by preceding the metacharacter with a backslash +character @samp{\}. (This is also called @dfn{quoting} the +metacharacter, and is known as a @dfn{backslash escape}.) When Guile +sees a backslash in a regular expression, it considers the following +glyph to be an ordinary character, no matter what special meaning it +would ordinarily have. Therefore, we can make the above example work by +changing the regexp to @samp{^\* [^:]*::}. The @samp{\*} sequence tells +the regular expression engine to match only a single asterisk in the +target string. + +Since the backslash is itself a metacharacter, you may force a regexp to +match a backslash in the target string by preceding the backslash with +itself. For example, to find variable references in a @TeX{} program, +you might want to find occurrences of the string @samp{\let\} followed +by any number of alphabetic characters. The regular expression +@samp{\\let\\[A-Za-z]*} would do this: the double backslashes in the +regexp each match a single backslash in the target string. + +@c begin (scm-doc-string "regex.scm" "regexp-quote") +@deffn procedure regexp-quote str +Quote each special character found in @var{str} with a backslash, and +return the resulting string. +@end deffn + +@strong{Very important:} Using backslash escapes in Guile source code +(as in Emacs Lisp or C) can be tricky, because the backslash character +has special meaning for the Guile reader. For example, if Guile +encounters the character sequence @samp{\n} in the middle of a string +while processing Scheme code, it replaces those characters with a +newline character. Similarly, the character sequence @samp{\t} is +replaced by a horizontal tab. Several of these @dfn{escape sequences} +are processed by the Guile reader before your code is executed. +Unrecognized escape sequences are ignored: if the characters @samp{\*} +appear in a string, they will be translated to the single character +@samp{*}. + +This translation is obviously undesirable for regular expressions, since +we want to be able to include backslashes in a string in order to +escape regexp metacharacters. Therefore, to make sure that a backslash +is preserved in a string in your Guile program, you must use @emph{two} +consecutive backslashes: + +@lisp +(define Info-menu-entry-pattern (make-regexp "^\\* [^:]*")) +@end lisp + +The string in this example is preprocessed by the Guile reader before +any code is executed. The resulting argument to @code{make-regexp} is +the string @samp{^\* [^:]*}, which is what we really want. + +This also means that in order to write a regular expression that matches +a single backslash character, the regular expression string in the +source code must include @emph{four} backslashes. Each consecutive pair +of backslashes gets translated by the Guile reader to a single +backslash, and the resulting double-backslash is interpreted by the +regexp engine as matching a single backslash character. Hence: + +@lisp +(define tex-variable-pattern (make-regexp "\\\\let\\\\=[A-Za-z]*")) +@end lisp + +The reason for the unwieldiness of this syntax is historical. Both +regular expression pattern matchers and Unix string processing systems +have traditionally used backslashes with the special meanings +described above. The POSIX regular expression specification and ANSI C +standard both require these semantics. Attempting to abandon either +convention would cause other kinds of compatibility problems, possibly +more severe ones. Therefore, without extending the Scheme reader to +support strings with different quoting conventions (an ungainly and +confusing extension when implemented in other languages), we must adhere +to this cumbersome escape syntax. + +@node Rx Interface +@subsection Rx Interface + +@c FIXME::martin: Shouldn't this be removed or moved to the +@c ``Guile Modules'' chapter? The functions are not available in +@c plain Guile... + +[FIXME: this is taken from Gary and Mark's quick summaries and should be +reviewed and expanded. Rx is pretty stable, so could already be done!] + +@cindex rx +@cindex finite automaton + +Guile includes an interface to Tom Lord's Rx library (currently only to +POSIX regular expressions). Use of the library requires a two step +process: compile a regular expression into an efficient structure, then +use the structure in any number of string comparisons. + +For example, given the +regular expression @samp{abc.} (which matches any string containing +@samp{abc} followed by any single character): + +@smalllisp +guile> @kbd{(define r (regcomp "abc."))} +guile> @kbd{r} +#<rgx abc.> +guile> @kbd{(regexec r "abc")} +#f +guile> @kbd{(regexec r "abcd")} +#((0 . 4)) +guile> +@end smalllisp + +The definitions of @code{regcomp} and @code{regexec} are as follows: + +@c NJFIXME not in libguile! +@deffn primitive regcomp pattern [flags] +Compile the regular expression pattern using POSIX rules. Flags is +optional and should be specified using symbolic names: +@defvar REG_EXTENDED +use extended POSIX syntax +@end defvar +@defvar REG_ICASE +use case-insensitive matching +@end defvar +@defvar REG_NEWLINE +allow anchors to match after newline characters in the +string and prevents @code{.} or @code{[^...]} from matching newlines. +@end defvar + +The @code{logior} procedure can be used to combine multiple flags. +The default is to use +POSIX basic syntax, which makes @code{+} and @code{?} literals and @code{\+} +and @code{\?} +operators. Backslashes in @var{pattern} must be escaped if specified in a +literal string e.g., @code{"\\(a\\)\\?"}. +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive regexec regex string [match-pick] [flags] + +Match @var{string} against the compiled POSIX regular expression +@var{regex}. +@var{match-pick} and @var{flags} are optional. Possible flags (which can be +combined using the logior procedure) are: + +@defvar REG_NOTBOL +The beginning of line operator won't match the beginning of +@var{string} (presumably because it's not the beginning of a line) +@end defvar + +@defvar REG_NOTEOL +Similar to REG_NOTBOL, but prevents the end of line operator +from matching the end of @var{string}. +@end defvar + +If no match is possible, regexec returns #f. Otherwise @var{match-pick} +determines the return value: + +@code{#t} or unspecified: a newly-allocated vector is returned, +containing pairs with the indices of the matched part of @var{string} and any +substrings. + +@code{""}: a list is returned: the first element contains a nested list +with the matched part of @var{string} surrounded by the the unmatched parts. +Remaining elements are matched substrings (if any). All returned +substrings share memory with @var{string}. + +@code{#f}: regexec returns #t if a match is made, otherwise #f. + +vector: the supplied vector is returned, with the first element replaced +by a pair containing the indices of the matched portion of @var{string} and +further elements replaced by pairs containing the indices of matched +substrings (if any). + +list: a list will be returned, with each member of the list +specified by a code in the corresponding position of the supplied list: + +a number: the numbered matching substring (0 for the entire match). + +@code{#\<}: the beginning of @var{string} to the beginning of the part matched +by regex. + +@code{#\>}: the end of the matched part of @var{string} to the end of +@var{string}. + +@code{#\c}: the "final tag", which seems to be associated with the "cut +operator", which doesn't seem to be available through the posix +interface. + +e.g., @code{(list #\< 0 1 #\>)}. The returned substrings share memory with +@var{string}. +@end deffn + +Here are some other procedures that might be used when using regular +expressions: + +@c NJFIXME not in libguile! +@deffn primitive compiled-regexp? obj +Test whether obj is a compiled regular expression. +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive regexp->dfa regex [flags] +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive dfa-fork dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive reset-dfa! dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive dfa-final-tag dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive dfa-continuable? dfa +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive advance-dfa! dfa string +@end deffn + + +@node Symbols and Variables +@section Symbols and Variables + +@c FIXME::martin: Review me! + +Symbols are a data type with a special property. On the one hand, +symbols are used for denoting variables in a Scheme program, on the +other they can be used as literal data as well. + +The association between symbols and values is maintained in special data +structures, the symbol tables. + +In addition, Guile offers variables as first-class objects. They can +be used for interacting with the module system. + +@menu +* Symbols:: All about symbols as a data type. +* Symbol Tables:: Tables for mapping symbols to values. +* Variables:: First-class variables. +@end menu + +@node Symbols +@subsection Symbols +@tpindex Symbols + +@c FIXME::martin: Review me! + +Symbols are especially useful because two symbols which are spelled the +same way are equivalent in the sense of @code{eq?}. That means that +they are actually the same Scheme object. The advantage is that symbols +can be compared extremely efficiently, although they carry more +information for the human reader than, say, numbers. + +It is very common in Scheme programs to use symbols as keys in +association lists (@pxref{Association Lists}) or hash tables +(@pxref{Hash Tables}), because this usage improves the readability a +lot, and does not cause any performance loss. + +The read syntax for symbols is a sequence of letters, digits, and +@emph{extended alphabetic characters} that begins with a character that +cannot begin a number is an identifier. In addition, @code{+}, +@code{-}, and @code{...} are identifiers. + +Extended alphabetic characters may be used within identifiers as if +they were letters. The following are extended alphabetic characters: + +@example +! $ % & * + - . / : < = > ? @@ ^ _ ~ +@end example + +In addition to the read syntax defined above (which is taken from R5RS +(@pxref{Formal syntax,,,r5rs,The Revised^5 Report on Scheme})), Guile +provides a method for writing symbols with unusual characters, such as +space characters. If you (for whatever reason) need to write a symbol +containing characters not mentioned above, you write symbols as follows: + +@itemize @bullet +@item +Begin the symbol with the two character @code{#@{}, + +@item +write the characters of the symbol and + +@item +finish the symbol with the characters @code{@}#}. +@end itemize + +Here are a few examples of this form of read syntax; the first +containing a space character, the second containing a line break and the +last one looks like a number. + +@lisp +#@{foo bar@}# +#@{what +ever@}# +#@{4242@}# +@end lisp + +Usage of this form of read syntax is discouraged, because it is not +portable at all, and is not very readable. + +@rnindex symbol? +@deffn primitive symbol? obj +Return @code{#t} if @var{obj} is a symbol, otherwise return +@code{#f}. +@end deffn + +@rnindex string->symbol +@deffn primitive string->symbol string +Return the symbol whose name is @var{string}. This procedure +can create symbols with names containing special characters or +letters in the non-standard case, but it is usually a bad idea +to create such symbols because in some implementations of +Scheme they cannot be read as themselves. See +@code{symbol->string}. + +The following examples assume that the implementation's +standard case is lower case: + +@lisp +(eq? 'mISSISSIppi 'mississippi) @result{} #t +(string->symbol "mISSISSIppi") @result{} @r{the symbol with name "mISSISSIppi"} +(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f +(eq? 'JollyWog + (string->symbol (symbol->string 'JollyWog))) @result{} #t +(string=? "K. Harper, M.D." + (symbol->string + (string->symbol "K. Harper, M.D."))) @result{}#t +@end lisp +@end deffn + +@rnindex symbol->string +@deffn primitive symbol->string s +Return the name of @var{symbol} as a string. If the symbol was +part of an object returned as the value of a literal expression +(section @pxref{Literal expressions,,,r5rs, The Revised^5 +Report on Scheme}) or by a call to the @code{read} procedure, +and its name contains alphabetic characters, then the string +returned will contain characters in the implementation's +preferred standard case--some implementations will prefer +upper case, others lower case. If the symbol was returned by +@code{string->symbol}, the case of characters in the string +returned will be the same as the case in the string that was +passed to @code{string->symbol}. It is an error to apply +mutation procedures like @code{string-set!} to strings returned +by this procedure. + +The following examples assume that the implementation's +standard case is lower case: + +@lisp +(symbol->string 'flying-fish) @result{} "flying-fish" +(symbol->string 'Martin) @result{} "martin" +(symbol->string + (string->symbol "Malvina")) @result{} "Malvina" +@end lisp +@end deffn + +@node Symbol Tables +@subsection Symbol Tables + +@c FIXME::martin: Review me! + +@c FIXME::martin: Are all these procedures still relevant? + +Guile symbol tables are hash tables. Each hash table, also called an +@dfn{obarray} (for `object array'), is a vector of association lists. +Each entry in the alists is a pair (@var{SYMBOL} . @var{VALUE}). To +@dfn{intern} a symbol in a symbol table means to return its +(@var{SYMBOL} . @var{VALUE}) pair, adding a new entry to the symbol +table (with an undefined value) if none is yet present. + +@c FIXME::martin: According to NEWS, removed. Remove here too, or +@c leave for compatibility? +@c @c docstring begin (texi-doc-string "guile" "builtin-bindings") +@c @deffn primitive builtin-bindings +@c Create and return a copy of the global symbol table, removing all +@c unbound symbols. +@c @end deffn + +@deffn primitive gensym [prefix] +Create a new symbol with a name constructed from a prefix and +a counter value. The string @var{prefix} can be specified as +an optional argument. Default prefix is @code{g}. The counter +is increased by 1 at each call. There is no provision for +resetting the counter. +@end deffn + +@deffn primitive gentemp [prefix [obarray]] +Create a new symbol with a name unique in an obarray. +The name is constructed from an optional string @var{prefix} +and a counter value. The default prefix is @code{t}. The +@var{obarray} is specified as a second optional argument. +Default is the system obarray where all normal symbols are +interned. The counter is increased by 1 at each +call. There is no provision for resetting the counter. +@end deffn + +@deffn primitive intern-symbol obarray string +Add a new symbol to @var{obarray} with name @var{string}, bound to an +unspecified initial value. The symbol table is not modified if a symbol +with this name is already present. +@end deffn + +@deffn primitive string->obarray-symbol obarray string [soft?] +Intern a new symbol in @var{obarray}, a symbol table, with name +@var{string}. +@end deffn + +@deffn primitive symbol-binding obarray string +Look up in @var{obarray} the symbol whose name is @var{string}, and +return the value to which it is bound. If @var{obarray} is @code{#f}, +use the global symbol table. If @var{string} is not interned in +@var{obarray}, an error is signalled. +@end deffn + +@deffn primitive symbol-bound? obarray string +Return @code{#t} if @var{obarray} contains a symbol with name +@var{string} bound to a defined value. This differs from +@var{symbol-interned?} in that the mere mention of a symbol +usually causes it to be interned; @code{symbol-bound?} +determines whether a symbol has been given any meaningful +value. +@end deffn + +@deffn primitive symbol-fref symbol +Return the contents of @var{symbol}'s @dfn{function slot}. +@end deffn + +@deffn primitive symbol-fset! symbol value +Change the binding of @var{symbol}'s function slot. +@end deffn + +@deffn primitive symbol-hash symbol +Return a hash value for @var{symbol}. +@end deffn + +@deffn primitive symbol-interned? obarray string +Return @code{#t} if @var{obarray} contains a symbol with name +@var{string}, and @code{#f} otherwise. +@end deffn + +@deffn primitive symbol-pref symbol +Return the @dfn{property list} currently associated with @var{symbol}. +@end deffn + +@deffn primitive symbol-pset! symbol value +Change the binding of @var{symbol}'s property slot. +@end deffn + +@deffn primitive symbol-set! obarray string value +Find the symbol in @var{obarray} whose name is @var{string}, and rebind +it to @var{value}. An error is signalled if @var{string} is not present +in @var{obarray}. +@end deffn + +@deffn primitive unintern-symbol obarray string +Remove the symbol with name @var{string} from @var{obarray}. This +function returns @code{#t} if the symbol was present and @code{#f} +otherwise. +@end deffn + +@node Variables +@subsection Variables +@tpindex Variables + +@c FIXME::martin: Review me! + +Variables are objects with two fields. They contain a value and they +can contain a symbol, which is the name of the variable. A variable is +said to be bound if it does not contain the object denoting unbound +variables in the value slot. + +Variables do not have a read syntax, they have to be created by calling +one of the constructor procedures @code{make-variable} or +@code{make-undefined-variable} or retrieved by @code{builtin-variable}. + +First-class variables are especially useful for interacting with the +current module system (@pxref{The Guile module system}). + +@deffn primitive builtin-variable name +Return the built-in variable with the name @var{name}. +@var{name} must be a symbol (not a string). +Then use @code{variable-ref} to access its value. +@end deffn + +@deffn primitive make-undefined-variable [name-hint] +Return a variable object initialized to an undefined value. +If given, uses @var{name-hint} as its internal (debugging) +name, otherwise just treat it as an anonymous variable. +Remember, of course, that multiple bindings to the same +variable may exist, so @var{name-hint} is just that---a hint. +@end deffn + +@deffn primitive make-variable init [name-hint] +Return a variable object initialized to value @var{init}. +If given, uses @var{name-hint} as its internal (debugging) +name, otherwise just treat it as an anonymous variable. +Remember, of course, that multiple bindings to the same +variable may exist, so @var{name-hint} is just that---a hint. +@end deffn + +@deffn primitive variable-bound? var +Return @code{#t} iff @var{var} is bound to a value. +Throws an error if @var{var} is not a variable object. +@end deffn + +@deffn primitive variable-ref var +Dereference @var{var} and return its value. +@var{var} must be a variable object; see @code{make-variable} +and @code{make-undefined-variable}. +@end deffn + +@deffn primitive variable-set! var val +Set the value of the variable @var{var} to @var{val}. +@var{var} must be a variable object, @var{val} can be any +value. Return an unspecified value. +@end deffn + +@deffn primitive variable? obj +Return @code{#t} iff @var{obj} is a variable object, else +return @code{#f} +@end deffn + + +@node Keywords +@section Keywords +@tpindex Keywords + +Keywords are self-evaluating objects with a convenient read syntax that +makes them easy to type. + +Guile's keyword support conforms to R5RS, and adds a (switchable) read +syntax extension to permit keywords to begin with @code{:} as well as +@code{#:}. + +@menu +* Why Use Keywords?:: Motivation for keyword usage. +* Coding With Keywords:: How to use keywords. +* Keyword Read Syntax:: Read syntax for keywords. +* Keyword Procedures:: Procedures for dealing with keywords. +* Keyword Primitives:: The underlying primitive procedures. +@end menu + +@node Why Use Keywords? +@subsection Why Use Keywords? + +Keywords are useful in contexts where a program or procedure wants to be +able to accept a large number of optional arguments without making its +interface unmanageable. + +To illustrate this, consider a hypothetical @code{make-window} +procedure, which creates a new window on the screen for drawing into +using some graphical toolkit. There are many parameters that the caller +might like to specify, but which could also be sensibly defaulted, for +example: + +@itemize @bullet +@item +colour depth -- Default: the colour depth for the screen + +@item +background colour -- Default: white + +@item +width -- Default: 600 + +@item +height -- Default: 400 +@end itemize + +If @code{make-window} did not use keywords, the caller would have to +pass in a value for each possible argument, remembering the correct +argument order and using a special value to indicate the default value +for that argument: + +@lisp +(make-window 'default ;; Colour depth + 'default ;; Background colour + 800 ;; Width + 100 ;; Height + @dots{}) ;; More make-window arguments +@end lisp + +With keywords, on the other hand, defaulted arguments are omitted, and +non-default arguments are clearly tagged by the appropriate keyword. As +a result, the invocation becomes much clearer: + +@lisp +(make-window #:width 800 #:height 100) +@end lisp + +On the other hand, for a simpler procedure with few arguments, the use +of keywords would be a hindrance rather than a help. The primitive +procedure @code{cons}, for example, would not be improved if it had to +be invoked as + +@lisp +(cons #:car x #:cdr y) +@end lisp + +So the decision whether to use keywords or not is purely pragmatic: use +them if they will clarify the procedure invocation at point of call. + +@node Coding With Keywords +@subsection Coding With Keywords + +If a procedure wants to support keywords, it should take a rest argument +and then use whatever means is convenient to extract keywords and their +corresponding arguments from the contents of that rest argument. + +The following example illustrates the principle: the code for +@code{make-window} uses a helper procedure called +@code{get-keyword-value} to extract individual keyword arguments from +the rest argument. + +@lisp +(define (get-keyword-value args keyword default) + (let ((kv (memq keyword args))) + (if (and kv (>= (length kv) 2)) + (cadr kv) + default))) + +(define (make-window . args) + (let ((depth (get-keyword-value args #:depth screen-depth)) + (bg (get-keyword-value args #:bg "white")) + (width (get-keyword-value args #:width 800)) + (height (get-keyword-value args #:height 100)) + @dots{}) + @dots{})) +@end lisp + +But you don't need to write @code{get-keyword-value}. The @code{(ice-9 +optargs)} module provides a set of powerful macros that you can use to +implement keyword-supporting procedures like this: + +@lisp +(use-modules (ice-9 optargs)) + +(define (make-window . args) + (let-keywords args #f ((depth screen-depth) + (bg "white") + (width 800) + (height 100)) + ...)) +@end lisp + +@noindent +Or, even more economically, like this: + +@lisp +(use-modules (ice-9 optargs)) + +(define* (make-window #:key (depth screen-depth) + (bg "white") + (width 800) + (height 100)) + ...) +@end lisp + +For further details on @code{let-keywords}, @code{define*} and other +facilities provided by the @code{(ice-9 optargs)} module, @ref{Optional +Arguments}. + + +@node Keyword Read Syntax +@subsection Keyword Read Syntax + +Guile, by default, only recognizes the keyword syntax specified by R5RS. +A token of the form @code{#:NAME}, where @code{NAME} has the same syntax +as a Scheme symbol, is the external representation of the keyword named +@code{NAME}. Keyword objects print using this syntax as well, so values +containing keyword objects can be read back into Guile. When used in an +expression, keywords are self-quoting objects. + +If the @code{keyword} read option is set to @code{'prefix}, Guile also +recognizes the alternative read syntax @code{:NAME}. Otherwise, tokens +of the form @code{:NAME} are read as symbols, as required by R5RS. + +To enable and disable the alternative non-R5RS keyword syntax, you use +the @code{read-options} procedure documented in @ref{General option +interface} and @ref{Reader options}. + +@smalllisp +(read-set! keywords 'prefix) + +#:type +@result{} +#:type + +:type +@result{} +#:type + +(read-set! keywords #f) + +#:type +@result{} +#:type + +:type +@result{} +ERROR: In expression :type: +ERROR: Unbound variable: :type +ABORT: (unbound-variable) +@end smalllisp + +@node Keyword Procedures +@subsection Keyword Procedures + +@c FIXME::martin: Review me! + +The following procedures can be used for converting symbols to keywords +and back. + +@deffn procedure symbol->keyword sym +Return a keyword with the same characters as in @var{sym}. +@end deffn + +@deffn procedure keyword->symbol kw +Return a symbol with the same characters as in @var{kw}. +@end deffn + + +@node Keyword Primitives +@subsection Keyword Primitives + +Internally, a keyword is implemented as something like a tagged symbol, +where the tag identifies the keyword as being self-evaluating, and the +symbol, known as the keyword's @dfn{dash symbol} has the same name as +the keyword name but prefixed by a single dash. For example, the +keyword @code{#:name} has the corresponding dash symbol @code{-name}. + +Most keyword objects are constructed automatically by the reader when it +reads a token beginning with @code{#:}. However, if you need to +construct a keyword object programmatically, you can do so by calling +@code{make-keyword-from-dash-symbol} with the corresponding dash symbol +(as the reader does). The dash symbol for a keyword object can be +retrieved using the @code{keyword-dash-symbol} procedure. + +@deffn primitive make-keyword-from-dash-symbol symbol +Make a keyword object from a @var{symbol} that starts with a dash. +@end deffn + +@deffn primitive keyword? obj +Return @code{#t} if the argument @var{obj} is a keyword, else +@code{#f}. +@end deffn + +@deffn primitive keyword-dash-symbol keyword +Return the dash symbol for @var{keyword}. +This is the inverse of @code{make-keyword-from-dash-symbol}. +@end deffn + +@node Pairs +@section Pairs +@tpindex Pairs + +@c FIXME::martin: Review me! + +Pairs are used to combine two Scheme objects into one compound object. +Hence the name: A pair stores a pair of objects. + +The data type @emph{pair} is extremely important in Scheme, just like in +any other Lisp dialect. The reason is that pairs are not only used to +make two values available as one object, but that pairs are used for +constructing lists of values. Because lists are so important in Scheme, +they are described in a section of their own (@pxref{Lists}). + +Pairs can literally get entered in source code or at the REPL, in the +so-called @dfn{dotted list} syntax. This syntax consists of an opening +parentheses, the first element of the pair, a dot, the second element +and a closing parentheses. The following example shows how a pair +consisting of the two numbers 1 and 2, and a pair containing the symbols +@code{foo} and @code{bar} can be entered. It is very important to write +the whitespace before and after the dot, because otherwise the Scheme +parser whould not be able to figure out where to split the tokens. + +@lisp +(1 . 2) +(foo . bar) +@end lisp + +But beware, if you want to try out these examples, you have to +@dfn{quote} the expressions. More information about quotation is +available in the section (REFFIXME). The correct way to try these +examples is as follows. + +@lisp +'(1 . 2) +@result{} +(1 . 2) +'(foo . bar) +@result{} +(foo . bar) +@end lisp + +A new pair is made by calling the procedure @code{cons} with two +arguments. Then the argument values are stored into a newly allocated +pair, and the pair is returned. The name @code{cons} stands for +@emph{construct}. Use the procedure @code{pair?} to test whether a +given Scheme object is a pair or not. + +@rnindex cons +@deffn primitive cons x y +Return a newly allocated pair whose car is @var{x} and whose +cdr is @var{y}. The pair is guaranteed to be different (in the +sense of @code{eq?}) from every previously existing object. +@end deffn + +@rnindex pair? +@deffn primitive pair? x +Return @code{#t} if @var{x} is a pair; otherwise return +@code{#f}. +@end deffn + +The two parts of a pair are traditionally called @emph{car} and +@emph{cdr}. They can be retrieved with procedures of the same name +(@code{car} and @code{cdr}), and can be modified with the procedures +@code{set-car!} and @code{set-cdr!}. Since a very common operation in +Scheme programs is to access the car of a pair, or the car of the cdr of +a pair, etc., the procedures called @code{caar}, @code{cadr} and so on +are also predefined. + +@rnindex car +@rnindex cdr +@deffn primitive car pair +@deffnx primitive cdr pair +Return the car or the cdr of @var{pair}, respectively. +@end deffn + +@deffn primitive caar pair +@deffnx primitive cadr pair @dots{} +@deffnx primitive cdddar pair +@deffnx primitive cddddr pair +These procedures are compositions of @code{car} and @code{cdr}, where +for example @code{caddr} could be defined by + +@lisp +(define caddr (lambda (x) (car (cdr (cdr x))))) +@end lisp +@end deffn + +@rnindex set-car! +@deffn primitive set-car! pair value +Stores @var{value} in the car field of @var{pair}. The value returned +by @code{set-car!} is unspecified. +@end deffn + +@rnindex set-cdr! +@deffn primitive set-cdr! pair value +Stores @var{value} in the cdr field of @var{pair}. The value returned +by @code{set-cdr!} is unspecified. +@end deffn + + +@node Lists +@section Lists +@tpindex Lists + +@c FIXME::martin: Review me! + +A very important data type in Scheme---as well as in all other Lisp +dialects---is the data type @dfn{list}.@footnote{Strictly speaking, +Scheme does not have a real datatype @emph{list}. Lists are made up of +chained @emph{pairs}, and only exist by definition---a list is a chain +of pairs which looks like a list.} + +This is the short definition of what a list is: + +@itemize @bullet +@item +Either the empty list @code{()}, + +@item +or a pair which has a list in its cdr. +@end itemize + +@c FIXME::martin: Describe the pair chaining in more detail. + +@c FIXME::martin: What is a proper, what an improper list? +@c What is a circular list? + +@c FIXME::martin: Maybe steal some graphics from the Elisp reference +@c manual? + +@menu +* List Syntax:: Writing literal lists. +* List Predicates:: Testing lists. +* List Constructors:: Creating new lists. +* List Selection:: Selecting from lists, getting their length. +* Append/Reverse:: Appending and reversing lists. +* List Modifification:: Modifying list structure. +* List Searching:: Searching for list elements +* List Mapping:: Applying procedures to lists. +@end menu + +@node List Syntax +@subsection List Read Syntax + +@c FIXME::martin: Review me! + +The syntax for lists is an opening parentheses, then all the elements of +the list (separated by whitespace) and finally a closing +parentheses.@footnote{Note that there is no separation character between +the list elements, like a comma or a semicolon.}. + +@lisp +(1 2 3) ; @r{a list of the numbers 1, 2 and 3} +("foo" bar 3.1415) ; @r{a string, a symbol and a real number} +() ; @r{the empty list} +@end lisp + +The last example needs a bit more explanation. A list with no elements, +called the @dfn{empty list}, is special in some ways. It is used for +terminating lists by storing it into the cdr of the last pair that makes +up a list. An example will clear that up: + +@lisp +(car '(1)) +@result{} +1 +(cdr '(1)) +@result{} +() +@end lisp + +This example also shows that lists have to be quoted (REFFIXME) when +written, because they would otherwise be mistakingly taken as procedure +applications (@pxref{Simple Invocation}). + + +@node List Predicates +@subsection List Predicates + +@c FIXME::martin: Review me! + +Often it is useful to test whether a given Scheme object is a list or +not. List-processing procedures could use this information to test +whether their input is valid, or they could do different things +depending on the datatype of their arguments. + +@rnindex list? +@deffn primitive list? x +Return @code{#t} iff @var{x} is a proper list, else @code{#f}. +@end deffn + +The predicate @code{null?} is often used in list-processing code to +tell whether a given list has run out of elements. That is, a loop +somehow deals with the elements of a list until the list satisfies +@code{null?}. Then, teh algorithm terminates. + +@rnindex null? +@deffn primitive null? x +Return @code{#t} iff @var{x} is the empty list, else @code{#f}. +@end deffn + +@node List Constructors +@subsection List Constructors + +This section describes the procedures for constructing new lists. +@code{list} simply returns a list where the elements are the arguments, +@code{cons*} is similar, but the last argument is stored in the cdr of +the last pair of the list. + +@rnindex list +@deffn primitive list arg1 @dots{} +Return a list containing @var{objs}, the arguments to +@code{list}. +@end deffn + +@deffn primitive cons* arg1 arg2 @dots{} +Like @code{list}, but the last arg provides the tail of the +constructed list, returning @code{(cons @var{arg1} (cons +@var{arg2} (cons @dots{} @var{argn})))}. Requires at least one +argument. If given one argument, that argument is returned as +result. This function is called @code{list*} in some other +Schemes and in Common LISP. +@end deffn + +@deffn primitive list-copy lst +Return a (newly-created) copy of @var{lst}. +@end deffn + +@deffn procedure make-list n [init] +Create a list containing of @var{n} elements, where each element is +initialized to @var{init}. @var{init} defaults to the empty list +@code{()} if not given. +@end deffn + +Note that @code{list-copy} only makes a copy of the pairs which make up +the spine of the lists. The list elements are not copied, which means +that modifying the elements of the new list also modyfies the elements +of the old list. On the other hand, applying procedures like +@code{set-cdr!} or @code{delv!} to the new list will not alter the old +list. If you also need to copy the list elements (making a deep copy), +use the procedure @code{copy-tree} (@pxref{Copying}). + +@node List Selection +@subsection List Selection + +@c FIXME::martin: Review me! + +These procedures are used to get some information about a list, or to +retrieve one or more elements of a list. + +@rnindex length +@deffn primitive length lst +Return the number of elements in list @var{lst}. +@end deffn + +@deffn primitive last-pair lst +Return a pointer to the last pair in @var{lst}, signalling an error if +@var{lst} is circular. +@end deffn + +@rnindex list-ref +@deffn primitive list-ref list k +Return the @var{k}th element from @var{list}. +@end deffn + +@rnindex list-tail +@deffn primitive list-tail lst k +@deffnx primitive list-cdr-ref lst k +Return the "tail" of @var{lst} beginning with its @var{k}th element. +The first element of the list is considered to be element 0. + +@code{list-tail} and @code{list-cdr-ref} are identical. It may help to +think of @code{list-cdr-ref} as accessing the @var{k}th cdr of the list, +or returning the results of cdring @var{k} times down @var{lst}. +@end deffn + +@deffn primitive list-head lst k +Copy the first @var{k} elements from @var{lst} into a new list, and +return it. +@end deffn + +@node Append/Reverse +@subsection Append and Reverse + +@c FIXME::martin: Review me! + +@code{append} and @code{append!} are used to concatenate two or more +lists in order to form a new list. @code{reverse} and @code{reverse!} +return lists with the same elements as their arguments, but in reverse +order. The procedure variants with an @code{!} directly modify the +pairs which form the list, whereas the other procedures create new +pairs. This is why you should be careful when using the side-effecting +variants. + +@rnindex append +@deffn primitive append . args +Return a list consisting of the elements the lists passed as +arguments. +@lisp +(append '(x) '(y)) @result{} (x y) +(append '(a) '(b c d)) @result{} (a b c d) +(append '(a (b)) '((c))) @result{} (a (b) (c)) +@end lisp +The resulting list is always newly allocated, except that it +shares structure with the last list argument. The last +argument may actually be any object; an improper list results +if the last argument is not a proper list. +@lisp +(append '(a b) '(c . d)) @result{} (a b c . d) +(append '() 'a) @result{} a +@end lisp +@end deffn + +@deffn primitive append! . lists +A destructive version of @code{append} (@pxref{Pairs and +lists,,,r5rs, The Revised^5 Report on Scheme}). The cdr field +of each list's final pair is changed to point to the head of +the next list, so no consing is performed. Return a pointer to +the mutated list. +@end deffn + +@rnindex reverse +@deffn primitive reverse lst +Return a new list that contains the elements of @var{lst} but +in reverse order. +@end deffn + +@c NJFIXME explain new_tail +@deffn primitive reverse! lst [new_tail] +A destructive version of @code{reverse} (@pxref{Pairs and lists,,,r5rs, +The Revised^5 Report on Scheme}). The cdr of each cell in @var{lst} is +modified to point to the previous list element. Return a pointer to the +head of the reversed list. + +Caveat: because the list is modified in place, the tail of the original +list now becomes its head, and the head of the original list now becomes +the tail. Therefore, the @var{lst} symbol to which the head of the +original list was bound now points to the tail. To ensure that the head +of the modified list is not lost, it is wise to save the return value of +@code{reverse!} +@end deffn + +@node List Modifification +@subsection List Modification + +@c FIXME::martin: Review me! + +The following procedures modify existing list. @code{list-set!} and +@code{list-cdr-set!} change which elements a list contains, the various +deletion procedures @code{delq}, @code{delv} etc. + +@deffn primitive list-set! list k val +Set the @var{k}th element of @var{list} to @var{val}. +@end deffn + +@deffn primitive list-cdr-set! list k val +Set the @var{k}th cdr of @var{list} to @var{val}. +@end deffn + +@deffn primitive delq item lst +Return a newly-created copy of @var{lst} with elements +@code{eq?} to @var{item} removed. This procedure mirrors +@code{memq}: @code{delq} compares elements of @var{lst} against +@var{item} with @code{eq?}. +@end deffn + +@deffn primitive delv item lst +Return a newly-created copy of @var{lst} with elements +@code{eqv?} to @var{item} removed. This procedure mirrors +@code{memv}: @code{delv} compares elements of @var{lst} against +@var{item} with @code{eqv?}. +@end deffn + +@deffn primitive delete item lst +Return a newly-created copy of @var{lst} with elements +@code{equal?} to @var{item} removed. This procedure mirrors +@code{member}: @code{delete} compares elements of @var{lst} +against @var{item} with @code{equal?}. +@end deffn + +@deffn primitive delq! item lst +@deffnx primitive delv! item lst +@deffnx primitive delete! item lst +These procedures are destructive versions of @code{delq}, @code{delv} +and @code{delete}: they modify the pointers in the existing @var{lst} +rather than creating a new list. Caveat evaluator: Like other +destructive list functions, these functions cannot modify the binding of +@var{lst}, and so cannot be used to delete the first element of +@var{lst} destructively. +@end deffn + +@deffn primitive delq1! item lst +Like @code{delq!}, but only deletes the first occurrence of +@var{item} from @var{lst}. Tests for equality using +@code{eq?}. See also @code{delv1!} and @code{delete1!}. +@end deffn + +@deffn primitive delv1! item lst +Like @code{delv!}, but only deletes the first occurrence of +@var{item} from @var{lst}. Tests for equality using +@code{eqv?}. See also @code{delq1!} and @code{delete1!}. +@end deffn + +@deffn primitive delete1! item lst +Like @code{delete!}, but only deletes the first occurrence of +@var{item} from @var{lst}. Tests for equality using +@code{equal?}. See also @code{delq1!} and @code{delv1!}. +@end deffn + +@node List Searching +@subsection List Searching + +@c FIXME::martin: Review me! + +The following procedures search lists for particular elements. They use +different comparison predicates for comparing list elements with the +object to be seached. When they fail, they return @code{#f}, otherwise +they return the sublist whose car is equal to the search object, where +equality depends on the equality predicate used. + +@rnindex memq +@deffn primitive memq x lst +Return the first sublist of @var{lst} whose car is @code{eq?} +to @var{x} where the sublists of @var{lst} are the non-empty +lists returned by @code{(list-tail @var{lst} @var{k})} for +@var{k} less than the length of @var{lst}. If @var{x} does not +occur in @var{lst}, then @code{#f} (not the empty list) is +returned. +@end deffn + +@rnindex memv +@deffn primitive memv x lst +Return the first sublist of @var{lst} whose car is @code{eqv?} +to @var{x} where the sublists of @var{lst} are the non-empty +lists returned by @code{(list-tail @var{lst} @var{k})} for +@var{k} less than the length of @var{lst}. If @var{x} does not +occur in @var{lst}, then @code{#f} (not the empty list) is +returned. +@end deffn + +@rnindex member +@deffn primitive member x lst +Return the first sublist of @var{lst} whose car is +@code{equal?} to @var{x} where the sublists of @var{lst} are +the non-empty lists returned by @code{(list-tail @var{lst} +@var{k})} for @var{k} less than the length of @var{lst}. If +@var{x} does not occur in @var{lst}, then @code{#f} (not the +empty list) is returned. +@end deffn + +[FIXME: is there any reason to have the `sloppy' functions available at +high level at all? Maybe these docs should be relegated to a "Guile +Internals" node or something. -twp] + +@deffn primitive sloppy-memq x lst +This procedure behaves like @code{memq}, but does no type or error checking. +Its use is recommended only in writing Guile internals, +not for high-level Scheme programs. +@end deffn + +@deffn primitive sloppy-memv x lst +This procedure behaves like @code{memv}, but does no type or error checking. +Its use is recommended only in writing Guile internals, +not for high-level Scheme programs. +@end deffn + +@deffn primitive sloppy-member x lst +This procedure behaves like @code{member}, but does no type or error checking. +Its use is recommended only in writing Guile internals, +not for high-level Scheme programs. +@end deffn + +@node List Mapping +@subsection List Mapping + +@c FIXME::martin: Review me! + +List processing is very convenient in Scheme because the process of +iterating over the elements of a list can be highly abstracted. The +procedures in this section are the most basic iterating procedures for +lists. They take a procedure and one or more lists as arguments, and +apply the procedure to each element of the list. They differ in what +the result of the invocation is. + +@rnindex map +@c begin (texi-doc-string "guile" "map") +@deffn primitive map proc arg1 arg2 @dots{} +@deffnx primitive map-in-order proc arg1 arg2 @dots{} +Apply @var{proc} to each element of the list @var{arg1} (if only two +arguments are given), or to the corresponding elements of the argument +lists (if more than two arguments are given). The result(s) of the +procedure applications are saved and returned in a list. For +@code{map}, the order of procedure applications is not specified, +@code{map-in-order} applies the procedure from left to right to the list +elements. +@end deffn + +@rnindex for-each +@c begin (texi-doc-string "guile" "for-each") +@deffn primitive for-each proc arg1 arg2 @dots{} +Like @code{map}, but the procedure is always applied from left to right, +and the result(s) of the procedure applications are thrown away. The +return value is not specified. +@end deffn + + +@node Vectors +@section Vectors +@tpindex Vectors + +@c FIXME::martin: Review me! + +@c FIXME::martin: Should the subsections of this section be nodes +@c of their own, or are the resulting nodes too short, then? + +Vectors are sequences of Scheme objects. Unlike lists, the length of a +vector, once the vector is created, cannot be changed. The advantage of +vectors over lists is that the time required to access one element of a +vector is constant, whereas lists have an access time linear to the +index of the accessed element in the list. + +Note that the vectors documented in this section can contain any kind of +Scheme object, it is even possible to have different types of objects in +the same vector. + +@subsection Vector Read Syntax + +Vectors can literally be entered in source code, just like strings, +characters or some of the other data types. The read syntax for vectors +is as follows: A sharp sign (@code{#}), followed by an opening +parentheses, all elements of the vector in their respective read syntax, +and finally a closing parentheses. The following are examples of the +read syntax for vectors; where the first vector only contains numbers +and the second three different object types: a string, a symbol and a +number in hexidecimal notation. + +@lisp +#(1 2 3) +#("Hello" foo #xdeadbeef) +@end lisp + +@subsection Vector Predicates + +@rnindex vector? +@deffn primitive vector? obj +Return @code{#t} if @var{obj} is a vector, otherwise return +@code{#f}. +@end deffn + +@subsection Vector Constructors + +@rnindex make-vector +@deffn primitive make-vector k [fill] +Return a newly allocated vector of @var{k} elements. If a +second argument is given, then each element is initialized to +@var{fill}. Otherwise the initial contents of each element is +unspecified. +@end deffn + +@rnindex vector +@rnindex list->vector +@deffn primitive vector . l +@deffnx primitive list->vector l +Return a newly allocated vector whose elements contain the +given arguments. Analogous to @code{list}. + +@lisp +(vector 'a 'b 'c) @result{} #(a b c) +@end lisp +@end deffn + +@rnindex vector->list +@deffn primitive vector->list v +Return a newly allocated list of the objects contained in the +elements of @var{vector}. + +@lisp +(vector->list '#(dah dah didah)) @result{} (dah dah didah) +(list->vector '(dididit dah)) @result{} #(dididit dah) +@end lisp +@end deffn + +@subsection Vector Modification + +A vector created by any of the vector constructor procedures +(@pxref{Vectors}) documented above can be modified using the +following procedures. + +According to R5RS, using any of these procedures on literally entered +vectors is an error, because these vectors are considered to be +constant, although Guile currently does not detect this error. + +@rnindex vector-set! +@deffn primitive vector-set! vector k obj +@var{k} must be a valid index of @var{vector}. +@code{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}. +The value returned by @samp{vector-set!} is unspecified. +@lisp +(let ((vec (vector 0 '(2 2 2 2) "Anna"))) + (vector-set! vec 1 '("Sue" "Sue")) + vec) @result{} #(0 ("Sue" "Sue") "Anna") +(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector +@end lisp +@end deffn + +@rnindex vector-fill! +@deffn primitive vector-fill! v fill +Store @var{fill} in every element of @var{vector}. The value +returned by @code{vector-fill!} is unspecified. +@end deffn + +@deffn primitive vector-move-left! vec1 start1 end1 vec2 start2 +Vector version of @code{substring-move-left!}. +@end deffn + +@deffn primitive vector-move-right! vec1 start1 end1 vec2 start2 +Vector version of @code{substring-move-right!}. +@end deffn + +@subsection Vector Selection + +These procedures return information about a given vector, such as the +size or what elements are contained in the vector. + +@rnindex vector-length +@deffn primitive vector-length vector +Returns the number of elements in @var{vector} as an exact integer. +@end deffn + +@rnindex vector-ref +@deffn primitive vector-ref vector k +@var{k} must be a valid index of @var{vector}. +@samp{Vector-ref} returns the contents of element @var{k} of +@var{vector}. +@lisp +(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8 +(vector-ref '#(1 1 2 3 5 8 13 21) + (let ((i (round (* 2 (acos -1))))) + (if (inexact? i) + (inexact->exact i) + i))) @result{} 13 +@end lisp +@end deffn + + +@node Records +@section Records + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +A @dfn{record type} is a first class object representing a user-defined +data type. A @dfn{record} is an instance of a record type. + +@deffn procedure record? obj +Returns @code{#t} if @var{obj} is a record of any type and @code{#f} +otherwise. + +Note that @code{record?} may be true of any Scheme value; there is no +promise that records are disjoint with other Scheme types. +@end deffn + +@deffn procedure make-record-type type-name field-names +Returns a @dfn{record-type descriptor}, a value representing a new data +type disjoint from all others. The @var{type-name} argument must be a +string, but is only used for debugging purposes (such as the printed +representation of a record of the new type). The @var{field-names} +argument is a list of symbols naming the @dfn{fields} of a record of the +new type. It is an error if the list contains any duplicates. It is +unspecified how record-type descriptors are represented.@refill +@end deffn + +@deffn procedure record-constructor rtd [field-names] +Returns a procedure for constructing new members of the type represented +by @var{rtd}. The returned procedure accepts exactly as many arguments +as there are symbols in the given list, @var{field-names}; these are +used, in order, as the initial values of those fields in a new record, +which is returned by the constructor procedure. The values of any +fields not named in that list are unspecified. The @var{field-names} +argument defaults to the list of field names in the call to +@code{make-record-type} that created the type represented by @var{rtd}; +if the @var{field-names} argument is provided, it is an error if it +contains any duplicates or any symbols not in the default list.@refill +@end deffn + +@deffn procedure record-predicate rtd +Returns a procedure for testing membership in the type represented by +@var{rtd}. The returned procedure accepts exactly one argument and +returns a true value if the argument is a member of the indicated record +type; it returns a false value otherwise.@refill +@end deffn + +@deffn procedure record-accessor rtd field-name +Returns a procedure for reading the value of a particular field of a +member of the type represented by @var{rtd}. The returned procedure +accepts exactly one argument which must be a record of the appropriate +type; it returns the current value of the field named by the symbol +@var{field-name} in that record. The symbol @var{field-name} must be a +member of the list of field-names in the call to @code{make-record-type} +that created the type represented by @var{rtd}.@refill +@end deffn + +@deffn procedure record-modifier rtd field-name +Returns a procedure for writing the value of a particular field of a +member of the type represented by @var{rtd}. The returned procedure +accepts exactly two arguments: first, a record of the appropriate type, +and second, an arbitrary Scheme value; it modifies the field named by +the symbol @var{field-name} in that record to contain the given value. +The returned value of the modifier procedure is unspecified. The symbol +@var{field-name} must be a member of the list of field-names in the call +to @code{make-record-type} that created the type represented by +@var{rtd}.@refill +@end deffn + +@deffn procedure record-type-descriptor record +Returns a record-type descriptor representing the type of the given +record. That is, for example, if the returned descriptor were passed to +@code{record-predicate}, the resulting predicate would return a true +value when passed the given record. Note that it is not necessarily the +case that the returned descriptor is the one that was passed to +@code{record-constructor} in the call that created the constructor +procedure that created the given record.@refill +@end deffn + +@deffn procedure record-type-name rtd +Returns the type-name associated with the type represented by rtd. The +returned value is @code{eqv?} to the @var{type-name} argument given in +the call to @code{make-record-type} that created the type represented by +@var{rtd}.@refill +@end deffn + +@deffn procedure record-type-fields rtd +Returns a list of the symbols naming the fields in members of the type +represented by @var{rtd}. The returned value is @code{equal?} to the +field-names argument given in the call to @code{make-record-type} that +created the type represented by @var{rtd}.@refill +@end deffn + + +@node Structures +@section Structures +@tpindex Structures + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +A @dfn{structure type} is a first class user-defined data type. A +@dfn{structure} is an instance of a structure type. A structure type is +itself a structure. + +Structures are less abstract and more general than traditional records. +In fact, in Guile Scheme, records are implemented using structures. + +@menu +* Structure Concepts:: The structure of Structures +* Structure Layout:: Defining the layout of structure types +* Structure Basics:: make-, -ref and -set! procedures for structs +* Vtables:: Accessing type-specific data +@end menu + +@node Structure Concepts +@subsection Structure Concepts + +A structure object consists of a handle, structure data, and a vtable. +The handle is a Scheme value which points to both the vtable and the +structure's data. Structure data is a dynamically allocated region of +memory, private to the structure, divided up into typed fields. A +vtable is another structure used to hold type-specific data. Multiple +structures can share a common vtable. + +Three concepts are key to understanding structures. + +@itemize @bullet{} +@item @dfn{layout specifications} + +Layout specifications determine how memory allocated to structures is +divided up into fields. Programmers must write a layout specification +whenever a new type of structure is defined. + +@item @dfn{structural accessors} + +Structure access is by field number. There is only one set of +accessors common to all structure objects. + +@item @dfn{vtables} + +Vtables, themselves structures, are first class representations of +disjoint sub-types of structures in general. In most cases, when a +new structure is created, programmers must specifiy a vtable for the +new structure. Each vtable has a field describing the layout of its +instances. Vtables can have additional, user-defined fields as well. +@end itemize + + + +@node Structure Layout +@subsection Structure Layout + +When a structure is created, a region of memory is allocated to hold its +state. The @dfn{layout} of the structure's type determines how that +memory is divided into fields. + +Each field has a specified type. There are only three types allowed, each +corresponding to a one letter code. The allowed types are: + +@itemize @bullet{} +@item 'u' -- unprotected + +The field holds binary data that is not GC protected. + +@item 'p' -- protected + +The field holds a Scheme value and is GC protected. + +@item 's' -- self + +The field holds a Scheme value and is GC protected. When a structure is +created with this type of field, the field is initialized to refer to +the structure's own handle. This kind of field is mainly useful when +mixing Scheme and C code in which the C code may need to compute a +structure's handle given only the address of its malloced data. +@end itemize + + +Each field also has an associated access protection. There are only +three kinds of protection, each corresponding to a one letter code. +The allowed protections are: + +@itemize @bullet{} +@item 'w' -- writable + +The field can be read and written. + +@item 'r' -- readable + +The field can be read, but not written. + +@item 'o' -- opaque + +The field can be neither read nor written. This kind +of protection is for fields useful only to built-in routines. +@end itemize + +A layout specification is described by stringing together pairs +of letters: one to specify a field type and one to specify a field +protection. For example, a traditional cons pair type object could +be described as: + +@example +; cons pairs have two writable fields of Scheme data +"pwpw" +@end example + +A pair object in which the first field is held constant could be: + +@example +"prpw" +@end example + +Binary fields, (fields of type "u"), hold one @emph{word} each. The +size of a word is a machine dependent value defined to be equal to the +value of the C expression: @code{sizeof (long)}. + +The last field of a structure layout may specify a tail array. +A tail array is indicated by capitalizing the field's protection +code ('W', 'R' or 'O'). A tail-array field is replaced by +a read-only binary data field containing an array size. The array +size is determined at the time the structure is created. It is followed +by a corresponding number of fields of the type specified for the +tail array. For example, a conventional Scheme vector can be +described as: + +@example +; A vector is an arbitrary number of writable fields holding Scheme +; values: +"pW" +@end example + +In the above example, field 0 contains the size of the vector and +fields beginning at 1 contain the vector elements. + +A kind of tagged vector (a constant tag followed by conventioal +vector elements) might be: + +@example +"prpW" +@end example + + +Structure layouts are represented by specially interned symbols whose +name is a string of type and protection codes. To create a new +structure layout, use this procedure: + +@deffn primitive make-struct-layout fields +Return a new structure layout object. + +@var{fields} must be a string made up of pairs of characters +strung together. The first character of each pair describes a field +type, the second a field protection. Allowed types are 'p' for +GC-protected Scheme data, 'u' for unprotected binary data, and 's' for +a field that points to the structure itself. Allowed protections +are 'w' for mutable fields, 'r' for read-only fields, and 'o' for opaque +fields. The last field protection specification may be capitalized to +indicate that the field is a tail-array. +@end deffn + + + +@node Structure Basics +@subsection Structure Basics + +This section describes the basic procedures for creating and accessing +structures. + +@deffn primitive make-struct vtable tail_array_size . init +Create a new structure. + +@var{type} must be a vtable structure (@pxref{Vtables}). + +@var{tail-elts} must be a non-negative integer. If the layout +specification indicated by @var{type} includes a tail-array, +this is the number of elements allocated to that array. + +The @var{init1}, @dots{} are optional arguments describing how +successive fields of the structure should be initialized. Only fields +with protection 'r' or 'w' can be initialized, except for fields of +type 's', which are automatically initialized to point to the new +structure itself; fields with protection 'o' can not be initialized by +Scheme programs. + +If fewer optional arguments than initializable fields are supplied, +fields of type 'p' get default value #f while fields of type 'u' are +initialized to 0. + +Structs are currently the basic representation for record-like data +structures in Guile. The plan is to eventually replace them with a +new representation which will at the same time be easier to use and +more powerful. + +For more information, see the documentation for @code{make-vtable-vtable}. +@end deffn + +@deffn primitive struct? x +Return @code{#t} iff @var{obj} is a structure object, else +@code{#f}. +@end deffn + + +@deffn primitive struct-ref handle pos +@deffnx primitive struct-set! struct n value +Access (or modify) the @var{n}th field of @var{struct}. + +If the field is of type 'p', then it can be set to an arbitrary value. + +If the field is of type 'u', then it can only be set to a non-negative +integer value small enough to fit in one machine word. +@end deffn + + + +@node Vtables +@subsection Vtables + +Vtables are structures that are used to represent structure types. Each +vtable contains a layout specification in field +@code{vtable-index-layout} -- instances of the type are laid out +according to that specification. Vtables contain additional fields +which are used only internally to libguile. The variable +@code{vtable-offset-user} is bound to a field number. Vtable fields +at that position or greater are user definable. + +@deffn primitive struct-vtable handle +Return the vtable structure that describes the type of @var{struct}. +@end deffn + +@deffn primitive struct-vtable? x +Return @code{#t} iff obj is a vtable structure. +@end deffn + +If you have a vtable structure, @code{V}, you can create an instance of +the type it describes by using @code{(make-struct V ...)}. But where +does @code{V} itself come from? One possibility is that @code{V} is an +instance of a user-defined vtable type, @code{V'}, so that @code{V} is +created by using @code{(make-struct V' ...)}. Another possibility is +that @code{V} is an instance of the type it itself describes. Vtable +structures of the second sort are created by this procedure: + +@deffn primitive make-vtable-vtable user_fields tail_array_size . init +Return a new, self-describing vtable structure. + +@var{user-fields} is a string describing user defined fields of the +vtable beginning at index @code{vtable-offset-user} +(see @code{make-struct-layout}). + +@var{tail-size} specifies the size of the tail-array (if any) of +this vtable. + +@var{init1}, @dots{} are the optional initializers for the fields of +the vtable. + +Vtables have one initializable system field---the struct printer. +This field comes before the user fields in the initializers passed +to @code{make-vtable-vtable} and @code{make-struct}, and thus works as +a third optional argument to @code{make-vtable-vtable} and a fourth to +@code{make-struct} when creating vtables: + +If the value is a procedure, it will be called instead of the standard +printer whenever a struct described by this vtable is printed. +The procedure will be called with arguments STRUCT and PORT. + +The structure of a struct is described by a vtable, so the vtable is +in essence the type of the struct. The vtable is itself a struct with +a vtable. This could go on forever if it weren't for the +vtable-vtables which are self-describing vtables, and thus terminate +the chain. + +There are several potential ways of using structs, but the standard +one is to use three kinds of structs, together building up a type +sub-system: one vtable-vtable working as the root and one or several +"types", each with a set of "instances". (The vtable-vtable should be +compared to the class <class> which is the class of itself.) + +@lisp +(define ball-root (make-vtable-vtable "pr" 0)) + +(define (make-ball-type ball-color) + (make-struct ball-root 0 + (make-struct-layout "pw") + (lambda (ball port) + (format port "#<a ~A ball owned by ~A>" + (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 red (make-ball-type 'red)) +(define green (make-ball-type 'green)) + +(define (make-ball type owner) (make-struct type 0 owner)) + +(define ball (make-ball green 'Nisse)) +ball @result{} #<a green ball owned by Nisse> +@end lisp +@end deffn + +@deffn primitive struct-vtable-name vtable +Return the name of the vtable @var{vtable}. +@end deffn + +@deffn primitive set-struct-vtable-name! vtable name +Set the name of the vtable @var{vtable} to @var{name}. +@end deffn + +@deffn primitive struct-vtable-tag handle +Return the vtable tag of the structure @var{handle}. +@end deffn + + +@node Arrays +@section Arrays +@tpindex Arrays + +@menu +* Conventional Arrays:: Arrays with arbitrary data. +* Array Mapping:: Applying a procedure to the contents of an array. +* Uniform Arrays:: Arrays with data of a single type. +* Bit Vectors:: Vectors of bits. +@end menu + +@node Conventional Arrays +@subsection Conventional Arrays + +@dfn{Conventional arrays} are a collection of cells organised into an +arbitrary number of dimensions. Each cell can hold any kind of Scheme +value and can be accessed in constant time by supplying an index for +each dimension. This contrasts with uniform arrays, which use memory +more efficiently but can hold data of only a single type, and lists +where inserting and deleting cells is more efficient, but more time +is usually required to access a particular cell. + +A conventional array is displayed as @code{#} followed by the @dfn{rank} +(number of dimensions) followed by the cells, organised into dimensions +using parentheses. The nesting depth of the parentheses is equal to +the rank. + +When an array is created, the number of dimensions and range of each +dimension must be specified, e.g., to create a 2x3 array with a +zero-based index: + +@example +(make-array 'ho 2 3) @result{} +#2((ho ho ho) (ho ho ho)) +@end example + +The range of each dimension can also be given explicitly, e.g., another +way to create the same array: + +@example +(make-array 'ho '(0 1) '(0 2)) @result{} +#2((ho ho ho) (ho ho ho)) +@end example + +A conventional array with one dimension based at zero is identical to +a vector: + +@example +(make-array 'ho 3) @result{} +#(ho ho ho) +@end example + +The following procedures can be used with conventional arrays (or vectors). + +@deffn primitive array? v [prot] +Return @code{#t} if the @var{obj} is an array, and @code{#f} if +not. The @var{prototype} argument is used with uniform arrays +and is described elsewhere. +@end deffn + +@deffn procedure make-array initial-value bound1 bound2 @dots{} +Creates and returns an array that has as many dimensions as there are +@var{bound}s and fills it with @var{initial-value}. +@end deffn + +@c array-ref's type is `compiled-closure'. There's some weird stuff +@c going on in array.c, too. Let's call it a primitive. -twp + +@deffn primitive uniform-vector-ref v args +@deffnx primitive array-ref v . args +Return the element at the @code{(index1, index2)} element in +@var{array}. +@end deffn + +@deffn primitive array-in-bounds? v . args +Return @code{#t} if its arguments would be acceptable to +@code{array-ref}. +@end deffn + +@deffn primitive array-set! v obj . args +@deffnx primitive uniform-array-set1! v obj args +Sets the element at the @code{(index1, index2)} element in @var{array} to +@var{new-value}. The value returned by array-set! is unspecified. +@end deffn + +@deffn primitive make-shared-array oldra mapfunc . dims +@code{make-shared-array} can be used to create shared subarrays of other +arrays. The @var{mapper} is a function that translates coordinates in +the new array into coordinates in the old array. A @var{mapper} must be +linear, and its range must stay within the bounds of the old array, but +it can be otherwise arbitrary. A simple example: +@lisp +(define fred (make-array #f 8 8)) +(define freds-diagonal + (make-shared-array fred (lambda (i) (list i i)) 8)) +(array-set! freds-diagonal 'foo 3) +(array-ref fred 3 3) @result{} foo +(define freds-center + (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2)) +(array-ref freds-center 0 0) @result{} foo +@end lisp +@end deffn + +@deffn primitive shared-array-increments ra +For each dimension, return the distance between elements in the root vector. +@end deffn + +@deffn primitive shared-array-offset ra +Return the root vector index of the first element in the array. +@end deffn + +@deffn primitive shared-array-root ra +Return the root vector of a shared array. +@end deffn + +@deffn primitive transpose-array ra . args +Return an array sharing contents with @var{array}, but with +dimensions arranged in a different order. There must be one +@var{dim} argument for each dimension of @var{array}. +@var{dim0}, @var{dim1}, @dots{} should be integers between 0 +and the rank of the array to be returned. Each integer in that +range must appear at least once in the argument list. + +The values of @var{dim0}, @var{dim1}, @dots{} correspond to +dimensions in the array to be returned, their positions in the +argument list to dimensions of @var{array}. Several @var{dim}s +may have the same value, in which case the returned array will +have smaller rank than @var{array}. + +@lisp +(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d)) +(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d) +(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{} + #2((a 4) (b 5) (c 6)) +@end lisp +@end deffn + +@deffn primitive enclose-array ra . axes +@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than +the rank of @var{array}. @var{enclose-array} returns an array +resembling an array of shared arrays. The dimensions of each shared +array are the same as the @var{dim}th dimensions of the original array, +the dimensions of the outer array are the same as those of the original +array that did not match a @var{dim}. + +An enclosed array is not a general Scheme array. Its elements may not +be set using @code{array-set!}. Two references to the same element of +an enclosed array will be @code{equal?} but will not in general be +@code{eq?}. The value returned by @var{array-prototype} when given an +enclosed array is unspecified. + +examples: +@lisp +(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) @result{} + #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))> +@end lisp +@end deffn + +@deffn procedure array-shape array +Returns a list of inclusive bounds of integers. +@example +(array-shape (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) (0 4)) +@end example +@end deffn + +@deffn primitive array-dimensions ra +@code{Array-dimensions} is similar to @code{array-shape} but replaces +elements with a @code{0} minimum with one greater than the maximum. So: +@lisp +(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5) +@end lisp +@end deffn + +@deffn primitive array-rank ra +Return the number of dimensions of @var{obj}. If @var{obj} is +not an array, @code{0} is returned. +@end deffn + +@deffn primitive array->list v +Return a list consisting of all the elements, in order, of +@var{array}. +@end deffn + +@deffn primitive array-copy! src dst +@deffnx primitive array-copy-in-order! src dst +Copies every element from vector or array @var{source} to the +corresponding element of @var{destination}. @var{destination} must have +the same rank as @var{source}, and be at least as large in each +dimension. The order is unspecified. +@end deffn + +@deffn primitive array-fill! ra fill +Stores @var{fill} in every element of @var{array}. The value returned +is unspecified. +@end deffn + +@c begin (texi-doc-string "guile" "array-equal?") +@deffn primitive array-equal? ra0 ra1 +Returns @code{#t} iff all arguments are arrays with the same shape, the +same type, and have corresponding elements which are either +@code{equal?} or @code{array-equal?}. This function differs from +@code{equal?} in that a one dimensional shared array may be +@var{array-equal?} but not @var{equal?} to a vector or uniform vector. +@end deffn + +@deffn primitive array-contents ra [strict] +@deffnx primitive array-contents array strict +If @var{array} may be @dfn{unrolled} into a one dimensional shared array +without changing their order (last subscript changing fastest), then +@code{array-contents} returns that shared array, otherwise it returns +@code{#f}. All arrays made by @var{make-array} and +@var{make-uniform-array} may be unrolled, some arrays made by +@var{make-shared-array} may not be. + +If the optional argument @var{strict} is provided, a shared array will +be returned only if its elements are stored internally contiguous in +memory. +@end deffn + +@node Array Mapping +@subsection Array Mapping + +@deffn primitive array-map! ra0 proc . lra +@deffnx primitive array-map-in-order! ra0 proc . lra +@var{array1}, @dots{} must have the same number of dimensions as +@var{array0} and have a range for each index which includes the range +for the corresponding index in @var{array0}. @var{proc} is applied to +each tuple of elements of @var{array1} @dots{} and the result is stored +as the corresponding element in @var{array0}. The value returned is +unspecified. The order of application is unspecified. +@end deffn + +@deffn primitive array-for-each proc ra0 . lra +@var{proc} is applied to each tuple of elements of @var{array0} @dots{} +in row-major order. The value returned is unspecified. +@end deffn + +@deffn primitive array-index-map! ra proc +applies @var{proc} to the indices of each element of @var{array} in +turn, storing the result in the corresponding element. The value +returned and the order of application are unspecified. + +One can implement @var{array-indexes} as +@lisp +(define (array-indexes array) + (let ((ra (apply make-array #f (array-shape array)))) + (array-index-map! ra (lambda x x)) + ra)) +@end lisp +Another example: +@lisp +(define (apl:index-generator n) + (let ((v (make-uniform-vector n 1))) + (array-index-map! v (lambda (i) i)) + v)) +@end lisp +@end deffn + +@node Uniform Arrays +@subsection Uniform Arrays +@tpindex Uniform Arrays + +@noindent +@dfn{Uniform arrays} have elements all of the +same type and occupy less storage than conventional +arrays. Uniform arrays with a single zero-based dimension +are also known as @dfn{uniform vectors}. The procedures in +this section can also be used on conventional arrays, vectors, +bit-vectors and strings. + +@noindent +When creating a uniform array, the type of data to be stored +is indicated with a @var{prototype} argument. The following table +lists the types available and example prototypes: + +@example +prototype type printing character + +#t boolean (bit-vector) b +#\a char (string) a +#\nul byte (integer) y +'s short (integer) h +1 unsigned long (integer) u +-1 signed long (integer) e +'l signed long long (integer) l +1.0 float (single precision) s +1/3 double (double precision float) i +0+i complex (double precision) c +() conventional vector +@end example + +@noindent +Unshared uniform arrays of characters with a single zero-based dimension +are identical to strings: + +@example +(make-uniform-array #\a 3) @result{} +"aaa" +@end example + +@noindent +Unshared uniform arrays of booleans with a single zero-based dimension +are identical to @ref{Bit Vectors, bit-vectors}. + +@example +(make-uniform-array #t 3) @result{} +#*111 +@end example + +@noindent +Other uniform vectors are written in a form similar to that of vectors, +except that a single character from the above table is put between +@code{#} and @code{(}. For example, a uniform vector of signed +long integers is displayed in the form @code{'#e(3 5 9)}. + +@deffn primitive array? v [prot] +Returns @code{#t} if the @var{obj} is an array, and @code{#f} if not. + +The @var{prototype} argument is used with uniform arrays and is described +elsewhere. +@end deffn + +@deffn procedure make-uniform-array prototype bound1 bound2 @dots{} +Creates and returns a uniform array of type corresponding to +@var{prototype} that has as many dimensions as there are @var{bound}s +and fills it with @var{prototype}. +@end deffn + +@deffn primitive array-prototype ra +Return an object that would produce an array of the same type +as @var{array}, if used as the @var{prototype} for +@code{make-uniform-array}. +@end deffn + +@deffn primitive list->uniform-array ndim prot lst +@deffnx procedure list->uniform-vector prot lst +Return a uniform array of the type indicated by prototype +@var{prot} with elements the same as those of @var{lst}. +Elements must be of the appropriate type, no coercions are +done. +@end deffn + +@deffn primitive uniform-vector-fill! uve fill +Stores @var{fill} in every element of @var{uve}. The value returned is +unspecified. +@end deffn + +@deffn primitive uniform-vector-length v +Return the number of elements in @var{uve}. +@end deffn + +@deffn primitive dimensions->uniform-array dims prot [fill] +@deffnx primitive make-uniform-vector length prototype [fill] +Create and return a uniform array or vector of type +corresponding to @var{prototype} with dimensions @var{dims} or +length @var{length}. If @var{fill} is supplied, it's used to +fill the array, otherwise @var{prototype} is used. +@end deffn + +@c Another compiled-closure. -twp + +@deffn primitive uniform-array-read! ra [port_or_fd [start [end]]] +@deffnx primitive uniform-vector-read! uve [port-or-fdes] [start] [end] +Attempts to read all elements of @var{ura}, in lexicographic order, as +binary objects from @var{port-or-fdes}. +If an end of file is encountered during +uniform-array-read! the objects up to that point only are put into @var{ura} +(starting at the beginning) and the remainder of the array is +unchanged. + +The optional arguments @var{start} and @var{end} allow +a specified region of a vector (or linearized array) to be read, +leaving the remainder of the vector unchanged. + +@code{uniform-array-read!} returns the number of objects read. +@var{port-or-fdes} may be omitted, in which case it defaults to the value +returned by @code{(current-input-port)}. +@end deffn + +@deffn primitive uniform-array-write v [port_or_fd [start [end]]] +@deffnx primitive uniform-vector-write uve [port-or-fdes] [start] [end] +Writes all elements of @var{ura} as binary objects to +@var{port-or-fdes}. + +The optional arguments @var{start} +and @var{end} allow +a specified region of a vector (or linearized array) to be written. + +The number of objects actually written is returned. +@var{port-or-fdes} may be +omitted, in which case it defaults to the value returned by +@code{(current-output-port)}. +@end deffn + +@node Bit Vectors +@subsection Bit Vectors + +@noindent +Bit vectors are a specific type of uniform array: an array of booleans +with a single zero-based index. + +@noindent +They are displayed as a sequence of @code{0}s and +@code{1}s prefixed by @code{#*}, e.g., + +@example +(make-uniform-vector 8 #t #f) @result{} +#*00000000 + +#b(#t #f #t) @result{} +#*101 +@end example + +@deffn primitive bit-count b bitvector +Return the number of occurrences of the boolean @var{b} in +@var{bitvector}. +@end deffn + +@deffn primitive bit-position item v k +Return the minimum index of an occurrence of @var{bool} in +@var{bv} which is at least @var{k}. If no @var{bool} occurs +within the specified range @code{#f} is returned. +@end deffn + +@deffn primitive bit-invert! v +Modifies @var{bv} by replacing each element with its negation. +@end deffn + +@deffn primitive bit-set*! v kv obj +If uve is a bit-vector @var{bv} and uve must be of the same +length. If @var{bool} is @code{#t}, uve is OR'ed into +@var{bv}; If @var{bool} is @code{#f}, the inversion of uve is +AND'ed into @var{bv}. + +If uve is a unsigned long integer vector all the elements of uve +must be between 0 and the @code{length} of @var{bv}. The bits +of @var{bv} corresponding to the indexes in uve are set to +@var{bool}. The return value is unspecified. +@end deffn + +@deffn primitive bit-count* v kv obj +Return +@lisp +(bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t). +@end lisp +@var{bv} is not modified. +@end deffn + + +@node Association Lists and Hash Tables +@section Association Lists and Hash Tables + +This chapter discusses dictionary objects: data structures that are +useful for organizing and indexing large bodies of information. + +@menu +* Dictionary Types:: About dictionary types; what they're good for. +* Association Lists:: List-based dictionaries. +* Hash Tables:: Table-based dictionaries. +@end menu + +@node Dictionary Types +@subsection Dictionary Types + +A @dfn{dictionary} object is a data structure used to index +information in a user-defined way. In standard Scheme, the main +aggregate data types are lists and vectors. Lists are not really +indexed at all, and vectors are indexed only by number +(e.g. @code{(vector-ref foo 5)}). Often you will find it useful +to index your data on some other type; for example, in a library +catalog you might want to look up a book by the name of its +author. Dictionaries are used to help you organize information in +such a way. + +An @dfn{association list} (or @dfn{alist} for short) is a list of +key-value pairs. Each pair represents a single quantity or +object; the @code{car} of the pair is a key which is used to +identify the object, and the @code{cdr} is the object's value. + +A @dfn{hash table} also permits you to index objects with +arbitrary keys, but in a way that makes looking up any one object +extremely fast. A well-designed hash system makes hash table +lookups almost as fast as conventional array or vector references. + +Alists are popular among Lisp programmers because they use only +the language's primitive operations (lists, @dfn{car}, @dfn{cdr} +and the equality primitives). No changes to the language core are +necessary. Therefore, with Scheme's built-in list manipulation +facilities, it is very convenient to handle data stored in an +association list. Also, alists are highly portable and can be +easily implemented on even the most minimal Lisp systems. + +However, alists are inefficient, especially for storing large +quantities of data. Because we want Guile to be useful for large +software systems as well as small ones, Guile provides a rich set +of tools for using either association lists or hash tables. + +@node Association Lists +@subsection Association Lists +@tpindex Association Lists +@tpindex Alist + +@cindex Association List +@cindex Alist +@cindex Database + +An association list is a conventional data structure that is often used +to implement simple key-value databases. It consists of a list of +entries in which each entry is a pair. The @dfn{key} of each entry is +the @code{car} of the pair and the @dfn{value} of each entry is the +@code{cdr}. + +@example +ASSOCIATION LIST ::= '( (KEY1 . VALUE1) + (KEY2 . VALUE2) + (KEY3 . VALUE3) + @dots{} + ) +@end example + +@noindent +Association lists are also known, for short, as @dfn{alists}. + +The structure of an association list is just one example of the infinite +number of possible structures that can be built using pairs and lists. +As such, the keys and values in an association list can be manipulated +using the general list structure procedures @code{cons}, @code{car}, +@code{cdr}, @code{set-car!}, @code{set-cdr!} and so on. However, +because association lists are so useful, Guile also provides specific +procedures for manipulating them. + +@menu +* Alist Key Equality:: +* Adding or Setting Alist Entries:: +* Retrieving Alist Entries:: +* Removing Alist Entries:: +* Sloppy Alist Functions:: +* Alist Example:: +@end menu + +@node Alist Key Equality +@subsubsection Alist Key Equality + +All of Guile's dedicated association list procedures, apart from +@code{acons}, come in three flavours, depending on the level of equality +that is required to decide whether an existing key in the association +list is the same as the key that the procedure call uses to identify the +required entry. + +@itemize @bullet +@item +Procedures with @dfn{assq} in their name use @code{eq?} to determine key +equality. + +@item +Procedures with @dfn{assv} in their name use @code{eqv?} to determine +key equality. + +@item +Procedures with @dfn{assoc} in their name use @code{equal?} to +determine key equality. +@end itemize + +@code{acons} is an exception because it is used to build association +lists which do not require their entries' keys to be unique. + +@node Adding or Setting Alist Entries +@subsubsection Adding or Setting Alist Entries + +@code{acons} adds a new entry to an association list and returns the +combined association list. The combined alist is formed by consing the +new entry onto the head of the alist specified in the @code{acons} +procedure call. So the specified alist is not modified, but its +contents become shared with the tail of the combined alist that +@code{acons} returns. + +In the most common usage of @code{acons}, a variable holding the +original association list is updated with the combined alist: + +@example +(set! address-list (acons name address address-list)) +@end example + +In such cases, it doesn't matter that the old and new values of +@code{address-list} share some of their contents, since the old value is +usually no longer independently accessible. + +Note that @code{acons} adds the specified new entry regardless of +whether the alist may already contain entries with keys that are, in +some sense, the same as that of the new entry. Thus @code{acons} is +ideal for building alists where there is no concept of key uniqueness. + +@example +(set! task-list (acons 3 "pay gas bill" '())) +task-list +@result{} +((3 . "pay gas bill")) + +(set! task-list (acons 3 "tidy bedroom" task-list)) +task-list +@result{} +((3 . "tidy bedroom") (3 . "pay gas bill")) +@end example + +@code{assq-set!}, @code{assv-set!} and @code{assoc-set!} are used to add +or replace an entry in an association list where there @emph{is} a +concept of key uniqueness. If the specified association list already +contains an entry whose key is the same as that specified in the +procedure call, the existing entry is replaced by the new one. +Otherwise, the new entry is consed onto the head of the old association +list to create the combined alist. In all cases, these procedures +return the combined alist. + +@code{assq-set!} and friends @emph{may} destructively modify the +structure of the old association list in such a way that an existing +variable is correctly updated without having to @code{set!} it to the +value returned: + +@example +address-list +@result{} +(("mary" . "34 Elm Road") ("james" . "16 Bow Street")) + +(assoc-set! address-list "james" "1a London Road") +@result{} +(("mary" . "34 Elm Road") ("james" . "1a London Road")) + +address-list +@result{} +(("mary" . "34 Elm Road") ("james" . "1a London Road")) +@end example + +Or they may not: + +@example +(assoc-set! address-list "bob" "11 Newington Avenue") +@result{} +(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road") + ("james" . "1a London Road")) + +address-list +@result{} +(("mary" . "34 Elm Road") ("james" . "1a London Road")) +@end example + +The only safe way to update an association list variable when adding or +replacing an entry like this is to @code{set!} the variable to the +returned value: + +@example +(set! address-list + (assoc-set! address-list "bob" "11 Newington Avenue")) +address-list +@result{} +(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road") + ("james" . "1a London Road")) +@end example + +Because of this slight inconvenience, you may find it more convenient to +use hash tables to store dictionary data. If your application will not +be modifying the contents of an alist very often, this may not make much +difference to you. + +If you need to keep the old value of an association list in a form +independent from the list that results from modification by +@code{acons}, @code{assq-set!}, @code{assv-set!} or @code{assoc-set!}, +use @code{list-copy} to copy the old association list before modifying +it. + +@deffn primitive acons key value alist +Adds a new key-value pair to @var{alist}. A new pair is +created whose car is @var{key} and whose cdr is @var{value}, and the +pair is consed onto @var{alist}, and the new list is returned. This +function is @emph{not} destructive; @var{alist} is not modified. +@end deffn + +@deffn primitive assq-set! alist key val +@deffnx primitive assv-set! alist key value +@deffnx primitive assoc-set! alist key value +Reassociate @var{key} in @var{alist} with @var{value}: find any existing +@var{alist} entry for @var{key} and associate it with the new +@var{value}. If @var{alist} does not contain an entry for @var{key}, +add a new one. Return the (possibly new) alist. + +These functions do not attempt to verify the structure of @var{alist}, +and so may cause unusual results if passed an object that is not an +association list. +@end deffn + +@node Retrieving Alist Entries +@subsubsection Retrieving Alist Entries +@rnindex assq +@rnindex assv +@rnindex assoc + +@code{assq}, @code{assv} and @code{assoc} take an alist and a key as +arguments and return the entry for that key if an entry exists, or +@code{#f} if there is no entry for that key. Note that, in the cases +where an entry exists, these procedures return the complete entry, that +is @code{(KEY . VALUE)}, not just the value. + +@deffn primitive assq key alist +@deffnx primitive assv key alist +@deffnx primitive assoc key alist +Fetches the entry in @var{alist} that is associated with @var{key}. To +decide whether the argument @var{key} matches a particular entry in +@var{alist}, @code{assq} compares keys with @code{eq?}, @code{assv} +uses @code{eqv?} and @code{assoc} uses @code{equal?}. If @var{key} +cannot be found in @var{alist} (according to whichever equality +predicate is in use), then @code{#f} is returned. These functions +return the entire alist entry found (i.e. both the key and the value). +@end deffn + +@code{assq-ref}, @code{assv-ref} and @code{assoc-ref}, on the other +hand, take an alist and a key and return @emph{just the value} for that +key, if an entry exists. If there is no entry for the specified key, +these procedures return @code{#f}. + +This creates an ambiguity: if the return value is @code{#f}, it means +either that there is no entry with the specified key, or that there +@emph{is} an entry for the specified key, with value @code{#f}. +Consequently, @code{assq-ref} and friends should only be used where it +is known that an entry exists, or where the ambiguity doesn't matter +for some other reason. + +@deffn primitive assq-ref alist key +@deffnx primitive assv-ref alist key +@deffnx primitive assoc-ref alist key +Like @code{assq}, @code{assv} and @code{assoc}, except that only the +value associated with @var{key} in @var{alist} is returned. These +functions are equivalent to + +@lisp +(let ((ent (@var{associator} @var{key} @var{alist}))) + (and ent (cdr ent))) +@end lisp + +where @var{associator} is one of @code{assq}, @code{assv} or @code{assoc}. +@end deffn + +@node Removing Alist Entries +@subsubsection Removing Alist Entries + +To remove the element from an association list whose key matches a +specified key, use @code{assq-remove!}, @code{assv-remove!} or +@code{assoc-remove!} (depending, as usual, on the level of equality +required between the key that you specify and the keys in the +association list). + +As with @code{assq-set!} and friends, the specified alist may or may not +be modified destructively, and the only safe way to update a variable +containing the alist is to @code{set!} it to the value that +@code{assq-remove!} and friends return. + +@example +address-list +@result{} +(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road") + ("james" . "1a London Road")) + +(set! address-list (assoc-remove! address-list "mary")) +address-list +@result{} +(("bob" . "11 Newington Avenue") ("james" . "1a London Road")) +@end example + +Note that, when @code{assq/v/oc-remove!} is used to modify an +association list that has been constructed only using the corresponding +@code{assq/v/oc-set!}, there can be at most one matching entry in the +alist, so the question of multiple entries being removed in one go does +not arise. If @code{assq/v/oc-remove!} is applied to an association +list that has been constructed using @code{acons}, or an +@code{assq/v/oc-set!} with a different level of equality, or any mixture +of these, it removes only the first matching entry from the alist, even +if the alist might contain further matching entries. For example: + +@example +(define address-list '()) +(set! address-list (assq-set! address-list "mary" "11 Elm Street")) +(set! address-list (assq-set! address-list "mary" "57 Pine Drive")) +address-list +@result{} +(("mary" . "57 Pine Drive") ("mary" . "11 Elm Street")) + +(set! address-list (assoc-remove! address-list "mary")) +address-list +@result{} +(("mary" . "11 Elm Street")) +@end example + +In this example, the two instances of the string "mary" are not the same +when compared using @code{eq?}, so the two @code{assq-set!} calls add +two distinct entries to @code{address-list}. When compared using +@code{equal?}, both "mary"s in @code{address-list} are the same as the +"mary" in the @code{assoc-remove!} call, but @code{assoc-remove!} stops +after removing the first matching entry that it finds, and so one of the +"mary" entries is left in place. + +@deffn primitive assq-remove! alist key +@deffnx primitive assv-remove! alist key +@deffnx primitive assoc-remove! alist key +Delete the first entry in @var{alist} associated with @var{key}, and return +the resulting alist. +@end deffn + +@node Sloppy Alist Functions +@subsubsection Sloppy Alist Functions + +@code{sloppy-assq}, @code{sloppy-assv} and @code{sloppy-assoc} behave +like the corresponding non-@code{sloppy-} procedures, except that they +return @code{#f} when the specified association list is not well-formed, +where the non-@code{sloppy-} versions would signal an error. + +Specifically, there are two conditions for which the non-@code{sloppy-} +procedures signal an error, which the @code{sloppy-} procedures handle +instead by returning @code{#f}. Firstly, if the specified alist as a +whole is not a proper list: + +@example +(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 NULLP): "open sesame" +ABORT: (wrong-type-arg) + +(sloppy-assoc "mary" '((1 . 2) ("key" . "door") . "open sesame")) +@result{} +#f +@end example + +@noindent +Secondly, if one of the entries in the specified alist is not a pair: + +@example +(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 CONSP): 2 +ABORT: (wrong-type-arg) + +(sloppy-assoc 2 '((1 . 1) 2 (3 . 9))) +@result{} +#f +@end example + +Unless you are explicitly working with badly formed association lists, +it is much safer to use the non-@code{sloppy-} procedures, because they +help to highlight coding and data errors that the @code{sloppy-} +versions would silently cover up. + +@deffn primitive sloppy-assq key alist +Behaves like @code{assq} but does not do any error checking. +Recommended only for use in Guile internals. +@end deffn + +@deffn primitive sloppy-assv key alist +Behaves like @code{assv} but does not do any error checking. +Recommended only for use in Guile internals. +@end deffn + +@deffn primitive sloppy-assoc key alist +Behaves like @code{assoc} but does not do any error checking. +Recommended only for use in Guile internals. +@end deffn + +@node Alist Example +@subsubsection Alist Example + +Here is a longer example of how alists may be used in practice. + +@lisp +(define capitals '(("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Miami"))) + +;; What's the capital of Oregon? +(assoc "Oregon" capitals) @result{} ("Oregon" . "Salem") +(assoc-ref capitals "Oregon") @result{} "Salem" + +;; We left out South Dakota. +(set! capitals + (assoc-set! capitals "South Dakota" "Bismarck")) +capitals +@result{} (("South Dakota" . "Bismarck") + ("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Miami")) + +;; And we got Florida wrong. +(set! capitals + (assoc-set! capitals "Florida" "Tallahassee")) +capitals +@result{} (("South Dakota" . "Bismarck") + ("New York" . "Albany") + ("Oregon" . "Salem") + ("Florida" . "Tallahassee")) + +;; After Oregon secedes, we can remove it. +(set! capitals + (assoc-remove! capitals "Oregon")) +capitals +@result{} (("South Dakota" . "Bismarck") + ("New York" . "Albany") + ("Florida" . "Tallahassee")) +@end lisp + +@node Hash Tables +@subsection Hash Tables +@tpindex Hash Tables + +@c FIXME::martin: Review me! + +Hash tables are dictionaries which offer similar functionality as +association lists: They provide a mapping from keys to values. The +difference is that association lists need time linear in the size of +elements when searching for entries, whereas hash tables can normally +search in constant time. The drawback is that hash tables require a +little bit more memory, and that you can not use the normal list +procedures (@pxref{Lists}) for working with them. + +@menu +* Hash Table Examples:: Demonstration of hash table usage. +* Hash Table Reference:: Hash table procedure descriptions. +@end menu + + +@node Hash Table Examples +@subsubsection Hash Table Examples + +@c FIXME::martin: Review me! + +For demonstration purposes, this section gives a few usage examples of +some hash table procedures, together with some explanation what they do. + +First we start by creating a new hash table with 31 slots, and +populate it with two key/value pairs. + +@lisp +(define h (make-hash-table 31)) + +(hashq-create-handle! h 'foo "bar") +@result{} +(foo . "bar") + +(hashq-create-handle! h 'braz "zonk") +@result{} +(braz . "zonk") + +(hashq-create-handle! h 'frob #f) +@result{} +(frob . #f) +@end lisp + +You can get the value for a given key with the procedure +@code{hashq-ref}, but the problem with this procedure is that you +cannot reliably determine whether a key does exists in the table. The +reason is that the procedure returns @code{#f} if the key is not in +the table, but it will return the same value if the key is in the +table and just happens to have the value @code{#f}, as you can see in +the following examples. + +@lisp +(hashq-ref h 'foo) +@result{} +"bar" + +(hashq-ref h 'frob) +@result{} +#f + +(hashq-ref h 'not-there) +@result{} +#f +@end lisp + +Better is to use the procedure @code{hashq-get-handle}, which makes a +distinction between the two cases. Just like @code{assq}, this +procedure returns a key/value-pair on success, and @code{#f} if the +key is not found. + +@lisp +(hashq-get-handle h 'foo) +@result{} +(foo . "bar") + +(hashq-get-handle h 'not-there) +@result{} +#f +@end lisp + +There is no procedure for calculating the number of key/value-pairs in +a hash table, but @code{hash-fold} can be used for doing exactly that. + +@lisp +(hash-fold (lambda (key value seed) (+ 1 seed)) 0 h) +@result{} +3 +@end lisp + +@node Hash Table Reference +@subsubsection Hash Table Reference + +Like the association list functions, the hash table functions come +in several varieties: @code{hashq}, @code{hashv}, and @code{hash}. +The @code{hashq} functions use @code{eq?} to determine whether two +keys match. The @code{hashv} functions use @code{eqv?}, and the +@code{hash} functions use @code{equal?}. + +In each of the functions that follow, the @var{table} argument +must be a vector. The @var{key} and @var{value} arguments may be +any Scheme object. + +@deffn procedure make-hash-table size +Create a new hash table of @var{size} slots. Note that the number of +slots does not limit the size of the table, it just tells how large +the underlying vector will be. The @var{size} should be similar to +the expected number of elements which will be added to the table, but +they need not match. For good performance, it might be a good idea to +use a prime number as the @var{size}. +@end deffn + +@deffn primitive hashq-ref table key [dflt] +Look up @var{key} in the hash table @var{table}, and return the +value (if any) associated with it. If @var{key} is not found, +return @var{default} (or @code{#f} if no @var{default} argument +is supplied). Uses @code{eq?} for equality testing. +@end deffn + +@deffn primitive hashv-ref table key [dflt] +Look up @var{key} in the hash table @var{table}, and return the +value (if any) associated with it. If @var{key} is not found, +return @var{default} (or @code{#f} if no @var{default} argument +is supplied). Uses @code{eqv?} for equality testing. +@end deffn + +@deffn primitive hash-ref table key [dflt] +Look up @var{key} in the hash table @var{table}, and return the +value (if any) associated with it. If @var{key} is not found, +return @var{default} (or @code{#f} if no @var{default} argument +is supplied). Uses @code{equal?} for equality testing. +@end deffn + +@deffn primitive hashq-set! table key val +Find the entry in @var{table} associated with @var{key}, and +store @var{value} there. Uses @code{eq?} for equality testing. +@end deffn + +@deffn primitive hashv-set! table key val +Find the entry in @var{table} associated with @var{key}, and +store @var{value} there. Uses @code{eqv?} for equality testing. +@end deffn + +@deffn primitive hash-set! table key val +Find the entry in @var{table} associated with @var{key}, and +store @var{value} there. Uses @code{equal?} for equality +testing. +@end deffn + +@deffn primitive hashq-remove! table key +Remove @var{key} (and any value associated with it) from +@var{table}. Uses @code{eq?} for equality tests. +@end deffn + +@deffn primitive hashv-remove! table key +Remove @var{key} (and any value associated with it) from +@var{table}. Uses @code{eqv?} for equality tests. +@end deffn + +@deffn primitive hash-remove! table key +Remove @var{key} (and any value associated with it) from +@var{table}. Uses @code{equal?} for equality tests. +@end deffn + +The standard hash table functions may be too limited for some +applications. For example, you may want a hash table to store +strings in a case-insensitive manner, so that references to keys +named ``foobar'', ``FOOBAR'' and ``FooBaR'' will all yield the +same item. Guile provides you with @dfn{extended} hash tables +that permit you to specify a hash function and associator function +of your choosing. The functions described in the rest of this section +can be used to implement such custom hash table structures. + +If you are unfamiliar with the inner workings of hash tables, then +this facility will probably be a little too abstract for you to +use comfortably. If you are interested in learning more, see an +introductory textbook on data structures or algorithms for an +explanation of how hash tables are implemented. + +@deffn primitive hashq key size +Determine a hash value for @var{key} that is suitable for +lookups in a hashtable of size @var{size}, where @code{eq?} is +used as the equality predicate. The function returns an +integer in the range 0 to @var{size} - 1. Note that +@code{hashq} may use internal addresses. Thus two calls to +hashq where the keys are @code{eq?} are not guaranteed to +deliver the same value if the key object gets garbage collected +in between. This can happen, for example with symbols: +@code{(hashq 'foo n) (gc) (hashq 'foo n)} may produce two +different values, since @code{foo} will be garbage collected. +@end deffn + +@deffn primitive hashv key size +Determine a hash value for @var{key} that is suitable for +lookups in a hashtable of size @var{size}, where @code{eqv?} is +used as the equality predicate. The function returns an +integer in the range 0 to @var{size} - 1. Note that +@code{(hashv key)} may use internal addresses. Thus two calls +to hashv where the keys are @code{eqv?} are not guaranteed to +deliver the same value if the key object gets garbage collected +in between. This can happen, for example with symbols: +@code{(hashv 'foo n) (gc) (hashv 'foo n)} may produce two +different values, since @code{foo} will be garbage collected. +@end deffn + +@deffn primitive hash key size +Determine a hash value for @var{key} that is suitable for +lookups in a hashtable of size @var{size}, where @code{equal?} +is used as the equality predicate. The function returns an +integer in the range 0 to @var{size} - 1. +@end deffn + +@deffn primitive hashx-ref hash assoc table key [dflt] +This behaves the same way as the corresponding @code{ref} +function, but uses @var{hash} as a hash function and +@var{assoc} to compare keys. @code{hash} must be a function +that takes two arguments, a key to be hashed and a table size. +@code{assoc} must be an associator function, like @code{assoc}, +@code{assq} or @code{assv}. + +By way of illustration, @code{hashq-ref table key} is +equivalent to @code{hashx-ref hashq assq table key}. +@end deffn + +@deffn primitive hashx-set! hash assoc table key val +This behaves the same way as the corresponding @code{set!} +function, but uses @var{hash} as a hash function and +@var{assoc} to compare keys. @code{hash} must be a function +that takes two arguments, a key to be hashed and a table size. +@code{assoc} must be an associator function, like @code{assoc}, +@code{assq} or @code{assv}. + + By way of illustration, @code{hashq-set! table key} is +equivalent to @code{hashx-set! hashq assq table key}. +@end deffn + +@deffn primitive hashq-get-handle table key +This procedure returns the @code{(key . value)} pair from the +hash table @var{table}. If @var{table} does not hold an +associated value for @var{key}, @code{#f} is returned. +Uses @code{eq?} for equality testing. +@end deffn + +@deffn primitive hashv-get-handle table key +This procedure returns the @code{(key . value)} pair from the +hash table @var{table}. If @var{table} does not hold an +associated value for @var{key}, @code{#f} is returned. +Uses @code{eqv?} for equality testing. +@end deffn + +@deffn primitive hash-get-handle table key +This procedure returns the @code{(key . value)} pair from the +hash table @var{table}. If @var{table} does not hold an +associated value for @var{key}, @code{#f} is returned. +Uses @code{equal?} for equality testing. +@end deffn + +@deffn primitive hashx-get-handle hash assoc table key +This behaves the same way as the corresponding +@code{-get-handle} function, but uses @var{hash} as a hash +function and @var{assoc} to compare keys. @code{hash} must be +a function that takes two arguments, a key to be hashed and a +table size. @code{assoc} must be an associator function, like +@code{assoc}, @code{assq} or @code{assv}. +@end deffn + +@deffn primitive hashq-create-handle! table key init +This function looks up @var{key} in @var{table} and returns its handle. +If @var{key} is not already present, a new handle is created which +associates @var{key} with @var{init}. +@end deffn + +@deffn primitive hashv-create-handle! table key init +This function looks up @var{key} in @var{table} and returns its handle. +If @var{key} is not already present, a new handle is created which +associates @var{key} with @var{init}. +@end deffn + +@deffn primitive hash-create-handle! table key init +This function looks up @var{key} in @var{table} and returns its handle. +If @var{key} is not already present, a new handle is created which +associates @var{key} with @var{init}. +@end deffn + +@deffn primitive hashx-create-handle! hash assoc table key init +This behaves the same way as the corresponding +@code{-create-handle} function, but uses @var{hash} as a hash +function and @var{assoc} to compare keys. @code{hash} must be +a function that takes two arguments, a key to be hashed and a +table size. @code{assoc} must be an associator function, like +@code{assoc}, @code{assq} or @code{assv}. +@end deffn + +@deffn primitive hash-fold proc init table +An iterator over hash-table elements. +Accumulates and returns a result by applying PROC successively. +The arguments to PROC are "(key value prior-result)" where key +and value are successive pairs from the hash table TABLE, and +prior-result is either INIT (for the first application of PROC) +or the return value of the previous application of PROC. +For example, @code{(hash-fold acons '() tab)} will convert a hash +table into an a-list of key-value pairs. +@end deffn + + +@node Hooks +@section Hooks +@tpindex Hooks + +@c FIXME::martin: Review me! + +A hook is basically a list of procedures to be called at well defined +points in time. Hooks are used internally for several debugging +facilities, but they can be used in user code, too. + +Hooks are created with @code{make-hook}, then procedures can be added to +a hook with @code{add-hook!} or removed with @code{remove-hook!} or +@code{reset-hook!}. The procedures stored in a hook can be invoked with +@code{run-hook}. + +@menu +* Hook Examples:: Hook usage by example. +* Hook Reference:: Reference of all hook procedures. +@end menu + +@node Hook Examples +@subsection Hook Examples + +Hook usage is shown by some examples in this section. First, we will +define a hook of arity 2 --- that is, the procedures stored in the hook +will have to accept two arguments. + +@lisp +(define hook (make-hook 2)) +hook +@result{} #<hook 2 40286c90> +@end lisp + +Now we are ready to add some procedures to the newly created hook with +@code{add-hook!}. In the following example, two procedures are added, +which print different messages and do different things with their +arguments. When the procedures have been added, we can invoke them +using @code{run-hook}. + +@lisp +(add-hook! hook (lambda (x y) + (display "Foo: ") + (display (+ x y)) + (newline))) +(add-hook! hook (lambda (x y) + (display "Bar: ") + (display (* x y)) + (newline))) +(run-hook hook 3 4) +@print{} Bar: 12 +@print{} Foo: 7 +@end lisp + +Note that the procedures are called in reverse order than they were +added. This can be changed by providing the optional third argument +on the second call to @code{add-hook!}. + +@lisp +(add-hook! hook (lambda (x y) + (display "Foo: ") + (display (+ x y)) + (newline))) +(add-hook! hook (lambda (x y) + (display "Bar: ") + (display (* x y)) + (newline)) + #t) ; @r{<- Change here!} +(run-hook hook 3 4) +@print{} Foo: 7 +@print{} Bar: 12 +@end lisp + +@node Hook Reference +@subsection Hook Reference + +When a hook is created with @code{make-hook}, you can supply the arity +of the procedures which can be added to the hook. The arity defaults to +zero. All procedures of a hook must have the same arity, and when the +procedures are invoked using @code{run-hook}, the number of arguments +must match the arity of the procedures. + +The order in which procedures are added to a hook matters. If the third +parameter to @var{add-hook!} is omitted or is equal to @code{#f}, the +procedure is added in front of the procedures which might already be on +that hook, otherwise the procedure is added at the end. The procedures +are always called from first to last when they are invoked via +@code{run-hook}. + +When calling @code{hook->list}, the procedures in the resulting list are +in the same order as they would have been called by @code{run-hook}. + +@deffn primitive make-hook [n_args] +Create a hook for storing procedure of arity @var{n_args}. +@var{n_args} defaults to zero. The returned value is a hook +object to be used with the other hook procedures. +@end deffn + +@deffn primitive hook? x +Return @code{#t} if @var{x} is a hook, @code{#f} otherwise. +@end deffn + +@deffn primitive hook-empty? hook +Return @code{#t} if @var{hook} is an empty hook, @code{#f} +otherwise. +@end deffn + +@deffn primitive add-hook! hook proc [append_p] +Add the procedure @var{proc} to the hook @var{hook}. The +procedure is added to the end if @var{append_p} is true, +otherwise it is added to the front. The return value of this +procedure is not specified. +@end deffn + +@deffn primitive remove-hook! hook proc +Remove the procedure @var{proc} from the hook @var{hook}. The +return value of this procedure is not specified. +@end deffn + +@deffn primitive reset-hook! hook +Remove all procedures from the hook @var{hook}. The return +value of this procedure is not specified. +@end deffn + +@deffn primitive run-hook hook . args +Apply all procedures from the hook @var{hook} to the arguments +@var{args}. The order of the procedure application is first to +last. The return value of this procedure is not specified. +@end deffn + +@deffn primitive hook->list hook +Convert the procedure list of @var{hook} to a list. +@end deffn + + +@node Other Data Types +@section Other Core Guile Data Types + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-debug.texi b/doc/ref/scheme-debug.texi new file mode 100644 index 000000000..d9387f5d0 --- /dev/null +++ b/doc/ref/scheme-debug.texi @@ -0,0 +1,187 @@ +@page +@node Debugging +@chapter Internal Debugging Interface + +--- The name of this chapter needs to clearly distinguish it + from the appendix describing the debugger UI. The intro + should have a pointer to the UI appendix. + +@deffn primitive display-error stack port subr message args rest +Display an error message to the output port @var{port}. +@var{stack} is the saved stack for the error, @var{subr} is +the name of the procedure in which the error occured and +@var{message} is the actual error message, which may contain +formatting instructions. These will format the arguments in +the list @var{args} accordingly. @var{rest} is currently +ignored. +@end deffn + +@deffn primitive display-application frame [port [indent]] +Display a procedure application @var{frame} to the output port +@var{port}. @var{indent} specifies the indentation of the +output. +@end deffn + +@deffn primitive display-backtrace stack port [first [depth]] +Display a backtrace to the output port @var{port}. @var{stack} +is the stack to take the backtrace from, @var{first} specifies +where in the stack to start and @var{depth} how much frames +to display. Both @var{first} and @var{depth} can be @code{#f}, +which means that default values will be used. +@end deffn + +@deffn primitive backtrace +Display a backtrace of the stack saved by the last error +to the current output port. +@end deffn + +@deffn primitive malloc-stats +Return an alist ((@var{what} . @var{n}) ...) describing number +of malloced objects. +@var{what} is the second argument to @code{scm_must_malloc}, +@var{n} is the number of objects of that type currently +allocated. +@end deffn + +@deffn primitive debug-options-interface [setting] +Option interface for the debug options. Instead of using +this procedure directly, use the procedures @code{debug-enable}, +@code{debug-disable}, @code{debug-set!} and @var{debug-options}. +@end deffn + +@deffn primitive with-traps thunk +Call @var{thunk} with traps enabled. +@end deffn + +@deffn primitive memoized? obj +Return @code{#t} if @var{obj} is memoized. +@end deffn + +@deffn primitive unmemoize m +Unmemoize the memoized expression @var{m}, +@end deffn + +@deffn primitive memoized-environment m +Return the environment of the memoized expression @var{m}. +@end deffn + +@deffn primitive procedure-name proc +Return the name of the procedure @var{proc} +@end deffn + +@deffn primitive procedure-source proc +Return the source of the procedure @var{proc}. +@end deffn + +@deffn primitive procedure-environment proc +Return the environment of the procedure @var{proc}. +@end deffn + +@deffn primitive debug-object? obj +Return @code{#t} if @var{obj} is a debug object. +@end deffn + +@deffn primitive frame-arguments frame +Return the arguments of @var{frame}. +@end deffn + +@deffn primitive frame-evaluating-args? frame +Return @code{#t} if @var{frame} contains evaluated arguments. +@end deffn + +@deffn primitive frame-next frame +Return the next frame of @var{frame}, or @code{#f} if +@var{frame} is the last frame in its stack. +@end deffn + +@deffn primitive frame-number frame +Return the frame number of @var{frame}. +@end deffn + +@deffn primitive frame-overflow? frame +Return @code{#t} if @var{frame} is an overflow frame. +@end deffn + +@deffn primitive frame-previous frame +Return the previous frame of @var{frame}, or @code{#f} if +@var{frame} is the first frame in its stack. +@end deffn + +@deffn primitive frame-procedure frame +Return the procedure for @var{frame}, or @code{#f} if no +procedure is associated with @var{frame}. +@end deffn + +@deffn primitive frame-procedure? frame +Return @code{#t} if a procedure is associated with @var{frame}. +@end deffn + +@deffn primitive frame-real? frame +Return @code{#t} if @var{frame} is a real frame. +@end deffn + +@deffn primitive frame-source frame +Return the source of @var{frame}. +@end deffn + +@deffn primitive frame? obj +Return @code{#t} if @var{obj} is a stack frame. +@end deffn + +@deffn primitive last-stack-frame obj +Return a stack which consists of a single frame, which is the +last stack frame for @var{obj}. @var{obj} must be either a +debug object or a continuation. +@end deffn + +@deffn primitive make-stack obj . args +Create a new stack. If @var{obj} is @code{#t}, the current +evaluation stack is used for creating the stack frames, +otherwise the frames are taken from @var{obj} (which must be +either a debug object or a continuation). + +@var{args} should be a list containing any combination of +integer, procedure and @code{#t} values. + +These values specify various ways of cutting away uninteresting +stack frames from the top and bottom of the stack that +@code{make-stack} returns. They come in pairs like this: +@code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2} +@var{outer_cut_2} @dots{})}. + +Each @var{inner_cut_N} can be @code{#t}, an integer, or a +procedure. @code{#t} means to cut away all frames up to but +excluding the first user module frame. An integer means to cut +away exactly that number of frames. A procedure means to cut +away all frames up to but excluding the application frame whose +procedure matches the specified one. + +Each @var{outer_cut_N} can be an integer or a procedure. An +integer means to cut away that number of frames. A procedure +means to cut away frames down to but excluding the application +frame whose procedure matches the specified one. + +If the @var{outer_cut_N} of the last pair is missing, it is +taken as 0. +@end deffn + +@deffn primitive stack-id stack +Return the identifier given to @var{stack} by @code{start-stack}. +@end deffn + +@deffn primitive stack-length stack +Return the length of @var{stack}. +@end deffn + +@deffn primitive stack-ref stack i +Return the @var{i}'th frame from @var{stack}. +@end deffn + +@deffn primitive stack? obj +Return @code{#t} if @var{obj} is a calling stack. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-evaluation.texi b/doc/ref/scheme-evaluation.texi new file mode 100644 index 000000000..210f26040 --- /dev/null +++ b/doc/ref/scheme-evaluation.texi @@ -0,0 +1,419 @@ +@page +@node Read/Load/Eval +@chapter Reading and Evaluating Scheme Code + +This chapter describes Guile functions that are concerned with reading, +loading and evaluating 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. +* 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. +@end menu + + +@node Scheme Syntax +@section Scheme Syntax: Standard and Guile Extensions + +@menu +* Expression Syntax:: +* Comments:: +* Block Comments:: +* Case Sensitivity:: +* Keyword Syntax:: +* Reader Extensions:: +@end menu + + +@node Expression Syntax +@subsection Expression Syntax + + +@node Comments +@subsection Comments + +@c FIXME::martin: Review me! + +Comments in Scheme source files are written by starting them with a +semicolon character (@code{;}). The comment then reaches up to the end +of the line. Comments can begin at any column, and the may be inserted +on the same line as Scheme code. + +@lisp +; Comment +;; Comment too +(define x 1) ; Comment after expression +(let ((y 1)) + ;; Display something. + (display y) +;;; Comment at left margin. + (display (+ y 1))) +@end lisp + +It is common to use a single semicolon for comments following +expressions on a line, to use two semicolons for comments which are +indented like code, and three semicolons for comments which start at +column 0, even if they are inside an indented code block. This +convention is used when indenting code in Emacs' Scheme mode. + + +@node Block Comments +@subsection Block Comments + +@c FIXME::martin: Review me! + +@cindex multiline comments +In addition to the standard line comments defined by R5RS, Guile has +another comment type for multiline comments, called @dfn{block +comments}. This type of comment begins with the character sequence +@code{#!} and ends with the characters @code{!#}, which must appear on a +line of their own. These comments are compatible with the block +comments in the Scheme Shell @file{scsh} (@pxref{The Scheme shell +(scsh)}). The characters @code{#!} were chosen because they are the +magic characters used in shell scripts for indicating that the name of +the program for executing the script follows on the same line. + +Thus a Guile script often starts like this. + +@lisp +#! /usr/local/bin/guile -s +!# +@end lisp + +More details on Guile scripting can be found in the scripting section +(@pxref{Guile Scripting}). + + +@node Case Sensitivity +@subsection Case Sensitivity + +@c FIXME::martin: Review me! + +Scheme as defined in R5RS is not case sensitive when reading symbols. +Guile, on the contrary is case sensitive by default, so the identifiers + +@lisp +guile-whuzzy +Guile-Whuzzy +@end lisp + +are the same in R5RS Scheme, but are different in Guile. + +It is possible to turn off case sensitivity in Guile by setting the +reader option @code{case-insensitive}. More on reader options can be +found at (@pxref{Reader options}). + +@lisp +(read-enable 'case-insensitive) +@end lisp + +Note that this is seldom a problem, because Scheme programmers tend not +to use uppercase letters in their identifiers anyway. + + +@node Keyword Syntax +@subsection Keyword Syntax + + +@node Reader Extensions +@subsection Reader Extensions + +@deffn primitive read-hash-extend chr proc +Install the procedure @var{proc} for reading expressions +starting with the character sequence @code{#} and @var{chr}. +@var{proc} will be called with two arguments: the character +@var{chr} and the port to read further data from. The object +returned will be the return value of @code{read}. +@end deffn + + +@node Scheme Read +@section Reading Scheme Code + +@rnindex read +@deffn primitive read [port] +Read an s-expression from the input port @var{port}, or from +the current input port if @var{port} is not specified. +Any whitespace before the next token is discarded. +@end deffn + +The behaviour of Guile's Scheme reader can be modified by manipulating +its read options. For more information about options, @xref{General +option interface}. If you want to know which reader options are +available, @xref{Reader options}. + +@c FIXME::martin: This is taken from libguile/options.c. Is there +@c actually a difference between 'help and 'full? + +@deffn procedure read-options [setting] +Display the current settings of the read options. If @var{setting} is +omitted, only a short form of the current read options is printed. +Otherwise, @var{setting} should be one of the following symbols: +@table @code +@item help +Display the complete option settings. +@item full +Like @code{help}, but also print programmer options. +@end table +@end deffn + +@deffn procedure read-enable option-name +@deffnx procedure read-disable option-name +@deffnx procedure read-set! option-name value +Modify the read options. @code{read-enable} should be used with boolean +options and switches them on, @code{read-disable} switches them off. +@code{read-set!} can be used to set an option to a specific value. +@end deffn + +@deffn primitive read-options-interface [setting] +Option interface for the read options. Instead of using +this procedure directly, use the procedures @code{read-enable}, +@code{read-disable}, @code{read-set!} and @code{read-options}. +@end deffn + + +@node Fly Evaluation +@section Procedures for On the Fly Evaluation + +@rnindex eval +@c ARGFIXME environment/environment specifier +@deffn primitive eval exp environment +Evaluate @var{exp}, a list representing a Scheme expression, in the +environment given by @var{environment specifier}. +@end deffn + +@rnindex interaction-environment +@deffn primitive interaction-environment +Return a specifier for the environment that contains +implementation--defined bindings, typically a superset of those +listed in the report. The intent is that this procedure will +return the environment in which the implementation would +evaluate expressions dynamically typed by the user. +@end deffn + +@deffn primitive eval-string string +Evaluate @var{string} as the text representation of a Scheme +form or forms, and return whatever value they produce. +Evaluation takes place in the environment returned by the +procedure @code{interaction-environment}. +@end deffn + +@deffn primitive apply:nconc2last lst +Given a list (@var{arg1} @dots{} @var{args}), this function +conses the @var{arg1} @dots{} arguments onto the front of +@var{args}, and returns the resulting list. Note that +@var{args} is a list; thus, the argument to this function is +a list whose last element is a list. +Note: Rather than do new consing, @code{apply:nconc2last} +destroys its argument, so use with care. +@end deffn + +@rnindex apply +@deffn primitive apply proc arg1 @dots{} args +@var{proc} must be a procedure and @var{args} must be a list. Call +@var{proc} with the elements of the list @code{(append (list @var{arg1} +@dots{}) @var{args})} as the actual arguments. +@end deffn + +@deffn primitive primitive-eval exp +Evaluate @var{exp} in the top-level environment specified by +the current module. +@end deffn + +@deffn primitive eval2 obj env_thunk +Evaluate @var{exp}, a Scheme expression, in the environment +designated by @var{lookup}, a symbol-lookup function. +Do not use this version of eval, it does not play well +with the module system. Use @code{eval} or +@code{primitive-eval} instead. +@end deffn + +@deffn primitive read-and-eval! [port] +Read a form from @var{port} (standard input by default), and evaluate it +(memoizing it in the process) in the top-level environment. If no data +is left to be read from @var{port}, an @code{end-of-file} error is +signalled. +@end deffn + + +@node Loading +@section Loading Scheme Code from File + +@rnindex load +@deffn procedure load filename +Load @var{filename} and evaluate its contents in the top-level +environment. The load paths are not searched. If the variable +@code{%load-hook} is defined, it should be bound to a procedure that +will be called before any code is loaded. See documentation for +@code{%load-hook} later in this section. +@end deffn + +@deffn procedure load-from-path filename +Similar to @code{load}, but searches for @var{filename} in the load +paths. +@end deffn + +@deffn primitive primitive-load filename +Load the file named @var{filename} and evaluate its contents in +the top-level environment. The load paths are not searched; +@var{filename} must either be a full pathname or be a pathname +relative to the current directory. If the variable +@code{%load-hook} is defined, it should be bound to a procedure +that will be called before any code is loaded. See the +documentation for @code{%load-hook} later in this section. +@end deffn + +@deffn primitive primitive-load-path filename +Search @var{%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. +@end deffn + +@deffn primitive %search-load-path filename +Search @var{%load-path} for the file named @var{filename}, +which must be readable by the current user. If @var{filename} +is found in the list of paths to search or is an absolute +pathname, return its full pathname. Otherwise, return +@code{#f}. Filenames may have any of the optional extensions +in the @code{%load-extensions} list; @code{%search-load-path} +will try each extension automatically. +@end deffn + +@defvar %load-hook +A procedure to be run whenever @code{primitive-load} is called. If this +procedure is defined, it will be called with the filename argument that +was passed to @code{primitive-load}. + +@example +(define %load-hook (lambda (file) + (display "Loading ") + (display file) + (write-line "...."))) @result{} undefined +(load-from-path "foo.scm") +@print{} Loading /usr/local/share/guile/site/foo.scm.... +@end example + +@end defvar + +@deffn primitive current-load-port +Return the current-load-port. +The load port is used internally by @code{primitive-load}. +@end deffn + +@defvar %load-extensions +A list of default file extensions for files containing Scheme code. +@code{%search-load-path} tries each of these extensions when looking for +a file to load. By default, @code{%load-extensions} is bound to the +list @code{("" ".scm")}. +@end defvar + + +@node Delayed Evaluation +@section Delayed Evaluation + +[delay] + +@deffn primitive promise? obj +Return true if @var{obj} is a promise, i.e. a delayed computation +(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}). +@end deffn + +@rnindex force +@deffn primitive force x +If the promise @var{x} has not been computed yet, compute and +return @var{x}, otherwise just return the previously computed +value. +@end deffn + + +@node Local Evaluation +@section Local Evaluation + +[the-environment] + +@deffn primitive local-eval exp [env] +Evaluate @var{exp} in its environment. If @var{env} is supplied, +it is the environment in which to evaluate @var{exp}. Otherwise, +@var{exp} must be a memoized code object (in which case, its environment +is implicit). +@end deffn + + +@node Evaluator Behaviour +@section Evaluator Behaviour + +@c FIXME::martin: Maybe this node name is bad, but the old name clashed with +@c `Evaluator options' under `Options and Config'. + +The behaviour of Guile's evaluator can be modified by manipulating the +evaluator options. For more information about options, @xref{General +option interface}. If you want to know which evaluator options are +available, @xref{Evaluator options}. + +@c FIXME::martin: This is taken from libguile/options.c. Is there +@c actually a difference between 'help and 'full? + +@deffn procedure eval-options [setting] +Display the current settings of the evaluator options. If @var{setting} +is omitted, only a short form of the current evaluator options is +printed. Otherwise, @var{setting} should be one of the following +symbols: +@table @code +@item help +Display the complete option settings. +@item full +Like @code{help}, but also print programmer options. +@end table +@end deffn + +@deffn procedure eval-enable option-name +@deffnx procedure eval-disable option-name +@deffnx procedure eval-set! option-name value +Modify the evaluator options. @code{eval-enable} should be used with boolean +options and switches them on, @code{eval-disable} switches them off. +@code{eval-set!} can be used to set an option to a specific value. +@end deffn + +@deffn primitive eval-options-interface [setting] +Option interface for the evaluation options. Instead of using +this procedure directly, use the procedures @code{eval-enable}, +@code{eval-disable}, @code{eval-set!} and @code{eval-options}. +@end deffn + +@c FIXME::martin: Why aren't these procedure named like the other options +@c procedures? + +@deffn procedure traps [setting] +Display the current settings of the evaluator traps options. If +@var{setting} is omitted, only a short form of the current evaluator +traps options is printed. Otherwise, @var{setting} should be one of the +following symbols: +@table @code +@item help +Display the complete option settings. +@item full +Like @code{help}, but also print programmer options. +@end table +@end deffn + +@deffn procedure trap-enable option-name +@deffnx procedure trap-disable option-name +@deffnx procedure trap-set! option-name value +Modify the evaluator options. @code{trap-enable} should be used with boolean +options and switches them on, @code{trap-disable} switches them off. +@code{trap-set!} can be used to set an option to a specific value. +@end deffn + +@deffn primitive evaluator-traps-interface [setting] +Option interface for the evaluator trap options. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-ideas.texi b/doc/ref/scheme-ideas.texi new file mode 100644 index 000000000..80f5fbab4 --- /dev/null +++ b/doc/ref/scheme-ideas.texi @@ -0,0 +1,1458 @@ +@page +@node Basic Ideas +@chapter Basic Ideas in Scheme + +In this chapter, we introduce the basic concepts that underpin the +elegance and power of the Scheme language. + +Readers who already possess a background knowledge of Scheme may happily +skip this chapter. For the reader who is new to the language, however, +the following discussions on data, procedures, expressions and closure +are designed to provide a minimum level of Scheme understanding that is +more or less assumed by the reference chapters that follow. + +The style of this introductory material aims about halfway between the +terse precision of R5RS and the discursive randomness of a Scheme +tutorial. + +@menu +* About Data:: Latent typing, types, values and variables. +* About Procedures:: The representation and use of procedures. +* About Expressions:: All kinds of expressions and their meaning. +* About Closure:: Closure, scoping and environments. +@end menu + + +@node About Data +@section Data Types, Values and Variables + +This section discusses the representation of data types and values, what +it means for Scheme to be a @dfn{latently typed} language, and the role +of variables. We conclude by introducing the Scheme syntaxes for +defining a new variable, and for changing the value of an existing +variable. + +@menu +* Latent Typing:: Scheme as a "latently typed" language. +* Values and Variables:: About data types, values and variables. +* Definition:: Defining variables and setting their values. +@end menu + + +@node Latent Typing +@subsection Latent Typing + +The term @dfn{latent typing} is used to descibe a computer language, +such as Scheme, for which you cannot, @emph{in general}, simply look at +a program's source code and determine what type of data will be +associated with a particular variable, or with the result of a +particular expression. + +Sometimes, of course, you @emph{can} tell from the code what the type of +an expression will be. If you have a line in your program that sets the +variable @code{x} to the numeric value 1, you can be certain that, +immediately after that line has executed (and in the absence of multiple +threads), @code{x} has the numeric value 1. Or if you write a procedure +that is designed to concatenate two strings, it is likely that the rest +of your application will always invoke this procedure with two string +parameters, and quite probable that the procedure would go wrong in some +way if it was ever invoked with parameters that were not both strings. + +Nevertheless, the point is that there is nothing in Scheme which +requires the procedure parameters always to be strings, or @code{x} +always to hold a numeric value, and there is no way of declaring in your +program that such constraints should always be obeyed. In the same +vein, there is no way to declare the expected type of a procedure's +return value. + +Instead, the types of variables and expressions are only known -- in +general -- at run time. If you @emph{need} to check at some point that +a value has the expected type, Scheme provides run time procedures that +you can invoke to do so. But equally, it can be perfectly valid for two +separate invocations of the same procedure to specify arguments with +different types, and to return values with different types. + +The next subsection explains what this means in practice, for the ways +that Scheme programs use data types, values and variables. + + +@node Values and Variables +@subsection Values and Variables + +Scheme provides many data types that you can use to represent your data. +Primitive types include characters, strings, numbers and procedures. +Compound types, which allow a group of primitive and compound values to +be stored together, include lists, pairs, vectors and multi-dimensional +arrays. In addition, Guile allows applications to define their own data +types, with the same status as the built-in standard Scheme types. + +As a Scheme program runs, values of all types pop in and out of +existence. Sometimes values are stored in variables, but more commonly +they pass seamlessly from being the result of one computation to being +one of the parameters for the next. + +Consider an example. A string value is created because the interpreter +reads in a literal string from your program's source code. Then a +numeric value is created as the result of calculating the length of the +string. A second numeric value is created by doubling the calculated +length. Finally the program creates a list with two elements -- the +doubled length and the original string itself -- and stores this list in +a program variable. + +All of the values involved here -- in fact, all values in Scheme -- +carry their type with them. In other words, every value ``knows,'' at +runtime, what kind of value it is. A number, a string, a list, +whatever. + +A variable, on the other hand, has no fixed type. A variable -- +@code{x}, say -- is simply the name of a location -- a box -- in which +you can store any kind of Scheme value. So the same variable in a +program may hold a number at one moment, a list of procedures the next, +and later a pair of strings. The ``type'' of a variable -- insofar as +the idea is meaningful at all -- is simply the type of whatever value +the variable happens to be storing at a particular moment. + + +@node Definition +@subsection Defining and Setting Variables + +To define a new variable, you use Scheme's @code{define} syntax like +this: + +@lisp +(define @var{variable-name} @var{value}) +@end lisp + +This makes a new variable called @var{variable-name} and stores +@var{value} in it as the variable's initial value. For example: + +@lisp +;; Make a variable `x' with initial numeric value 1. +(define x 1) + +;; Make a variable `organization' with an initial string value. +(define organization "Free Software Foundation") +@end lisp + +(In Scheme, a semicolon marks the beginning of a comment that continues +until the end of the line. So the lines beginning @code{;;} are +comments.) + +Changing the value of an already existing variable is very similar, +except that @code{define} is replaced by the Scheme syntax @code{set!}, +like this: + +@lisp +(set! @var{variable-name} @var{new-value}) +@end lisp + +Remember that variables do not have fixed types, so @var{new-value} may +have a completely different type from whatever was previously stored in +the location named by @var{variable-name}. Both of the following +examples are therefore correct. + +@lisp +;; Change the value of `x' to 5. +(set! x 5) + +;; Change the value of `organization' to the FSF's street number. +(set! organization 545) +@end lisp + +In these examples, @var{value} and @var{new-value} are literal numeric +or string values. In general, however, @var{value} and @var{new-value} +can be any Scheme expression. Even though we have not yet covered the +forms that Scheme expressions can take (@pxref{About Expressions}), you +can probably guess what the following @code{set!} example does@dots{} + +@lisp +(set! x (+ x 1)) +@end lisp + +(Note: this is not a complete description of @code{define} and +@code{set!}, because we need to introduce some other aspects of Scheme +before the missing pieces can be filled in. If, however, you are +already familiar with the structure of Scheme, you may like to read +about those missing pieces immediately by jumping ahead to the following +references. + +@itemize @bullet +@item +@xref{Internal Definitions}, to read about using @code{define} other +than at top level in a Scheme program, including a discussion of when it +works to use @code{define} rather than @code{set!} to change the value +of an existing variable. + +@item +@ref{Lambda Alternatives}, to read about an alternative form of the +@code{define} syntax that can be used when defining new procedures. + +@item +REFFIXME, to read about an alternative form of the @code{set!} syntax +that helps with changing a single value in the depths of a compound data +structure.) +@end itemize + + +@node About Procedures +@section The Representation and Use of Procedures + +This section introduces the basics of using and creating Scheme +procedures. It discusses the representation of procedures as just +another kind of Scheme value, and shows how procedure invocation +expressions are constructed. We then explain how @code{lambda} is used +to create new procedures, and conclude by presenting the various +shorthand forms of @code{define} that can be used instead of writing an +explicit @code{lambda} expression. + +@menu +* Procedures as Values:: Procedures are values like everything else. +* Simple Invocation:: How to write a simple procedure invocation. +* Creating a Procedure:: How to create your own procedures. +* Lambda Alternatives:: Other ways of writing procedure definitions. +@end menu + + +@node Procedures as Values +@subsection Procedures as Values + +One of the great simplifications of Scheme is that a procedure is just +another type of value, and that procedure values can be passed around +and stored in variables in exactly the same way as, for example, strings +and lists. When we talk about a built-in standard Scheme procedure such +as @code{open-input-file}, what we actually mean is that there is a +pre-defined top level variable called @code{open-input-file}, whose +value is a procedure that implements what R5RS says that +@code{open-input-file} should do. + +Note that this is quite different from many dialects of Lisp --- +including Emacs Lisp --- in which a program can use the same name with +two quite separate meanings: one meaning identifies a Lisp function, +while the other meaning identifies a Lisp variable, whose value need +have nothing to do with the function that is associated with the first +meaning. In these dialects, functions and variables are said to live in +different @dfn{namespaces}. + +In Scheme, on the other hand, all names belong to a single unified +namespace, and the variables that these names identify can hold any kind +of Scheme value, including procedure values. + +One consequence of the ``procedures as values'' idea is that, if you +don't happen to like the standard name for a Scheme procedure, you can +change it. + +For example, @code{call-with-current-continuation} is a very important +standard Scheme procedure, but it also has a very long name! So, many +programmers use the following definition to assign the same procedure +value to the more convenient name @code{call/cc}. + +@lisp +(define call/cc call-with-current-continuation) +@end lisp + +Let's understand exactly how this works. The definition creates a new +variable @code{call/cc}, and then sets its value to the value of the +variable @code{call-with-current-continuation}; the latter value is a +procedure that implements the behaviour that R5RS specifies under the +name ``call-with-current-continuation''. So @code{call/cc} ends up +holding this value as well. + +Now that @code{call/cc} holds the required procedure value, you could +choose to use @code{call-with-current-continuation} for a completely +different purpose, or just change its value so that you will get an +error if you accidentally use @code{call-with-current-continuation} as a +procedure in your program rather than @code{call/cc}. For example: + +@lisp +(set! call-with-current-continuation "Not a procedure any more!") +@end lisp + +Or you could just leave @code{call-with-current-continuation} as it was. +It's perfectly fine for more than one variable to hold the same +procedure value. + + +@node Simple Invocation +@subsection Simple Procedure Invocation + +A procedure invocation in Scheme is written like this: + +@lisp +(@var{procedure} [@var{arg1} [@var{arg2} @dots{}]]) +@end lisp + +In this expression, @var{procedure} can be any Scheme expression whose +value is a procedure. Most commonly, however, @var{procedure} is simply +the name of a variable whose value is a procedure. + +For example, @code{string-append} is a standard Scheme procedure whose +behaviour is to concatenate together all the arguments, which are +expected to be strings, that it is given. So the expression + +@lisp +(string-append "/home" "/" "andrew") +@end lisp + +@noindent +is a procedure invocation whose result is the string value +@code{"/home/andrew"}. + +Similarly, @code{string-length} is a standard Scheme procedure that +returns the length of a single string argument, so + +@lisp +(string-length "abc") +@end lisp + +@noindent +is a procedure invocation whose result is the numeric value 3. + +Each of the parameters in a procedure invocation can itself be any +Scheme expression. Since a procedure invocation is itself a type of +expression, we can put these two examples together to get + +@lisp +(string-length (string-append "/home" "/" "andrew")) +@end lisp + +@noindent +--- a procedure invocation whose result is the numeric value 12. + +(You may be wondering what happens if the two examples are combined the +other way round. If we do this, we can make a procedure invocation +expression that is @emph{syntactically} correct: + +@lisp +(string-append "/home" (string-length "abc")) +@end lisp + +@noindent +but when this expression is executed, it will cause an error, because +the result of @code{(string-length "abc")} is a numeric value, and +@code{string-append} is not designed to accept a numeric value as one of +its arguments.) + + +@node Creating a Procedure +@subsection Creating and Using a New Procedure + +Scheme has lots of standard procedures, and Guile provides all of these +via predefined top level variables. All of these standard procedures +are documented in the later chapters of this reference manual. + +Before very long, though, you will want to create new procedures that +encapsulate aspects of your own applications' functionality. To do +this, you can use the famous @code{lambda} syntax. + +For example, the value of the following Scheme expression + +@lisp +(lambda (name address) @var{expression} @dots{}) +@end lisp + +@noindent +is a newly created procedure that takes two arguments: +@code{name} and @code{address}. The behaviour of the +new procedure is determined by the sequence of @var{expression}s in the +@dfn{body} of the procedure definition. (Typically, these +@var{expression}s would use the arguments in some way, or else there +wouldn't be any point in giving them to the procedure.) When invoked, +the new procedure returns a value that is the value of the last +@var{expression} in the procedure body. + +To make things more concrete, let's suppose that the two arguments are +both strings, and that the purpose of this procedure is to form a +combined string that includes these arguments. Then the full lambda +expression might look like this: + +@lisp +(lambda (name address) + (string-append "Name=" name ":Address=" address)) +@end lisp + +We noted in the previous subsection that the @var{procedure} part of a +procedure invocation expression can be any Scheme expression whose value +is a procedure. But that's exactly what a lambda expression is! So we +can use a lambda expression directly in a procedure invocation, like +this: + +@lisp +((lambda (name address) + (string-append "Name=" name ":Address=" address)) + "FSF" + "Cambridge") +@end lisp + +@noindent +This is a valid procedure invocation expression, whose result is the +string @code{"Name=FSF:Address=Cambridge"}. + +It it more common, though, to store the procedure value in a variable --- + +@lisp +(define make-combined-string + (lambda (name address) + (string-append "Name=" name ":Address=" address))) +@end lisp + +@noindent +--- and then to use the variable name in the procedure invocation: + +@lisp +(make-combined-string "FSF" "Cambridge") +@end lisp + +@noindent +Which has exactly the same result. + +It's important to note that procedures created using @code{lambda} have +exactly the same status as the standard built in Scheme procedures, and +can be invoked, passed around, and stored in variables in exactly the +same ways. + + +@node Lambda Alternatives +@subsection Lambda Alternatives + +Since it is so common in Scheme programs to want to create a procedure +and then store it in a variable, there is an alternative form of the +@code{define} syntax that allows you to do just that. + +A @code{define} expression of the form + +@lisp +(define (@var{name} [@var{arg1} [@var{arg2} @dots{}]]) + @var{expression} @dots{}) +@end lisp + +@noindent +is exactly equivalent to the longer form + +@lisp +(define @var{name} + (lambda ([@var{arg1} [@var{arg2} @dots{}]]) + @var{expression} @dots{})) +@end lisp + +So, for example, the definition of @code{make-combined-string} in the +previous subsection could equally be written: + +@lisp +(define (make-combined-string name address) + (string-append "Name=" name ":Address=" address)) +@end lisp + +This kind of procedure definition creates a procedure that requires +exactly the expected number of arguments. There are two further forms +of the @code{lambda} expression, which create a procedure that can +accept a variable number of arguments: + +@lisp +(lambda (@var{arg1} @dots{} . @var{args}) @var{expression} @dots{}) + +(lambda @var{args} @var{expression} @dots{}) +@end lisp + +@noindent +The corresponding forms of the alternative @code{define} syntax are: + +@lisp +(define (@var{name} @var{arg1} @dots{} . @var{args}) @var{expression} @dots{}) + +(define (@var{name} . @var{args}) @var{expression} @dots{}) +@end lisp + +@noindent +For details on how these forms work, see @xref{Lambda}. + +(It could be argued that the alternative @code{define} forms are rather +confusing, especially for newcomers to the Scheme language, as they hide +both the role of @code{lambda} and the fact that procedures are values +that are stored in variables in the some way as any other kind of value. +On the other hand, they are very convenient, and they are also a good +example of another of Scheme's powerful features: the ability to specify +arbitrary syntactic transformations at run time, which can be applied to +subsequently read input.) + + +@node About Expressions +@section Expressions and Evaluation + +So far, we have met expressions that @emph{do} things, such as the +@code{define} expressions that create and initialize new variables, and +we have also talked about expressions that have @emph{values}, for +example the value of the procedure invocation expression: + +@lisp +(string-append "/home" "/" "andrew") +@end lisp + +@noindent +but we haven't yet been precise about what causes an expression like +this procedure invocation to be reduced to its ``value'', or how the +processing of such expressions relates to the execution of a Scheme +program as a whole. + +This section clarifies what we mean by an expression's value, by +introducing the idea of @dfn{evaluation}. It discusses the side effects +that evaluation can have, explains how each of the various types of +Scheme expression is evaluated, and describes the behaviour and use of +the Guile REPL as a mechanism for exploring evaluation. The section +concludes with a very brief summary of Scheme's common syntactic +expressions. + +@menu +* Evaluating:: How a Scheme program is executed. +* The REPL:: Interacting with the Guile interpreter. +* Syntax Summary:: Common syntactic expressions -- in brief. +@end menu + + +@node Evaluating +@subsection Evaluating Expressions and Executing Programs + +In Scheme, the process of executing an expression is known as +@dfn{evaluation}. Evaluation has two kinds of result: + +@itemize @bullet +@item +the @dfn{value} of the evaluated expression + +@item +the @dfn{side effects} of the evaluation, which consist of any effects of +evaluating the expression that are not represented by the value. +@end itemize + +Of the expressions that we have met so far, @code{define} and +@code{set!} expressions have side effects --- the creation or +modification of a variable --- but no value; @code{lambda} expressions +have values --- the newly constructed procedures --- but no side +effects; and procedure invocation expressions, in general, have either +values, or side effects, or both. + +It is tempting to try to define more intuitively what we mean by +``value'' and ``side effects'', and what the difference between them is. +In general, though, this is extremely difficult. It is also +unnecessary; instead, we can quite happily define the behaviour of a +Scheme program by specifying how Scheme executes a program as a whole, +and then by describing the value and side effects of evaluation for each +type of expression individually. + +@noindent +So, some@footnote{These definitions are approximate. For the whole and +detailed truth, see @xref{Formal syntax and semantics,R5RS +syntax,,r5rs}.} definitions@dots{} + +@itemize @bullet + +@item +A Scheme program consists of a sequence of expressions. + +@item +A Scheme interpreter executes the program by evaluating these +expressions in order, one by one. + +@item +An expression can be + +@itemize @bullet +@item +a piece of literal data, such as a number @code{2.3} or a string +@code{"Hello world!"} +@item +a variable name +@item +a procedure invocation expression +@item +one of Scheme's special syntactic expressions. +@end itemize +@end itemize + +@noindent +The following subsections describe how each of these types of expression +is evaluated. + +@menu +* Eval Literal:: Evaluating literal data. +* Eval Variable:: Evaluating variable references. +* Eval Procedure:: Evaluating procedure invocation expressions. +* Eval Special:: Evaluating special syntactic expressions. +@end menu + +@node Eval Literal +@subsubsection Evaluating Literal Data + +When a literal data expression is evaluated, the value of the expression +is simply the value that the expression describes. The evaluation of a +literal data expression has no side effects. + +@noindent +So, for example, + +@itemize @bullet +@item +the value of the expression @code{"abc"} is the string value +@code{"abc"} + +@item +the value of the expression @code{3+4i} is the complex number 3 + 4i + +@item +the value of the expression @code{#(1 2 3)} is a three-element vector +containing the numeric values 1, 2 and 3. +@end itemize + +For any data type which can be expressed literally like this, the syntax +of the literal data expression for that data type --- in other words, +what you need to write in your code to indicate a literal value of that +type --- is known as the data type's @dfn{read syntax}. This manual +specifies the read syntax for each such data type in the section that +describes that data type. + +Some data types do not have a read syntax. Procedures, for example, +cannot be expressed as literal data; they must be created using a +@code{lambda} expression (@pxref{Creating a Procedure}) or implicitly +using the shorthand form of @code{define} (@pxref{Lambda Alternatives}). + + +@node Eval Variable +@subsubsection Evaluating a Variable Reference + +When an expression that consists simply of a variable name is evaluated, +the value of the expression is the value of the named variable. The +evaluation of a variable reference expression has no side effects. + +So, after + +@lisp +(define key "Paul Evans") +@end lisp + +@noindent +the value of the expression @code{key} is the string value @code{"Paul +Evans"}. If @var{key} is then modified by + +@lisp +(set! key 3.74) +@end lisp + +@noindent +the value of the expression @code{key} is the numeric value 3.74. + +If there is no variable with the specified name, evaluation of the +variable reference expression signals an error. + + +@node Eval Procedure +@subsubsection Evaluating a Procedure Invocation Expression + +This is where evaluation starts getting interesting! As already noted, +a procedure invocation expression has the form + +@lisp +(@var{procedure} [@var{arg1} [@var{arg2} @dots{}]]) +@end lisp + +@noindent +where @var{procedure} must be an expression whose value, when evaluated, +is a procedure. + +The evaluation of a procedure invocation expression like this proceeds +by + +@itemize @bullet +@item +evaluating individually the expressions @var{procedure}, @var{arg1}, +@var{arg2}, and so on + +@item +calling the procedure that is the value of the @var{procedure} +expression with the list of values obtained from the evaluations of +@var{arg1}, @var{arg2} etc. as its parameters. +@end itemize + +For a procedure defined in Scheme, ``calling the procedure with the list +of values as its parameters'' means binding the values to the +procedure's formal parameters and then evaluating the sequence of +expressions that make up the body of the procedure definition. The +value of the procedure invocation expression is the value of the last +evaluated expression in the procedure body. The side effects of calling +the procedure are the combination of the side effects of the sequence of +evaluations of expressions in the procedure body. + +For a built-in procedure, the value and side-effects of calling the +procedure are best described by that procedure's documentation. + +Note that the complete side effects of evaluating a procedure invocation +expression consist not only of the side effects of the procedure call, +but also of any side effects of the preceding evaluation of the +expressions @var{procedure}, @var{arg1}, @var{arg2}, and so on. + +To illustrate this, let's look again at the procedure invocation +expression: + +@lisp +(string-length (string-append "/home" "/" "andrew")) +@end lisp + +In the outermost expression, @var{procedure} is @code{string-length} and +@var{arg1} is @code{(string-append "/home" "/" "andrew")}. + +@itemize @bullet +@item +Evaluation of @code{string-length}, which is a variable, gives a +procedure value that implements the expected behaviour for +``string-length''. + +@item +Evaluation of @code{(string-append "/home" "/" "andrew")}, which is +another procedure invocation expression, means evaluating each of + +@itemize @bullet +@item +@code{string-append}, which gives a procedure value that implements the +expected behaviour for ``string-append'' + +@item +@code{"/home"}, which gives the string value @code{"/home"} + +@item +@code{"/"}, which gives the string value @code{"/"} + +@item +@code{"andrew"}, which gives the string value @code{"andrew"} +@end itemize + +and then invoking the procedure value with this list of string values as +its arguments. The resulting value is a single string value that is the +concatenation of all the arguments, namely @code{"/home/andrew"}. +@end itemize + +In the evaluation of the outermost expression, the interpreter can now +invoke the procedure value obtained from @var{procedure} with the value +obtained from @var{arg1} as its arguments. The resulting value is a +numeric value that is the length of the argument string, which is 12. + + +@node Eval Special +@subsubsection Evaluating Special Syntactic Expressions + +When a procedure invocation expression is evaluated, the procedure and +@emph{all} the argument expressions must be evaluated before the +procedure can be invoked. Special syntactic expressions are special +because they are able to manipulate their arguments in an unevaluated +form, and can choose whether to evaluate any or all of the argument +expressions. + +Why is this needed? Consider a program fragment that asks the user +whether or not to delete a file, and then deletes the file if the user +answers yes. + +@lisp +(if (string=? (read-answer "Should I delete this file?") + "yes") + (delete-file file)) +@end lisp + +If the outermost @code{(if @dots{})} expression here was a procedure +invocation expression, the expression @code{(delete-file file)}, whose +effect is to actually delete a file, would already have been executed +before the @code{if} procedure even got invoked! Clearly this is no use +--- the whole point of an @code{if} expression is that the +@dfn{consequent} expression is only evaluated if the condition of the +@code{if} expression is ``true''. + +Therefore @code{if} must be special syntax, not a procedure. Other +special syntaxes that we have already met are @code{define}, @code{set!} +and @code{lambda}. @code{define} and @code{set!} are syntax because +they need to know the variable @emph{name} that is given as the first +argument in a @code{define} or @code{set!} expression, not that +variable's value. @code{lambda} is syntax because it does not +immediately evaluate the expressions that define the procedure body; +instead it creates a procedure object that incorporates these +expressions so that they can be evaluated in the future, when that +procedure is invoked. + +The rules for evaluating each special syntactic expression are specified +individually for each special syntax. For a summary of standard special +syntax, see @xref{Syntax Summary}. + + +@node The REPL +@subsection Using the Guile REPL + +If you start Guile without specifying a particular program for it to +execute, Guile enters its standard Read Evaluate Print Loop --- or +@dfn{REPL} for short. In this mode, Guile repeatedly reads in the next +Scheme expression that the user types, evaluates it, and prints the +resulting value. + +The REPL is a useful mechanism for exploring the evaluation behaviour +described in the previous subsection. If you type @code{string-append}, +for example, the REPL replies @code{#<primitive-procedure +string-append>}, illustrating the relationship between the variable +@code{string-append} and the procedure value stored in that variable. + +In this manual, the notation @result{} is used to mean ``evaluates +to''. Wherever you see an example of the form + +@lisp +@var{expression} +@result{} +@var{result} +@end lisp + +@noindent +feel free to try it out yourself by typing @var{expression} into the +REPL and checking that it gives the expected @var{result}. + + +@node Syntax Summary +@subsection Summary of Common Syntax + +This subsection lists the most commonly used Scheme syntactic +expressions, simply so that you will recognize common special syntax +when you see it. For a full description of each of these syntaxes, +follow the appropriate reference. + +@code{if} and @code{cond} (@pxref{if cond case}) provide conditional +evaluation of argument expressions depending on whether one or more +conditions evaluate to ``true'' or ``false''. + +@code{case} (@pxref{if cond case}) provides conditional evaluation of +argument expressions depending on whether a variable has one of a +specified group of values. + +@code{define} (REFFIXME) is used to create a new variable and set its +initial value. + +@code{set!} (REFFIXME) is used to modify an existing variable's value. + +@code{lambda} (@pxref{Lambda}) is used to construct procedure objects. + +@code{let}, @code{let*} and @code{letrec} (@pxref{Local Bindings}) +create an inner lexical environment for the evaluation of a sequence of +expressions, in which a specified set of local variables is bound to the +values of a corresponding set of expressions. For an introduction to +environments, see @xref{About Closure}. + +@code{begin} (@pxref{begin}) executes a sequence of expressions in order +and returns the value of the last expression. Note that this is not the +same as a procedure which returns its last argument, because the +evaluation of a procedure invocation expression does not guarantee to +evaluate the arguments in order. + +@code{and} (@pxref{and or}) executes a sequence of expressions in order +until either there are no expressions left, or one of them evaluates to +``false''. + +@code{or} (@pxref{and or}) executes a sequence of expressions in order +until either there are no expressions left, or one of them evaluates to +``true''. + + +@node About Closure +@section The Concept of Closure + +@cindex closure + +The concept of @dfn{closure} is the idea that a lambda expression +``captures'' the variable bindings that are in lexical scope at the +point where the lambda expression occurs. The procedure created by the +lambda expression can refer to and mutate the captured bindings, and the +values of those bindings persist between procedure calls. + +This section explains and explores the various parts of this idea in +more detail. + +@menu +* About Environments:: Names, locations, values and environments. +* Local Variables:: Local variables and local environments. +* Chaining:: Environment chaining. +* Lexical Scope:: The meaning of lexical scoping. +* Closure:: Explaining the concept of closure. +* Serial Number:: Example 1: a serial number generator. +* Shared Variable:: Example 2: a shared persistent variable. +* Callback Closure:: Example 3: the callback closure problem. +* OO Closure:: Example 4: object orientation. +@end menu + +@node About Environments +@subsection Names, Locations, Values and Environments + +@cindex location +@cindex environment +@cindex vcell +@cindex top level environment +@cindex environment, top level + +We said earlier that a variable name in a Scheme program is associated +with a location in which any kind of Scheme value may be stored. +(Incidentally, the term ``vcell'' is often used in Lisp and Scheme +circles as an alternative to ``location''.) Thus part of what we mean +when we talk about ``creating a variable'' is in fact establishing an +association between a name, or identifier, that is used by the Scheme +program code, and the variable location to which that name refers. +Although the value that is stored in that location may change, the +location to which a given name refers is always the same. + +We can illustrate this by breaking down the operation of the +@code{define} syntax into three parts: @code{define} + +@itemize @bullet +@item +creates a new location + +@item +establishes an association between that location and the name specified +as the first argument of the @code{define} expression + +@item +stores in that location the value obtained by evaluating the second +argument of the @code{define} expression. +@end itemize + +A collection of associations between names and locations is called an +@dfn{environment}. When you create a top level variable in a program +using @code{define}, the name-location association for that variable is +added to the ``top level'' environment. The ``top level'' environment +also includes name-location associations for all the procedures that are +supplied by standard Scheme. + +It is also possible to create environments other than the top level one, +and to create variable bindings, or name-location associations, in those +environments. This ability is a key ingredient in the concept of +closure; the next subsection shows how it is done. + + +@node Local Variables +@subsection Local Variables and Environments + +@cindex local variable +@cindex variable, local +@cindex local environment +@cindex environment, local + +We have seen how to create top level variables using the @code{define} +syntax (@pxref{Definition}). It is often useful to create variables +that are more limited in their scope, typically as part of a procedure +body. In Scheme, this is done using the @code{let} syntax, or one of +its modified forms @code{let*} and @code{letrec}. These syntaxes are +described in full later in the manual (@pxref{Local Bindings}). Here +our purpose is to illustrate their use just enough that we can see how +local variables work. + +For example, the following code uses a local variable @code{s} to +simplify the computation of the area of a triangle given the lengths of +its three sides. + +@lisp +(define a 5.3) +(define b 4.7) +(define c 2.8) + +(define area + (let ((s (/ (+ a b c) 2))) + (sqrt (* s (- s a) (- s b) (- s c))))) +@end lisp + +The effect of the @code{let} expression is to create a new environment +and, within this environment, an association between the name @code{s} +and a new location whose initial value is obtained by evaluating +@code{(/ (+ a b c) 2)}. The expressions in the body of the @code{let}, +namely @code{(sqrt (* s (- s a) (- s b) (- s c)))}, are then evaluated +in the context of the new environment, and the value of the last +expression evaluated becomes the value of the whole @code{let} +expression, and therefore the value of the variable @code{area}. + + +@node Chaining +@subsection Environment Chaining + +@cindex shadowing an imported variable binding +@cindex chaining environments + +In the example of the previous subsection, we glossed over an important +point. The body of the @code{let} expression in that example refers not +only to the local variable @code{s}, but also to the top level variables +@code{a}, @code{b}, @code{c} and @code{sqrt}. (@code{sqrt} is the +standard Scheme procedure for calculating a square root.) If the body +of the @code{let} expression is evaluated in the context of the +@emph{local} @code{let} environment, how does the evaluation get at the +values of these top level variables? + +The answer is that the local environment created by a @code{let} +expression automatically has a reference to its containing environment +--- in this case the top level environment --- and that the Scheme +interpreter automatically looks for a variable binding in the containing +environment if it doesn't find one in the local environment. More +generally, every environment except for the top level one has a +reference to its containing environment, and the interpreter keeps +searching back up the chain of environments --- from most local to top +level --- until it either finds a variable binding for the required +identifier or exhausts the chain. + +This description also determines what happens when there is more than +one variable binding with the same name. Suppose, continuing the +example of the previous subsection, that there was also a pre-existing +top level variable @code{s} created by the expression: + +@lisp +(define s "Some beans, my lord!") +@end lisp + +Then both the top level environment and the local @code{let} environment +would contain bindings for the name @code{s}. When evaluating code +within the @code{let} body, the interpreter looks first in the local +@code{let} environment, and so finds the binding for @code{s} created by +the @code{let} syntax. Even though this environment has a reference to +the top level environment, which also has a binding for @code{s}, the +interpreter doesn't get as far as looking there. When evaluating code +outside the @code{let} body, the interpreter looks up variable names in +the top level environment, so the name @code{s} refers to the top level +variable. + +Within the @code{let} body, the binding for @code{s} in the local +environment is said to @dfn{shadow} the binding for @code{s} in the top +level environment. + + +@node Lexical Scope +@subsection Lexical Scope + +The rules that we have just been describing are the details of how +Scheme implements ``lexical scoping''. This subsection takes a brief +diversion to explain what lexical scope means in general and to present +an example of non-lexical scoping. + +``Lexical scope'' in general is the idea that + +@itemize @bullet +@item +an identifier at a particular place in a program always refers to the +same variable location --- where ``always'' means ``every time that the +containing expression is executed'', and that + +@item +the variable location to which it refers can be determined by static +examination of the source code context in which that identifier appears, +without having to consider the flow of execution through the program as +a whole. +@end itemize + +In practice, lexical scoping is the norm for most programming languages, +and probably corresponds to what you would intuitively consider to be +``normal''. You may even be wondering how the situation could possibly +--- and usefully --- be otherwise. To demonstrate that another kind of +scoping is possible, therefore, and to compare it against lexical +scoping, the following subsection presents an example of non-lexical +scoping and examines in detail how its behavior differs from the +corresponding lexically scoped code. + +@menu +* Scoping Example:: An example of non-lexical scoping. +@end menu + + +@node Scoping Example +@subsubsection An Example of Non-Lexical Scoping + +To demonstrate that non-lexical scoping does exist and can be useful, we +present the following example from Emacs Lisp, which is a ``dynamically +scoped'' language. + +@lisp +(defvar currency-abbreviation "USD") + +(defun currency-string (units hundredths) + (concat currency-abbreviation + (number-to-string units) + "." + (number-to-string hundredths))) + +(defun french-currency-string (units hundredths) + (let ((currency-abbreviation "FRF")) + (currency-string units hundredths))) +@end lisp + +The question to focus on here is: what does the identifier +@code{currency-abbreviation} refer to in the @code{currency-string} +function? The answer, in Emacs Lisp, is that all variable bindings go +onto a single stack, and that @code{currency-abbreviation} refers to the +topmost binding from that stack which has the name +``currency-abbreviation''. The binding that is created by the +@code{defvar} form, to the value @code{"USD"}, is only relevant if none +of the code that calls @code{currency-string} rebinds the name +``currency-abbreviation'' in the meanwhile. + +The second function @code{french-currency-string} works precisely by +taking advantage of this behaviour. It creates a new binding for the +name ``currency-abbreviation'' which overrides the one established by +the @code{defvar} form. + +@lisp +;; Note! This is Emacs Lisp evaluation, not Scheme! +(french-currency-string 33 44) +@result{} +"FRF33.44" +@end lisp + +Now let's look at the corresponding, @emph{lexically scoped} Scheme +code: + +@lisp +(define currency-abbreviation "USD") + +(define (currency-string units hundredths) + (string-append currency-abbreviation + (number->string units) + "." + (number->string hundredths))) + +(define (french-currency-string units hundredths) + (let ((currency-abbreviation "FRF")) + (currency-string units hundredths))) +@end lisp + +According to the rules of lexical scoping, the +@code{currency-abbreviation} in @code{currency-string} refers to the +variable location in the innermost environment at that point in the code +which has a binding for @code{currency-abbreviation}, which is the +variable location in the top level environment created by the preceding +@code{(define currency-abbreviation @dots{})} expression. + +In Scheme, therefore, the @code{french-currency-string} procedure does +not work as intended. The variable binding that it creates for +``currency-abbreviation'' is purely local to the code that forms the +body of the @code{let} expression. Since this code doesn't directly use +the name ``currency-abbreviation'' at all, the binding is pointless. + +@lisp +(french-currency-string 33 44) +@result{} +"USD33.44" +@end lisp + +This begs the question of how the Emacs Lisp behaviour can be +implemented in Scheme. In general, this is a design question whose +answer depends upon the problem that is being addressed. In this case, +the best answer may be that @code{currency-string} should be +redesigned so that it can take an optional third argument. This third +argument, if supplied, is interpreted as a currency abbreviation that +overrides the default. + +It is possible to change @code{french-currency-string} so that it mostly +works without changing @code{currency-string}, but the fix is inelegant, +and susceptible to interrupts that could leave the +@code{currency-abbreviation} variable in the wrong state: + +@lisp +(define (french-currency-string units hundredths) + (set! currency-abbreviation "FRF") + (let ((result (currency-string units hundredths))) + (set! currency-abbreviation "USD") + result)) +@end lisp + +The key point here is that the code does not create any local binding +for the identifier @code{currency-abbreviation}, so all occurences of +this identifier refer to the top level variable. + + +@node Closure +@subsection Closure + +Consider a @code{let} expression that doesn't contain any +@code{lambda}s: + +@lisp +(let ((s (/ (+ a b c) 2))) + (sqrt (* s (- s a) (- s b) (- s c)))) +@end lisp + +@noindent +When the Scheme interpreter evaluates this, it + +@itemize @bullet +@item +creates a new environment with a reference to the environment that was +current when it encountered the @code{let} + +@item +creates a variable binding for @code{s} in the new environment, with +value given by @code{(/ (+ a b c) 2)} + +@item +evaluates the expression in the body of the @code{let} in the context of +the new local environment, and remembers the value @code{V} + +@item +forgets the local environment + +@item +continues evaluating the expression that contained the @code{let}, using +the value @code{V} as the value of the @code{let} expression, in the +context of the containing environment. +@end itemize + +After the @code{let} expression has been evaluated, the local +environment that was created is simply forgotten, and there is no longer +any way to access the binding that was created in this environment. If +the same code is evaluated again, it will follow the same steps again, +creating a second new local environment that has no connection with the +first, and then forgetting this one as well. + +If the @code{let} body contains a @code{lambda} expression, however, the +local environment is @emph{not} forgotten. Instead, it becomes +associated with the procedure that is created by the @code{lambda} +expression, and is reinstated every time that that procedure is called. +In detail, this works as follows. + +@itemize @bullet +@item +When the Scheme interpreter evaluates a @code{lambda} expression, to +create a procedure object, it stores the current environment as part of +the procedure definition. + +@item +Then, whenever that procedure is called, the interpreter reinstates the +environment that is stored in the procedure definition and evaluates the +procedure body within the context of that environment. +@end itemize + +The result is that the procedure body is always evaluated in the context +of the environment that was current when the procedure was created. + +This is what is meant by @dfn{closure}. The next few subsections +present examples that explore the usefulness of this concept. + + +@node Serial Number +@subsection Example 1: A Serial Number Generator + +This example uses closure to create a procedure with a variable binding +that is private to the procedure, like a local variable, but whose value +persists between procedure calls. + +@lisp +(define (make-serial-number-generator) + (let ((current-serial-number 0)) + (lambda () + (set! current-serial-number (+ current-serial-number 1)) + current-serial-number))) + +(define entry-sn-generator (make-serial-number-generator)) + +(entry-sn-generator) +@result{} +1 + +(entry-sn-generator) +@result{} +2 +@end lisp + +When @code{make-serial-number-generator} is called, it creates a local +environment with a binding for @code{current-serial-number} whose +initial value is 0, then, within this environment, creates a procedure. +The local environment is stored within the created procedure object and +so persists for the lifetime of the created procedure. + +Every time the created procedure is invoked, it increments the value of +the @code{current-serial-number} binding in the captured environment and +then returns the current value. + +Note that @code{make-serial-number-generator} can be called again to +create a second serial number generator that is independent of the +first. Every new invocation of @code{make-serial-number-generator} +creates a new local @code{let} environment and returns a new procedure +object with an association to this environment. + + +@node Shared Variable +@subsection Example 2: A Shared Persistent Variable + +This example uses closure to create two procedures, @code{get-balance} +and @code{deposit}, that both refer to the same captured local +environment so that they can both access the @code{balance} variable +binding inside that environment. The value of this variable binding +persists between calls to either procedure. + +Note that the captured @code{balance} variable binding is private to +these two procedures: it is not directly accessible to any other code. +It can only be accessed indirectly via @code{get-balance} or +@code{deposit}, as illustrated by the @code{withdraw} procedure. + +@lisp +(define get-balance #f) +(define deposit #f) + +(let ((balance 0)) + (set! get-balance + (lambda () + balance)) + (set! deposit + (lambda (amount) + (set! balance (+ balance amount)) + balance))) + +(define (withdraw amount) + (deposit (- amount))) + +(get-balance) +@result{} +0 + +(deposit 50) +@result{} +50 + +(withdraw 75) +@result{} +-25 +@end lisp + +A detail here is that the @code{get-balance} and @code{deposit} +variables must be set up by @code{define}ing them at top level and then +@code{set!}ing their values inside the @code{let} body. Using +@code{define} within the @code{let} body would not work: this would +create variable bindings within the local @code{let} environment that +would not be accessible at top level. + + +@node Callback Closure +@subsection Example 3: The Callback Closure Problem + +A frequently used programming model for library code is to allow an +application to register a callback function for the library to call when +some particular event occurs. It is often useful for the application to +make several such registrations using the same callback function, for +example if several similar library events can be handled using the same +application code, but the need then arises to distinguish the callback +function calls that are associated with one callback registration from +those that are associated with different callback registrations. + +In languages without the ability to create functions dynamically, this +problem is usually solved by passing a @code{user_data} parameter on the +registration call, and including the value of this parameter as one of +the parameters on the callback function. Here is an example of +declarations using this solution in C: + +@example +typedef void (event_handler_t) (int event_type, + void *user_data); + +void register_callback (int event_type, + event_handler_t *handler, + void *user_data); +@end example + +In Scheme, closure can be used to achieve the same functionality without +requiring the library code to store a @code{user-data} for each callback +registration. + +@lisp +;; In the library: + +(define (register-callback event-type handler-proc) + @dots{}) + +;; In the application: + +(define (make-handler event-type user-data) + (lambda () + @dots{} + <code referencing event-type and user-data> + @dots{})) + +(register-callback event-type + (make-handler event-type @dots{})) +@end lisp + +As far as the library is concerned, @code{handler-proc} is a procedure +with no arguments, and all the library has to do is call it when the +appropriate event occurs. From the application's point of view, though, +the handler procedure has used closure to capture an environment that +includes all the context that the handler code needs --- +@code{event-type} and @code{user-data} --- to handle the event +correctly. + + +@node OO Closure +@subsection Example 4: Object Orientation + +Closure is the capture of an environment, containing persistent variable +bindings, within the definition of a procedure or a set of related +procedures. This is rather similar to the idea in some object oriented +languages of encapsulating a set of related data variables inside an +``object'', together with a set of ``methods'' that operate on the +encapsulated data. The following example shows how closure can be used +to emulate the ideas of objects, methods and encapsulation in Scheme. + +@lisp +(define (make-account) + (let ((balance 0)) + (define (get-balance) + balance) + (define (deposit amount) + (set! balance (+ balance amount)) + balance) + (define (withdraw amount) + (deposit (- amount))) + + (lambda args + (apply + (case (car args) + ((get-balance) get-balance) + ((deposit) deposit) + ((withdraw) withdraw) + (else (error "Invalid method!"))) + (cdr args))))) +@end lisp + +Each call to @code{make-account} creates and returns a new procedure, +created by the expression in the example code that begins ``(lambda +args''. + +@lisp +(define my-account (make-account)) + +my-account +@result{} +#<procedure args> +@end lisp + +This procedure acts as an account object with methods +@code{get-balance}, @code{deposit} and @code{withdraw}. To apply one of +the methods to the account, you call the procedure with a symbol +indicating the required method as the first parameter, followed by any +other parameters that are required by that method. + +@lisp +(my-account 'get-balance) +@result{} +0 + +(my-account 'withdraw 5) +@result{} +-5 + +(my-account 'deposit 396) +@result{} +391 + +(my-account 'get-balance) +@result{} +391 +@end lisp + +Note how, in this example, both the current balance and the helper +procedures @code{get-balance}, @code{deposit} and @code{withdraw}, used +to implement the guts of the account object's methods, are all stored in +variable bindings within the private local environment captured by the +@code{lambda} expression that creates the account object procedure. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-indices.texi b/doc/ref/scheme-indices.texi new file mode 100644 index 000000000..03a21bb30 --- /dev/null +++ b/doc/ref/scheme-indices.texi @@ -0,0 +1,17 @@ +@page +@node R5RS Index +@chapter R5RS Index + +@printindex rn + + +@page +@node Guile Extensions Index +@chapter Guile Extensions Index + +@printindex ge + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-intro.texi b/doc/ref/scheme-intro.texi new file mode 100644 index 000000000..5bac00086 --- /dev/null +++ b/doc/ref/scheme-intro.texi @@ -0,0 +1,55 @@ +@page +@node Scheme Intro +@chapter Introduction to Guile Scheme + +Guile's core language is Scheme, which is specified and described in the +series of reports known as @dfn{RnRS}. @dfn{RnRS} is shorthand for the +@iftex +@dfn{Revised$^n$ Report on the Algorithmic Language Scheme}. +@end iftex +@ifnottex +@dfn{Revised^n Report on the Algorithmic Language Scheme}. +@end ifnottex +The current latest revision of RnRS is version 5 +(@pxref{Top,R5RS,,r5rs}), and Guile 1.4 is fully compliant with the +Scheme specification in this revision. + +But Guile, like most Scheme implementations, also goes beyond R5RS in +many ways, because R5RS does not give specifications (or even +recommendations) regarding many issues that are important in practical +programming. Some of the areas where Guile extends R5RS are: + +@itemize @bullet +@item +Guile's interactive documentation system + +@item +Guile's support for POSIX-compliant network programming + +@item +GOOPS -- Guile's framework for object oriented programming. +@end itemize + +@menu +* Scheme Layout:: The layout of this part of the manual. +@end menu + + +@node Scheme Layout +@section Layout + +This part of the reference manual documents all of Guile's core +Scheme-level language and features in functionally-related groups. +Where a particular section of the manual includes both R5RS-compliant +parts and Guile-specific extensions, the text indicates which parts of +the documentation describe R5RS behaviour and which parts describe Guile +extensions. + +For a breakdown of Guile's core language and features in terms of what +is R5RS-compliant and what is Guile-specific, see the corresponding +indices: @ref{R5RS Index} and @ref{Guile Extensions Index}. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-io.texi b/doc/ref/scheme-io.texi new file mode 100644 index 000000000..c775c165c --- /dev/null +++ b/doc/ref/scheme-io.texi @@ -0,0 +1,826 @@ +@page +@node Input and Output +@chapter Input and Output + +@menu +* Ports:: The idea of the port abstraction. +* Reading:: Procedures for reading from a port. +* Writing:: Procedures for writing to a port. +* Closing:: Procedures to close a port. +* Random Access:: Moving around a random access port. +* Line/Delimited:: Read and write lines or delimited text. +* 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. +@end menu + + +@node Ports +@section Ports + +[Concept of the port abstraction.] + +Sequential input/output in Scheme is represented by operations on a +@dfn{port}. Characters can be read from an input port and +written to an output port. This chapter explains the operations +that Guile provides for working with ports. + +The formal definition of a port is very generic: an input port is +simply ``an object which can deliver characters on command,'' and +an output port is ``an object which can accept characters.'' +Because this definition is so loose, it is easy to write functions +that simulate ports in software. @dfn{Soft ports} and @dfn{string +ports} are two interesting and powerful examples of this technique. + +@rnindex input-port? +@deffn primitive input-port? x +Return @code{#t} if @var{x} is an input port, otherwise return +@code{#f}. Any object satisfying this predicate also satisfies +@code{port?}. +@end deffn + +@rnindex output-port? +@deffn primitive output-port? x +Return @code{#t} if @var{x} is an output port, otherwise return +@code{#f}. Any object satisfying this predicate also satisfies +@code{port?}. +@end deffn + +@deffn primitive port? x +Return a boolean indicating whether @var{x} is a port. +Equivalent to @code{(or (input-port? @var{x}) (output-port? +@var{x}))}. +@end deffn + + +@node Reading +@section Reading + +[Generic procedures for reading from ports.] + +@rnindex eof-object? +@deffn primitive eof-object? x +Return @code{#t} if @var{x} is an end-of-file object; otherwise +return @code{#f}. +@end deffn + +@rnindex char-ready? +@deffn primitive char-ready? [port] +Return @code{#t} if a character is ready on input @var{port} +and return @code{#f} otherwise. If @code{char-ready?} returns +@code{#t} then the next @code{read-char} operation on +@var{port} is guaranteed not to hang. If @var{port} is a file +port at end of file then @code{char-ready?} returns @code{#t}. +@footnote{@code{char-ready?} exists to make it possible for a +program to accept characters from interactive ports without +getting stuck waiting for input. Any input editors associated +with such ports must make sure that characters whose existence +has been asserted by @code{char-ready?} cannot be rubbed out. +If @code{char-ready?} were to return @code{#f} at end of file, +a port at end of file would be indistinguishable from an +interactive port that has no ready characters.} +@end deffn + +@rnindex read-char? +@deffn primitive read-char [port] +Return the next character available from @var{port}, updating +@var{port} to point to the following character. If no more +characters are available, the end-of-file object is returned. +@end deffn + +@rnindex peek-char? +@deffn primitive peek-char [port] +Return the next character available from @var{port}, +@emph{without} updating @var{port} to point to the following +character. If no more characters are available, the +end-of-file object is returned.@footnote{The value returned by +a call to @code{peek-char} is the same as the value that would +have been returned by a call to @code{read-char} on the same +port. The only difference is that the very next call to +@code{read-char} or @code{peek-char} on that @var{port} will +return the value returned by the preceding call to +@code{peek-char}. In particular, a call to @code{peek-char} on +an interactive port will hang waiting for input whenever a call +to @code{read-char} would have hung.} +@end deffn + +@deffn primitive unread-char cobj port +Place @var{char} in @var{port} so that it will be read by the +next read operation. If called multiple times, the unread characters +will be read again in last-in first-out order. If @var{port} is +not supplied, the current input port is used. +@end deffn + +@deffn primitive unread-string str port +Place the string @var{str} in @var{port} so that its characters will be +read in subsequent read operations. If called multiple times, the +unread characters will be read again in last-in first-out order. If +@var{port} is not supplied, the current-input-port is used. +@end deffn + +@deffn primitive drain-input port +Drain @var{port}'s read buffers (including any pushed-back +characters) and return the content as a single string. +@end deffn + +@deffn primitive port-column port +@deffnx primitive port-line port +Return the current column number or line number of @var{port}, +using the current input port if none is specified. If the number is +unknown, the result is #f. Otherwise, the result is a 0-origin integer +- i.e. the first character of the first line is line 0, column 0. +(However, when you display a file position, for example in an error +message, we recommend you add 1 to get 1-origin integers. This is +because lines and column numbers traditionally start with 1, and that is +what non-programmers will find most natural.) +@end deffn + +@deffn primitive set-port-column! port column +@deffnx primitive set-port-line! port line +Set the current column or line number of @var{port}, using the +current input port if none is specified. +@end deffn + +@node Writing +@section Writing + +[Generic procedures for writing to ports.] + +@deffn primitive get-print-state port +Return the print state of the port @var{port}. If @var{port} +has no associated print state, @code{#f} is returned. +@end deffn + +@rnindex newline +@deffn primitive newline [port] +Send a newline to @var{port}. +@end deffn + +@deffn primitive port-with-print-state port pstate +Create a new port which behaves like @var{port}, but with an +included print state @var{pstate}. +@end deffn + +@deffn primitive print-options-interface [setting] +Option interface for the print options. Instead of using +this procedure directly, use the procedures +@code{print-enable}, @code{print-disable}, @code{print-set!} +and @code{print-options}. +@end deffn + +@deffn primitive simple-format destination message . args +Write @var{message} to @var{destination}, defaulting to +the current output port. +@var{message} can contain @code{~A} (was @code{%s}) and +@code{~S} (was @code{%S}) escapes. When printed, +the escapes are replaced with corresponding members of +@var{ARGS}: +@code{~A} formats using @code{display} and @code{~S} formats +using @code{write}. +If @var{destination} is @code{#t}, then use the current output +port, if @var{destination} is @code{#f}, then return a string +containing the formatted text. Does not add a trailing newline. +@end deffn + +@rnindex write-char +@deffn primitive write-char chr [port] +Send character @var{chr} to @var{port}. +@end deffn + +@findex fflush +@deffn primitive force-output [port] +Flush the specified output port, or the current output port if @var{port} +is omitted. The current output buffer contents are passed to the +underlying port implementation (e.g., in the case of fports, the +data will be written to the file and the output buffer will be cleared.) +It has no effect on an unbuffered port. + +The return value is unspecified. +@end deffn + +@deffn primitive flush-all-ports +Equivalent to calling @code{force-output} on +all open output ports. The return value is unspecified. +@end deffn + + +@node Closing +@section Closing + +@deffn primitive close-port port +Close the specified port object. Return @code{#t} if it +successfully closes a port or @code{#f} if it was already +closed. An exception may be raised if an error occurs, for +example when flushing buffered output. See also @ref{Ports and +File Descriptors, close}, for a procedure which can close file +descriptors. +@end deffn + +@rnindex close-input-port +@deffn primitive close-input-port port +Close the specified input port object. The routine has no effect if +the file has already been closed. An exception may be raised if an +error occurs. The value returned is unspecified. + +See also @ref{Ports and File Descriptors, close}, for a procedure +which can close file descriptors. +@end deffn + +@rnindex close-output-port +@deffn primitive close-output-port port +Close the specified output port object. The routine has no effect if +the file has already been closed. An exception may be raised if an +error occurs. The value returned is unspecified. + +See also @ref{Ports and File Descriptors, close}, for a procedure +which can close file descriptors. +@end deffn + +@deffn primitive port-closed? port +Return @code{#t} if @var{port} is closed or @code{#f} if it is +open. +@end deffn + + +@node Random Access +@section Random Access + +@deffn primitive seek fd_port offset whence +Sets the current position of @var{fd/port} to the integer +@var{offset}, which is interpreted according to the value of +@var{whence}. + +One of the following variables should be supplied for +@var{whence}: +@defvar SEEK_SET +Seek from the beginning of the file. +@end defvar +@defvar SEEK_CUR +Seek from the current position. +@end defvar +@defvar SEEK_END +Seek from the end of the file. +@end defvar +If @var{fd/port} is a file descriptor, the underlying system +call is @code{lseek}. @var{port} may be a string port. + +The value returned is the new position in the file. This means +that the current position of a port can be obtained using: +@lisp +(seek port 0 SEEK_CUR) +@end lisp +@end deffn + +@deffn primitive ftell fd_port +Return an integer representing the current position of +@var{fd/port}, measured from the beginning. Equivalent to: + +@lisp +(seek port 0 SEEK_CUR) +@end lisp +@end deffn + +@findex truncate +@findex ftruncate +@deffn primitive truncate-file object [length] +Truncates the object referred to by @var{object} to at most +@var{length} bytes. @var{object} can be a string containing a +file name or an integer file descriptor or a port. +@var{length} may be omitted if @var{object} is not a file name, +in which case the truncation occurs at the current port. +position. The return value is unspecified. +@end deffn + +@node Line/Delimited +@section Line Oriented and Delimited Text + +The delimited-I/O module can be accessed with: + +@smalllisp +(use-modules (ice-9 rdelim)) +@end smalllisp + +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)} +module from guile-scsh, but does not use multiple values or character +sets and has an extra procedure @code{write-line}. + +@c begin (scm-doc-string "rdelim.scm" "read-line") +@deffn procedure read-line [port] [handle-delim] +Return a line of text from @var{port} if specified, otherwise from the +value returned by @code{(current-input-port)}. Under Unix, a line of text +is terminated by the first end-of-line character or by end-of-file. + +If @var{handle-delim} is specified, it should be one of the following +symbols: +@table @code +@item trim +Discard the terminating delimiter. This is the default, but it will +be impossible to tell whether the read terminated with a delimiter or +end-of-file. +@item concat +Append the terminating delimiter (if any) to the returned string. +@item peek +Push the terminating delimiter (if any) back on to the port. +@item split +Return a pair containing the string read from the port and the +terminating delimiter or end-of-file object. +@end table +@end deffn + +@c begin (scm-doc-string "rdelim.scm" "read-line!") +@deffn procedure read-line! buf [port] +Read a line of text into the supplied string @var{buf} and return the +number of characters added to @var{buf}. If @var{buf} is filled, then +@code{#f} is returned. +Read from @var{port} if +specified, otherwise from the value returned by @code{(current-input-port)}. +@end deffn + +@c begin (scm-doc-string "rdelim.scm" "read-delimited") +@deffn procedure read-delimited delims [port] [handle-delim] +Read text until one of the characters in the string @var{delims} is found +or end-of-file is reached. Read from @var{port} if supplied, otherwise +from the value returned by @code{(current-input-port)}. +@var{handle-delim} takes the same values as described for @code{read-line}. +@end deffn + +@c begin (scm-doc-string "rdelim.scm" "read-delimited!") +@deffn procedure read-delimited! delims buf [port] [handle-delim] [start] [end] +Read text into the supplied string @var{buf} and return the number of +characters added to @var{buf} (subject to @var{handle-delim}, which takes +the same values specified for @code{read-line}. If @var{buf} is filled, +@code{#f} is returned for both the number of characters read and the +delimiter. Also terminates if one of the characters in the string +@var{delims} is found +or end-of-file is reached. Read from @var{port} if supplied, otherwise +from the value returned by @code{(current-input-port)}. +@end deffn + +@deffn primitive write-line obj [port] +Display @var{obj} and a newline character to @var{port}. If +@var{port} is not specified, @code{(current-output-port)} is +used. This function is equivalent to: +@lisp +(display obj [port]) +(newline [port]) +@end lisp +@end deffn + +Some of the abovementioned I/O functions rely on the following C +primitives. These will mainly be of interest to people hacking Guile +internals. + +@deffn primitive %read-delimited! delims str gobble [port [start [end]]] +Read characters from @var{port} into @var{str} until one of the +characters in the @var{delims} string is encountered. If +@var{gobble} is true, discard the delimiter character; +otherwise, leave it in the input stream for the next read. If +@var{port} is not specified, use the value of +@code{(current-input-port)}. If @var{start} or @var{end} are +specified, store data only into the substring of @var{str} +bounded by @var{start} and @var{end} (which default to the +beginning and end of the string, respectively). + + Return a pair consisting of the delimiter that terminated the +string and the number of characters read. If reading stopped +at the end of file, the delimiter returned is the +@var{eof-object}; if the string was filled without encountering +a delimiter, this value is @code{#f}. +@end deffn + +@deffn primitive %read-line [port] +Read a newline-terminated line from @var{port}, allocating storage as +necessary. The newline terminator (if any) is removed from the string, +and a pair consisting of the line and its delimiter is returned. The +delimiter may be either a newline or the @var{eof-object}; if +@code{%read-line} is called at the end of file, it returns the pair +@code{(#<eof> . #<eof>)}. +@end deffn + +@node Block Reading and Writing +@section Block reading and writing + +The Block-string-I/O module can be accessed with: + +@smalllisp +(use-modules (ice-9 rw)) +@end smalllisp + +It currently contains procedures that help to implement the +@code{(scsh rw)} module in guile-scsh. + +@deffn primitive read-string!/partial str [port_or_fdes start end] +Read characters from a port or file descriptor into a +string @var{str}. A port must have an underlying file +descriptor --- a so-called fport. This procedure is +scsh-compatible and can efficiently read large strings. +It will: + +@itemize +@item +attempt to fill the entire string, unless the @var{start} +and/or @var{end} arguments are supplied. i.e., @var{start} +defaults to 0 and @var{end} defaults to +@code{(string-length str)} +@item +use the current input port if @var{port_or_fdes} is not +supplied. +@item +return fewer than the requested number of characters in some +cases, e.g., on end of file, if interrupted by a signal, or if +not all the characters are immediately available. +@item +wait indefinitely for some input if no characters are +currently available, +unless the port is in non-blocking mode. +@item +read characters from the port's input buffers if available, +instead from the underlying file descriptor. +@item +return @code{#f} if end-of-file is encountered before reading +any characters, otherwise return the number of characters +read. +@item +return 0 if the port is in non-blocking mode and no characters +are immediately available. +@item +return 0 if the request is for 0 bytes, with no +end-of-file check. +@end itemize +@end deffn + +@deffn primitive write-string/partial str [port_or_fdes start end] +Write characters from a string @var{str} to a port or file +descriptor. A port must have an underlying file descriptor +--- a so-called fport. This procedure is +scsh-compatible and can efficiently write large strings. +It will: + +@itemize +@item +attempt to write the entire string, unless the @var{start} +and/or @var{end} arguments are supplied. i.e., @var{start} +defaults to 0 and @var{end} defaults to +@code{(string-length str)} +@item +use the current output port if @var{port_of_fdes} is not +supplied. +@item +in the case of a buffered port, store the characters in the +port's output buffer, if all will fit. If they will not fit +then any existing buffered characters will be flushed +before attempting +to write the new characters directly to the underlying file +descriptor. If the port is in non-blocking mode and +buffered characters can not be flushed immediately, then an +@code{EAGAIN} system-error exception will be raised (Note: +scsh does not support the use of non-blocking buffered ports.) +@item +write fewer than the requested number of +characters in some cases, e.g., if interrupted by a signal or +if not all of the output can be accepted immediately. +@item +wait indefinitely for at least one character +from @var{str} to be accepted by the port, unless the port is +in non-blocking mode. +@item +return the number of characters accepted by the port. +@item +return 0 if the port is in non-blocking mode and can not accept +at least one character from @var{str} immediately +@item +return 0 immediately if the request size is 0 bytes. +@end itemize +@end deffn + +@node Default Ports +@section Default Ports for Input, Output and Errors + +@rnindex current-input-port +@deffn primitive current-input-port +Return the current input port. This is the default port used +by many input procedures. Initially, @code{current-input-port} +returns the @dfn{standard input} in Unix and C terminology. +@end deffn + +@rnindex current-output-port +@deffn primitive current-output-port +Return the current output port. This is the default port used +by many output procedures. Initially, +@code{current-output-port} returns the @dfn{standard output} in +Unix and C terminology. +@end deffn + +@deffn primitive current-error-port +Return the port to which errors and warnings should be sent (the +@dfn{standard error} in Unix and C terminology). +@end deffn + +@deffn primitive set-current-input-port port +@deffnx primitive set-current-output-port port +@deffnx primitive set-current-error-port port +Change the ports returned by @code{current-input-port}, +@code{current-output-port} and @code{current-error-port}, respectively, +so that they use the supplied @var{port} for input or output. +@end deffn + +@deffn primitive set-current-output-port port +Set the current default output port to PORT. +@end deffn + +@deffn primitive set-current-error-port port +Set the current default error port to PORT. +@end deffn + + +@node Port Types +@section Types of Port + +[Types of port; how to make them.] + +@menu +* File Ports:: Ports on an operating system file. +* String Ports:: Ports on a Scheme string. +* Soft Ports:: Ports on arbitrary Scheme procedures. +* Void Ports:: Ports on nothing at all. +@end menu + + +@node File Ports +@subsection File Ports + +The following procedures are used to open file ports. +See also @ref{Ports and File Descriptors, open}, for an interface +to the Unix @code{open} system call. + +@deffn primitive open-file filename mode +Open the file whose name is @var{filename}, and return a port +representing that file. The attributes of the port are +determined by the @var{mode} string. The way in which this is +interpreted is similar to C stdio. The first character must be +one of the following: +@table @samp +@item r +Open an existing file for input. +@item w +Open a file for output, creating it if it doesn't already exist +or removing its contents if it does. +@item a +Open a file for output, creating it if it doesn't already +exist. All writes to the port will go to the end of the file. +The "append mode" can be turned off while the port is in use +@pxref{Ports and File Descriptors, fcntl} +@end table +The following additional characters can be appended: +@table @samp +@item + +Open the port for both input and output. E.g., @code{r+}: open +an existing file for both input and output. +@item 0 +Create an "unbuffered" port. In this case input and output +operations are passed directly to the underlying port +implementation without additional buffering. This is likely to +slow down I/O operations. The buffering mode can be changed +while a port is in use @pxref{Ports and File Descriptors, +setvbuf} +@item l +Add line-buffering to the port. The port output buffer will be +automatically flushed whenever a newline character is written. +@end table +In theory we could create read/write ports which were buffered +in one direction only. However this isn't included in the +current interfaces. If a file cannot be opened with the access +requested, @code{open-file} throws an exception. +@end deffn + +@rnindex open-input-file +@deffn procedure open-input-file filename +Open @var{filename} for input. Equivalent to +@smalllisp +(open-file @var{filename} "r") +@end smalllisp +@end deffn + +@rnindex open-output-file +@deffn procedure open-output-file filename +Open @var{filename} for output. Equivalent to +@smalllisp +(open-file @var{filename} "w") +@end smalllisp +@end deffn + +@rnindex call-with-input-file +@deffn procedure call-with-input-file file proc +@var{proc} should be a procedure of one argument, and @var{file} should +be a string naming a file. The file must already exist. These +procedures call @var{proc} with one argument: the port obtained by +opening the named file for input or output. If the file cannot be +opened, an error is signalled. If the procedure returns, then the port +is closed automatically and the value yielded by the procedure is +returned. If the procedure does not return, then the port will not be +closed automatically unless it is possible to prove that the port will +never again be used for a read or write operation. +@end deffn + +@rnindex call-with-output-file +@deffn procedure call-with-output-file file proc +@var{proc} should be a procedure of one argument, and @var{file} should +be a string naming a file. The behaviour is unspecified if the file +already exists. These procedures call @var{proc} with one argument: the +port obtained by opening the named file for input or output. If the +file cannot be opened, an error is signalled. If the procedure returns, +then the port is closed automatically and the value yielded by the +procedure is returned. If the procedure does not return, then the port +will not be closed automatically unless it is possible to prove that the +port will never again be used for a read or write operation. +@end deffn + +@rnindex with-input-from-file +@deffn procedure with-input-from-file file thunk +@var{thunk} must be a procedure of no arguments, and @var{file} must be +a string naming a file. The file must already exist. The file is opened +for input, an input port connected to it is made the default value +returned by @code{current-input-port}, and the @var{thunk} is called +with no arguments. When the @var{thunk} returns, the port is closed and +the previous default is restored. Returns the value yielded by +@var{thunk}. If an escape procedure is used to escape from the +continuation of these procedures, their behavior is implementation +dependent. +@end deffn + +@rnindex with-output-to-file +@deffn procedure with-output-to-file file thunk +@var{thunk} must be a procedure of no arguments, and @var{file} must be +a string naming a file. The effect is unspecified if the file already +exists. The file is opened for output, an output port connected to it +is made the default value returned by @code{current-output-port}, and +the @var{thunk} is called with no arguments. When the @var{thunk} +returns, the port is closed and the previous default is restored. +Returns the value yielded by @var{thunk}. If an escape procedure is +used to escape from the continuation of these procedures, their behavior +is implementation dependent. +@end deffn + +@deffn procedure with-error-to-file file thunk +@var{thunk} must be a procedure of no arguments, and @var{file} must be +a string naming a file. The effect is unspecified if the file already +exists. The file is opened for output, an output port connected to it +is made the default value returned by @code{current-error-port}, and the +@var{thunk} is called with no arguments. When the @var{thunk} returns, +the port is closed and the previous default is restored. Returns the +value yielded by @var{thunk}. If an escape procedure is used to escape +from the continuation of these procedures, their behavior is +implementation dependent. +@end deffn + +@deffn primitive port-mode port +Returns the port modes associated with the open port @var{port}. These +will not necessarily be identical to the modes used when the port was +opened, since modes such as "append" which are used only during +port creation are not retained. +@end deffn + +@deffn primitive port-filename port +Return the filename associated with @var{port}. This function returns +the strings "standard input", "standard output" and "standard error" +when called on the current input, output and error ports respectively. +@end deffn + +@deffn primitive set-port-filename! port filename +Change the filename associated with @var{port}, using the current input +port if none is specified. Note that this does not change the port's +source of data, but only the value that is returned by +@code{port-filename} and reported in diagnostic output. +@end deffn + +@deffn primitive file-port? obj +Determine whether @var{obj} is a port that is related to a file. +@end deffn + + +@node String Ports +@subsection String Ports + +The following allow string ports to be opened by analogy to R4R* +file port facilities: + +@deffn primitive call-with-output-string proc +Calls the one-argument procedure @var{proc} with a newly created output +port. When the function returns, the string composed of the characters +written into the port is returned. +@end deffn + +@deffn primitive call-with-input-string string proc +Calls the one-argument procedure @var{proc} with a newly +created input port from which @var{string}'s contents may be +read. The value yielded by the @var{proc} is returned. +@end deffn + +@deffn procedure with-output-to-string thunk +Calls the zero-argument procedure @var{thunk} with the current output +port set temporarily to a new string port. It returns a string +composed of the characters written to the current output. +@end deffn + +@deffn procedure with-input-from-string string thunk +Calls the zero-argument procedure @var{thunk} with the current input +port set temporarily to a string port opened on the specified +@var{string}. The value yielded by @var{thunk} is returned. +@end deffn + +@deffn primitive open-input-string str +Take a string and return an input port that delivers characters +from the string. The port can be closed by +@code{close-input-port}, though its storage will be reclaimed +by the garbage collector if it becomes inaccessible. +@end deffn + +@deffn primitive open-output-string +Return an output port that will accumulate characters for +retrieval by @code{get-output-string}. The port can be closed +by the procedure @code{close-output-port}, though its storage +will be reclaimed by the garbage collector if it becomes +inaccessible. +@end deffn + +@deffn primitive get-output-string port +Given an output port created by @code{open-output-string}, +return a string consisting of the characters that have been +output to the port so far. +@end deffn + +A string port can be used in many procedures which accept a port +but which are not dependent on implementation details of fports. +E.g., seeking and truncating will work on a string port, +but trying to extract the file descriptor number will fail. + + +@node Soft Ports +@subsection Soft Ports + +A @dfn{soft-port} is a port based on a vector of procedures capable of +accepting or delivering characters. It allows emulation of I/O ports. + +@deffn primitive make-soft-port pv modes +Return a port capable of receiving or delivering characters as +specified by the @var{modes} string (@pxref{File Ports, +open-file}). @var{pv} must be a vector of length 5. Its +components are as follows: + +@enumerate 0 +@item +procedure accepting one character for output +@item +procedure accepting a string for output +@item +thunk for flushing output +@item +thunk for getting one character +@item +thunk for closing port (not by garbage collection) +@end enumerate + +For an output-only port only elements 0, 1, 2, and 4 need be +procedures. For an input-only port only elements 3 and 4 need +be procedures. Thunks 2 and 4 can instead be @code{#f} if +there is no useful operation for them to perform. + +If thunk 3 returns @code{#f} or an @code{eof-object} +(@pxref{Input, eof-object?, ,r5rs, The Revised^5 Report on +Scheme}) it indicates that the port has reached end-of-file. +For example: + +@lisp +(define stdout (current-output-port)) +(define p (make-soft-port + (vector + (lambda (c) (write c stdout)) + (lambda (s) (display s stdout)) + (lambda () (display "." stdout)) + (lambda () (char-upcase (read-char))) + (lambda () (display "@@" stdout))) + "rw")) + +(write p p) @result{} #<input-output: soft 8081e20> +@end lisp +@end deffn + + +@node Void Ports +@subsection Void Ports + +This kind of port causes any data to be discarded when written to, and +always returns the end-of-file object when read from. + +@deffn primitive %make-void-port mode +Create and return a new void port. A void port acts like +@code{/dev/null}. The @var{mode} argument specifies the input/output +modes for this port: see the documentation for @code{open-file} in +@ref{File Ports}. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-memory.texi b/doc/ref/scheme-memory.texi new file mode 100644 index 000000000..6a1f21e9c --- /dev/null +++ b/doc/ref/scheme-memory.texi @@ -0,0 +1,222 @@ +@page +@node Memory Management +@chapter Memory Management and Garbage Collection + +@menu +* Garbage Collection:: +* Weak References:: +* Guardians:: +@end menu + + +@node Garbage Collection +@section Garbage Collection + +[FIXME: this is pasted in from Tom Lord's original guile.texi and should +be reviewed] + +@deffn primitive gc +Scans all of SCM objects and reclaims for further use those that are +no longer accessible. +@end deffn + +@deffn primitive gc-stats +Return an association list of statistics about Guile's current +use of storage. +@end deffn + +@deffn primitive object-address obj +Return an integer that for the lifetime of @var{obj} is uniquely +returned by this function for @var{obj} +@end deffn + +@deffn primitive unhash-name name +Flushes the glocs for @var{name}, or all glocs if @var{name} +is @code{#t}. +@end deffn + + +@node Weak References +@section Weak References + +[FIXME: This chapter is based on Mikael Djurfeldt's answer to a question +by Michael Livshin. Any mistakes are not theirs, of course. ] + +Weak references let you attach bookkeeping information to data so that +the additional information automatically disappears when the original +data is no longer in use and gets garbage collected. In a weak key hash, +the hash entry for that key disappears as soon as the key is no longer +referneced from anywhere else. For weak value hashes, the same happens +as soon as the value is no longer in use. Entries in a doubly weak hash +disappear when either the key or the value are not used anywhere else +anymore. + +Property lists offer the same kind of functionality as weak key hashes +in many situations. (@pxref{Property Lists}) + +Here's an example (a little bit strained perhaps, but one of the +examples is actually used in Guile): + +Assume that you're implementing a debugging system where you want to +associate information about filename and position of source code +expressions with the expressions themselves. + +Hashtables can be used for that, but if you use ordinary hash tables +it will be impossible for the scheme interpreter to "forget" old +source when, for example, a file is reloaded. + +To implement the mapping from source code expressions to positional +information it is necessary to use weak-key tables since we don't want +the expressions to be remembered just because they are in our table. + +To implement a mapping from source file line numbers to source code +expressions you would use a weak-value table. + +To implement a mapping from source code expressions to the procedures +they constitute a doubly-weak table has to be used. + +@menu +* Weak key hashes:: +* Weak vectors:: +@end menu + + +@node Weak key hashes +@subsection Weak key hashes + +@deffn primitive make-weak-key-hash-table size +@deffnx primitive make-weak-value-hash-table size +@deffnx primitive make-doubly-weak-hash-table size +Return a weak hash table with @var{size} buckets. As with any +hash table, choosing a good size for the table requires some +caution. + +You can modify weak hash tables in exactly the same way you +would modify regular hash tables. (@pxref{Hash Tables}) +@end deffn + +@deffn primitive weak-key-hash-table? obj +@deffnx primitive weak-value-hash-table? obj +@deffnx primitive doubly-weak-hash-table? obj +Return @code{#t} if @var{obj} is the specified weak hash +table. Note that a doubly weak hash table is neither a weak key +nor a weak value hash table. +@end deffn + +@deffn primitive make-weak-value-hash-table k +@end deffn + +@deffn primitive weak-value-hash-table? x +@end deffn + +@deffn primitive make-doubly-weak-hash-table k +@end deffn + +@deffn primitive doubly-weak-hash-table? x +@end deffn + + +@node Weak vectors +@subsection Weak vectors + +Weak vectors are mainly useful in Guile's implementation of weak hash +tables. + +@deffn primitive make-weak-vector size [fill] +Return a weak vector with @var{size} elements. If the optional +argument @var{fill} is given, all entries in the vector will be +set to @var{fill}. The default value for @var{fill} is the +empty list. +@end deffn + +@deffn primitive weak-vector . l +@deffnx primitive list->weak-vector l +Construct a weak vector from a list: @code{weak-vector} uses +the list of its arguments while @code{list->weak-vector} uses +its only argument @var{l} (a list) to construct a weak vector +the same way @code{list->vector} would. +@end deffn + +@deffn primitive weak-vector? obj +Return @code{#t} if @var{obj} is a weak vector. Note that all +weak hashes are also weak vectors. +@end deffn + + +@node Guardians +@section Guardians + +@deffn primitive make-guardian [greedy?] +Create a new guardian. +A guardian protects a set of objects from garbage collection, +allowing a program to apply cleanup or other actions. + +@code{make-guardian} returns a procedure representing the guardian. +Calling the guardian procedure with an argument adds the +argument to the guardian's set of protected objects. +Calling the guardian procedure without an argument returns +one of the protected objects which are ready for garbage +collection, or @code{#f} if no such object is available. +Objects which are returned in this way are removed from +the guardian. + +@code{make-guardian} takes one optional argument that says whether the +new guardian should be greedy or sharing. If there is any chance +that any object protected by the guardian may be resurrected, +then you should make the guardian greedy (this is the default). + +See R. Kent Dybvig, Carl Bruggeman, and David Eby (1993) +"Guardians in a Generation-Based Garbage Collector". +ACM SIGPLAN Conference on Programming Language Design +and Implementation, June 1993. + +(the semantics are slightly different at this point, but the +paper still (mostly) accurately describes the interface). +@end deffn + +@deffn primitive destroy-guardian! guardian +Destroys @var{guardian}, by making it impossible to put any more +objects in it or get any objects from it. It also unguards any +objects guarded by @var{guardian}. +@end deffn + +@deffn primitive guardian-greedy? guardian +Return @code{#t} if @var{guardian} is a greedy guardian, otherwise @code{#f}. +@end deffn + +@deffn primitive guardian-destroyed? guardian +Return @code{#t} if @var{guardian} has been destroyed, otherwise @code{#f}. +@end deffn + + +@page +@node Objects +@chapter Objects + +@deffn primitive entity? obj +Return @code{#t} if @var{obj} is an entity. +@end deffn + +@deffn primitive operator? obj +Return @code{#t} if @var{obj} is an operator. +@end deffn + +@deffn primitive set-object-procedure! obj proc +Return the object procedure of @var{obj} to @var{proc}. +@var{obj} must be either an entity or an operator. +@end deffn + +@deffn primitive make-class-object metaclass layout +Create a new class object of class @var{metaclass}, with the +slot layout specified by @var{layout}. +@end deffn + +@deffn primitive make-subclass-object class layout +Create a subclass object of @var{class}, with the slot layout +specified by @var{layout}. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-modules.texi b/doc/ref/scheme-modules.texi new file mode 100644 index 000000000..c0b37bc3c --- /dev/null +++ b/doc/ref/scheme-modules.texi @@ -0,0 +1,826 @@ +@page +@node Modules +@chapter Modules +@cindex modules + +When programs become large, naming conflicts can occur when a function +or global variable defined in one file has the same name as a function +or global variable in another file. Even just a @emph{similarity} +between function names can cause hard-to-find bugs, since a programmer +might type the wrong function name. + +The approach used to tackle this problem is called @emph{information +encapsulation}, which consists of packaging functional units into a +given name space that is clearly separated from other name spaces. +@cindex encapsulation +@cindex information encapsulation +@cindex name space + +The language features that allow this are usually called @emph{the +module system} because programs are broken up into modules that are +compiled separately (or loaded separately in an interpreter). + +Older languages, like C, have limited support for name space +manipulation and protection. In C a variable or function is public by +default, and can be made local to a module with the @code{static} +keyword. But you cannot reference public variables and functions from +another module with different names. + +More advanced module systems have become a common feature in recently +designed languages: ML, Python, Perl, and Modula 3 all allow the +@emph{renaming} of objects from a foreign module, so they will not +clutter the global name space. +@cindex name space - private + +@menu +* Scheme and modules:: How modules are handled in standard Scheme. +* The Guile module system:: How Guile does it. +* Dynamic Libraries:: Loading libraries of compiled code at run time. +@end menu + + +@node Scheme and modules +@section Scheme and modules + +Scheme, as defined in R5RS, does @emph{not} have a module system at all. + +Aubrey Jaffer, mostly to support his portable Scheme library SLIB, +implemented a provide/require mechanism for many Scheme implementations. +Library files in SLIB @emph{provide} a feature, and when user programs +@emph{require} that feature, the library file is loaded in. + +For example, the file @file{random.scm} in the SLIB package contains the +line + +@smalllisp +(provide 'random) +@end smalllisp + +so to use its procedures, a user would type + +@smalllisp +(require 'random) +@end smalllisp + +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 +module system. + + +@node The Guile module system +@section The Guile module system + +In 1996 Tom Lord implemented a full-featured module system for Guile which +allows loading Scheme source files into a private name space. This system has +been in available since Guile version 1.4. +@c fixme: Actually, was it available before? 1.4 seems a bit late... + +For Guile version 1.5.0 and later, the system has been improved to have better +integration from C code, more fine-grained user control over interfaces, and +documentation. + +Although it is anticipated that the module system implementation will +change in the future, the Scheme programming interface described in this +manual should be considered stable. The C programming interface is +considered relatively stable, although at the time of this writing, +there is still some flux. +@c fixme: Review: Need better C code interface commentary. + +@menu +* General Information about Modules:: Guile module basics. +* Using Guile Modules:: How to use existing modules. +* Creating Guile Modules:: How to package your code into modules. +* More Module Procedures:: Low-level module code. +* Module System Quirks:: Strange things to be aware of. +* Included Guile Modules:: Which modules come with Guile? +@end menu + +@node General Information about Modules +@subsection General Information about Modules + +A Guile module is a collection of named procedures, variables and +macros, altogether called the @dfn{bindings}, since they bind, or +associate, a symbol (the name) to a Scheme object (procedure, variable, +or macro). Within a module, all bindings are visible. Certain bindings +can be declared @dfn{public}, in which case they are added to the +module's so-called @dfn{export list}; this set of public bindings is +called the module's @dfn{public interface} (@pxref{Creating Guile +Modules}). + +A client module @dfn{uses} a providing module's bindings by either +accessing the providing module's public interface, or by building a +custom interface (and then accessing that). In a custom interface, the +client module can @dfn{select} which bindings to access and can also +algorithmically @dfn{rename} bindings. In contrast, when using the +providing module's public interface, the entire export list is available +without renaming (@pxref{Using Guile Modules}). + +To use a module, it must be found and loaded. All Guile modules have a +unique @dfn{module name}, which is a list of one or more symbols. +Examples are @code{(ice-9 popen)} or @code{(srfi srfi-11)}. When Guile +searches for the code of a module, it constructs the name of the file to +load by concatenating the name elements with slashes between the +elements and appending a number of file name extensions from the list +@code{%load-extensions} (REFFIXME). The resulting file name is then +searched in all directories in the variable @code{%load-path}. For +example, the @code{(ice-9 popen)} module would result in the filename +@code{ice-9/popen.scm} and searched in the installation directory of +Guile and in all other directories in the load path. + +@c FIXME::martin: Not sure about this, maybe someone knows better? +Every module has a so-called syntax transformer associated with it. +This is a procedure which performs all syntax transformation for the +time the module is read in and evaluated. When working with modules, +you can manipulate the current syntax transformer using the +@code{use-syntax} syntactic form or the @code{#:use-syntax} module +definition option (@pxref{Creating Guile Modules}). + +Please note that there are some problems with the current module system +you should keep in mind (@pxref{Module System Quirks}). We hope to +address these eventually. + + +@node Using Guile Modules +@subsection Using Guile Modules + +To use a Guile module is to access either its public interface or a +custom interface (@pxref{General Information about Modules}). Both +types of access are handled by the syntactic form @code{use-modules}, +which accepts one or more interface specifications and, upon evaluation, +arranges for those interfaces to be available to the current module. +This process may include locating and loading code for a given module if +that code has not yet been loaded (REFFIXME %load-path). + +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 +(use-modules (ice-9 popen)) +@end smalllisp + +Here, the interface specification is @code{(ice-9 popen)}, and the +result is that the current module now has access to @code{open-pipe}, +@code{close-pipe}, @code{open-input-pipe}, and so on (@pxref{Included +Guile Modules}). + +Note in the previous example that if the current module had already +defined @code{open-pipe}, that definition would be overwritten by the +definition in @code{(ice-9 popen)}. For this reason (and others), there +is a second variation of interface specification that not only names a +module to be accessed, but also selects bindings from it and renames +them to suit the current module's needs. For example: + +@smalllisp +(use-modules ((ice-9 popen) + :select ((open-pipe . pipe-open) close-pipe) + :rename (symbol-prefix-proc 'unixy:))) +@end smalllisp + +Here, the interface specification is more complex than before, and the +result is that a custom interface with only two bindings is created and +subsequently accessed by the current module. The mapping of old to new +names is as follows: + +@c Use `smallexample' since `table' is ugly. --ttn +@smallexample +(ice-9 popen) sees: current module sees: +open-pipe unixy:pipe-open +close-pipe unixy:close-pipe +@end smallexample + +This example also shows how to use the convenience procedure +@code{symbol-prefix-proc}. + +@c begin (scm-doc-string "boot-9.scm" "symbol-prefix-proc") +@deffn procedure symbol-prefix-proc prefix-sym +Return a procedure that prefixes its arg (a symbol) with +@var{prefix-sym}. +@c Insert gratuitous C++ slam here. --ttn +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "use-modules") +@deffn syntax use-modules spec @dots{} +Resolve each interface specification @var{spec} into an interface and +arrange for these to be accessible by the current module. The return +value is unspecified. + +@var{spec} can be a list of symbols, in which case it names a module +whose public interface is found and used. + +@var{spec} can also be of the form: + +@smalllisp + (MODULE-NAME [:select SELECTION] [:rename RENAMER]) +@end smalllisp + +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 +list of selection-specs; and @var{renamer} is a procedure that takes a +symbol and returns its new name. A selection-spec is either a symbol or +a pair of symbols @code{(ORIG . SEEN)}, where @var{orig} is the name in +the used module and @var{seen} is the name in the using module. Note +that @var{seen} is also passed through @var{renamer}. + +The @code{:select} and @code{:rename} clauses are optional. If both are +omitted, the returned interface has no bindings. If the @code{:select} +clause is omitted, @var{renamer} operates on the used module's public +interface. + +Signal error if module name is not resolvable. +@end deffn + + +@c FIXME::martin: Is this correct, and is there more to say? +@c FIXME::martin: Define term and concept `system transformer' somewhere. + +@deffn syntax use-syntax module-name +Load the module @code{module-name} and use its system +transformer as the system transformer for the currently defined module, +as well as installing it as the current system transformer. +@end deffn + + +@node Creating Guile Modules +@subsection Creating Guile Modules + +When you want to create your own modules, you have to take the following +steps: + +@itemize @bullet +@item +Create a Scheme source file and add all variables and procedures you wish +to export, or which are required by the exported procedures. + +@item +Add a @code{define-module} form at the beginning. + +@item +Export all bindings which should be in the public interface, either +by using @code{define-public} or @code{export} (both documented below). +@end itemize + +@c begin (scm-doc-string "boot-9.scm" "define-module") +@deffn syntax define-module module-name [options @dots{}] +@var{module-name} is of the form @code{(hierarchy file)}. One +example of this is + +@smalllisp +(define-module (ice-9 popen)) +@end smalllisp + +@code{define-module} makes this module available to Guile programs under +the given @var{module-name}. + +The @var{options} are keyword/value pairs which specify more about the +defined module. The recognized options and their meaning is shown in +the following table. + +@c fixme: Should we use "#:" or ":"? + +@table @code +@item #:use-module @var{interface-specification} +Equivalent to a @code{(use-modules @var{interface-specification})} +(@pxref{Using Guile Modules}). + +@item #:use-syntax @var{module} +Use @var{module} when loading the currently defined module, and install +it as the syntax transformer. + +@item #:autoload @var{module} @var{symbol} +Load @var{module} whenever @var{symbol} is accessed. + +@item #:export @var{list} +Export all identifiers in @var{list}, which must be a list of symbols. +This is equivalent to @code{(export @var{list})} in the module body. + +@item #:no-backtrace +Tell Guile not to record information for procedure backtraces when +executing the procedures in this module. + +@item #:pure +Create a @dfn{pure} module, that is a module which does not contain any +of the standard procedure bindings except for the syntax forms. This is +useful if you want to create @dfn{safe} modules, that is modules which +do not know anything about dangerous procedures. +@end table + +@end deffn +@c end + +@deffn syntax export variable @dots{} +Add all @var{variable}s (which must be symbols) to the list of exported +bindings of the current module. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "define-public") +@deffn syntax define-public @dots{} +Equivalent to @code{(begin (define foo ...) (export foo))}. +@end deffn +@c end + + +@node More Module Procedures +@subsection More Module Procedures + +@c FIXME::martin: Review me! + +@c FIXME::martin: Should this procedure be documented and supported +@c at all? + +The procedures in this section are useful if you want to dig into the +innards of Guile's module system. If you don't know precisely what you +do, you should probably avoid using any of them. + +@deffn primitive standard-eval-closure module +Return an eval closure for the module @var{module}. +@end deffn + + +@node Module System Quirks +@subsection Module System Quirks + +Although the programming interfaces are relatively stable, the Guile +module system itself is still evolving. Here are some situations where +usage surpasses design. + +@itemize @bullet + +@item +When using a module which exports a macro definition, the other module +must export all bindings the macro expansion uses, too, because the +expanded code would otherwise not be able to see these definitions and +issue a ``variable unbound'' error, or worse, would use another binding +which might be present in the scope of the expansion. + +@item +When two or more used modules export bindings with the same names, the +last accessed module wins, and the exported binding of that last module +will silently be used. This might lead to hard-to-find errors because +wrong procedures or variables are used. To avoid this kind of +@dfn{name-clash} situation, use a custom interface specification +(@pxref{Using Guile Modules}). (We include this entry for the possible +benefit of users of Guile versions previous to 1.5.0, when custom +interfaces were added to the module system.) + +@item +[Add other quirks here.] + +@end itemize + + +@node Included Guile Modules +@subsection Included Guile Modules + +@c FIXME::martin: Review me! + +Some modules are included in the Guile distribution; here are references +to the entries in this manual which describe them in more detail: + +@table @strong +@item boot-9 +boot-9 is Guile's initialization module, and it is always loaded when +Guile starts up. + +@item (ice-9 debug) +Mikael Djurfeldt's source-level debugging support for Guile +(@pxref{Debugger User Interface}). + +@item (ice-9 threads) +Guile's support for multi threaded execution (@pxref{Scheduling}). + +@item (ice-9 rdelim) +Line- and character-delimited input (@pxref{Line/Delimited}). + +@item (ice-9 rw) +Block string input/output (@pxref{Block Reading and Writing}). + +@item (ice-9 documentation) +Online documentation (REFFIXME). + +@item (srfi srfi-1) +A library providing a lot of useful list and pair processing +procedures (@pxref{SRFI-1}). + +@item (srfi srfi-2) +Support for @code{and-let*} (@pxref{SRFI-2}). + +@item (srfi srfi-4) +Support for homogeneous numeric vectors (@pxref{SRFI-4}). + +@item (srfi srfi-6) +Support for some additional string port procedures (@pxref{SRFI-6}). + +@item (srfi srfi-8) +Multiple-value handling with @code{receive} (@pxref{SRFI-8}). + +@item (srfi srfi-9) +Record definition with @code{define-record-type} (@pxref{SRFI-9}). + +@item (srfi srfi-10) +Read hash extension @code{#,()} (@pxref{SRFI-10}). + +@item (srfi srfi-11) +Multiple-value handling with @code{let-values} and @code{let-values*} +(@pxref{SRFI-11}). + +@item (srfi srfi-13) +String library (@pxref{SRFI-13}). + +@item (srfi srfi-14) +Character-set library (@pxref{SRFI-14}). + +@item (srfi srfi-17) +Getter-with-setter support (@pxref{SRFI-17}). + +@item (ice-9 slib) +This module contains hooks for using Aubrey Jaffer's portable Scheme +library SLIB from Guile (@pxref{SLIB}). + +@c FIXME::martin: This module is not in the distribution. Remove it +@c from here? +@item (ice-9 jacal) +This module contains hooks for using Aubrey Jaffer's symbolic math +packge Jacal from Guile (@pxref{JACAL}). +@end table + + +@node Dynamic Libraries +@section Dynamic Libraries + +Most modern Unices have something called @dfn{shared libraries}. This +ordinarily means that they have the capability to share the executable +image of a library between several running programs to save memory and +disk space. But generally, shared libraries give a lot of additional +flexibility compared to the traditional static libraries. In fact, +calling them `dynamic' libraries is as correct as calling them `shared'. + +Shared libraries really give you a lot of flexibility in addition to the +memory and disk space savings. When you link a program against a shared +library, that library is not closely incorporated into the final +executable. Instead, the executable of your program only contains +enough information to find the needed shared libraries when the program +is actually run. Only then, when the program is starting, is the final +step of the linking process performed. This means that you need not +recompile all programs when you install a new, only slightly modified +version of a shared library. The programs will pick up the changes +automatically the next time they are run. + +Now, when all the necessary machinery is there to perform part of the +linking at run-time, why not take the next step and allow the programmer +to explicitly take advantage of it from within his program? Of course, +many operating systems that support shared libraries do just that, and +chances are that Guile will allow you to access this feature from within +your Scheme programs. As you might have guessed already, this feature +is called @dfn{dynamic linking}@footnote{Some people also refer to the +final linking stage at program startup as `dynamic linking', so if you +want to make yourself perfectly clear, it is probably best to use the +more technical term @dfn{dlopening}, as suggested by Gordon Matzigkeit +in his libtool documentation.} + +As with many aspects of Guile, there is a low-level way to access the +dynamic linking apparatus, and a more high-level interface that +integrates dynamically linked libraries into the module system. + +@menu +* Low level dynamic linking:: +* Compiled Code Modules:: +* Dynamic Linking and Compiled Code Modules:: +@end menu + +@node Low level dynamic linking +@subsection Low level dynamic linking + +When using the low level procedures to do your dynamic linking, you have +complete control over which library is loaded when and what get's done +with it. + +@deffn primitive dynamic-link library +Find the shared library denoted by @var{library} (a string) and link it +into the running Guile application. When everything works out, return a +Scheme object suitable for representing the linked object file. +Otherwise an error is thrown. How object files are searched is system +dependent. + +Normally, @var{library} is just the name of some shared library file +that will be searched for in the places where shared libraries usually +reside, such as in @file{/usr/lib} and @file{/usr/local/lib}. +@end deffn + +@deffn primitive dynamic-object? val +Determine whether @var{val} represents a dynamically linked object file. +@end deffn + +@deffn primitive dynamic-unlink dynobj +Unlink the indicated object file from the application. The argument +@var{dynobj} should be one of the values returned by +@code{dynamic-link}. When @code{dynamic-unlink} has been called on +@var{dynobj}, it is no longer usable as an argument to the functions +below and you will get type mismatch errors when you try to. +@end deffn + +@deffn primitive dynamic-func function dynobj +Search the C function indicated by @var{function} (a string or symbol) +in @var{dynobj} and return some Scheme object that can later be used +with @code{dynamic-call} to actually call this function. Right now, +these Scheme objects are formed by casting the address of the function +to @code{long} and converting this number to its Scheme representation. + +Regardless whether your C compiler prepends an underscore @samp{_} to +the global names in a program, you should @strong{not} include this +underscore in @var{function}. Guile knows whether the underscore is +needed or not and will add it when necessary. +@end deffn + +@deffn primitive dynamic-call function dynobj +Call the C function indicated by @var{function} and @var{dynobj}. The +function is passed no arguments and its return value is ignored. When +@var{function} is something returned by @code{dynamic-func}, call that +function and ignore @var{dynobj}. When @var{function} is a string (or +symbol, etc.), look it up in @var{dynobj}; this is equivalent to + +@smallexample +(dynamic-call (dynamic-func @var{function} @var{dynobj} #f)) +@end smallexample + +Interrupts are deferred while the C function is executing (with +@code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}). +@end deffn + +@deffn primitive dynamic-args-call function dynobj args +Call the C function indicated by @var{function} and @var{dynobj}, just +like @code{dynamic-call}, but pass it some arguments and return its +return value. The C function is expected to take two arguments and +return an @code{int}, just like @code{main}: + +@smallexample +int c_func (int argc, char **argv); +@end smallexample + +The parameter @var{args} must be a list of strings and is converted into +an array of @code{char *}. The array is passed in @var{argv} and its +size in @var{argc}. The return value is converted to a Scheme number +and returned from the call to @code{dynamic-args-call}. +@end deffn + +When dynamic linking is disabled or not supported on your system, +the above functions throw errors, but they are still available. + +Here is a small example that works on GNU/Linux: + +@smallexample +(define libc-obj (dynamic-link "libc.so")) +libc-obj +@result{} #<dynamic-object "libc.so"> +(dynamic-args-call 'rand libc-obj '()) +@result{} 269167349 +(dynamic-unlink libc-obj) +libc-obj +@result{} #<dynamic-object "libc.so" (unlinked)> +@end smallexample + +As you can see, after calling @code{dynamic-unlink} on a dynamically +linked library, it is marked as @samp{(unlinked)} and you are no longer +able to use it with @code{dynamic-call}, etc. Whether the library is +really removed from you program is system-dependent and will generally +not happen when some other parts of your program still use it. In the +example above, @code{libc} is almost certainly not removed from your +program because it is badly needed by almost everything. + +The functions to call a function from a dynamically linked library, +@code{dynamic-call} and @code{dynamic-args-call}, are not very powerful. +They are mostly intended to be used for calling specially written +initialization functions that will then add new primitives to Guile. +For example, we do not expect that you will dynamically link +@file{libX11} with @code{dynamic-link} and then construct a beautiful +graphical user interface just by using @code{dynamic-call} and +@code{dynamic-args-call}. Instead, the usual way would be to write a +special Guile<->X11 glue library that has intimate knowledge about both +Guile and X11 and does whatever is necessary to make them inter-operate +smoothly. This glue library could then be dynamically linked into a +vanilla Guile interpreter and activated by calling its initialization +function. That function would add all the new types and primitives to +the Guile interpreter that it has to offer. + +From this setup the next logical step is to integrate these glue +libraries into the module system of Guile so that you can load new +primitives into a running system just as you can load new Scheme code. + +There is, however, another possibility to get a more thorough access to +the functions contained in a dynamically linked library. Anthony Green +has written @file{libffi}, a library that implements a @dfn{foreign +function interface} for a number of different platforms. With it, you +can extend the Spartan functionality of @code{dynamic-call} and +@code{dynamic-args-call} considerably. There is glue code available in +the Guile contrib archive to make @file{libffi} accessible from Guile. + +@node Compiled Code Modules +@subsection Putting Compiled Code into Modules + +@c FIXME::martin: Change all gh_ references to their scm_ equivalents. + +The new primitives that you add to Guile with @code{gh_new_procedure} +or with any of the other mechanisms are normally placed into the same +module as all the other builtin procedures (like @code{display}). +However, it is also possible to put new primitives into their own +module. + +The mechanism for doing so is not very well thought out and is likely to +change when the module system of Guile itself is revised, but it is +simple and useful enough to document it as it stands. + +What @code{gh_new_procedure} and the functions used by the snarfer +really do is to add the new primitives to whatever module is the +@emph{current module} when they are called. This is analogous to the +way Scheme code is put into modules: the @code{define-module} expression +at the top of a Scheme source file creates a new module and makes it the +current module while the rest of the file is evaluated. The +@code{define} expressions in that file then add their new definitions to +this current module. + +Therefore, all we need to do is to make sure that the right module is +current when calling @code{gh_new_procedure} for our new primitives. +Unfortunately, there is not yet an easy way to access the module system +from C, so we are better off with a more indirect approach. Instead of +adding our primitives at initialization time we merely register with +Guile that we are ready to provide the contents of a certain module, +should it ever be needed. + +@deftypefun void scm_register_module_xxx (char *@var{name}, void (*@var{initfunc})(void)) +Register with Guile that @var{initfunc} will provide the contents of the +module @var{name}. + +The function @var{initfunc} should perform the usual initialization +actions for your new primitives, like calling @code{gh_new_procedure} or +including the file produced by the snarfer. When @var{initfunc} is +called, the current module is a newly created module with a name as +indicated by @var{name}. Each definition that is added to it will be +automatically exported. + +The string @var{name} indicates the hierachical name of the new module. +It should consist of the individual components of the module name +separated by single spaces. That is, the Scheme module name @code{(foo +bar)}, which is a list, should be written as @code{"foo bar"} for the +@var{name} parameter. + +You can call @code{scm_register_module_xxx} at any time, even before +Guile has been initialized. This might be useful when you want to put +the call to it in some initialization code that is magically called +before main, like constructors for global C++ objects. + +An example for @code{scm_register_module_xxx} appears in the next section. +@end deftypefun + +Now, instead of calling the initialization function at program startup, +you should simply call @code{scm_register_module_xxx} and pass it the +initialization function. When the named module is later requested by +Scheme code with @code{use-modules} for example, Guile will notice that +it knows how to create this module and will call the initialization +function at the right time in the right context. + +@node Dynamic Linking and Compiled Code Modules +@subsection Dynamic Linking and Compiled Code Modules + +The most interesting application of dynamically linked libraries is +probably to use them for providing @emph{compiled code modules} to +Scheme programs. As much fun as programming in Scheme is, every now and +then comes the need to write some low-level C stuff to make Scheme even +more fun. + +Not only can you put these new primitives into their own module (see the +previous section), you can even put them into a shared library that is +only then linked to your running Guile image when it is actually +needed. + +An example will hopefully make everything clear. Suppose we want to +make the Bessel functions of the C library available to Scheme in the +module @samp{(math bessel)}. First we need to write the appropriate +glue code to convert the arguments and return values of the functions +from Scheme to C and back. Additionally, we need a function that will +add them to the set of Guile primitives. Because this is just an +example, we will only implement this for the @code{j0} function, tho. + +@c FIXME::martin: Change all gh_ references to their scm_ equivalents. + +@smallexample +#include <math.h> +#include <guile/gh.h> + +SCM +j0_wrapper (SCM x) +@{ + return gh_double2scm (j0 (gh_scm2double (x))); +@} + +void +init_math_bessel () +@{ + gh_new_procedure1_0 ("j0", j0_wrapper); +@} +@end smallexample + +We can already try to bring this into action by manually calling the low +level functions for performing dynamic linking. The C source file needs +to be compiled into a shared library. Here is how to do it on +GNU/Linux, please refer to the @code{libtool} documentation for how to +create dynamically linkable libraries portably. + +@smallexample +gcc -shared -o libbessel.so -fPIC bessel.c +@end smallexample + +Now fire up Guile: + +@smalllisp +(define bessel-lib (dynamic-link "./libbessel.so")) +(dynamic-call "init_math_bessel" bessel-lib) +(j0 2) +@result{} 0.223890779141236 +@end smalllisp + +The filename @file{./libbessel.so} should be pointing to the shared +library produced with the @code{gcc} command above, of course. The +second line of the Guile interaction will call the +@code{init_math_bessel} function which in turn will register the C +function @code{j0_wrapper} with the Guile interpreter under the name +@code{j0}. This function becomes immediately available and we can call +it from Scheme. + +Fun, isn't it? But we are only half way there. This is what +@code{apropos} has to say about @code{j0}: + +@smallexample +(apropos 'j0) +@print{} the-root-module: j0 #<primitive-procedure j0> +@end smallexample + +As you can see, @code{j0} is contained in the root module, where all +the other Guile primitives like @code{display}, etc live. In general, +a primitive is put into whatever module is the @dfn{current module} at +the time @code{gh_new_procedure} is called. To put @code{j0} into its +own module named @samp{(math bessel)}, we need to make a call to +@code{scm_register_module_xxx}. Additionally, to have Guile perform +the dynamic linking automatically, we need to put @file{libbessel.so} +into a place where Guile can find it. The call to +@code{scm_register_module_xxx} should be contained in a specially +named @dfn{module init function}. Guile knows about this special name +and will call that function automatically after having linked in the +shared library. For our example, we add the following code to +@file{bessel.c}: + +@smallexample +void scm_init_math_bessel_module () +@{ + scm_register_module_xxx ("math bessel", init_math_bessel); +@} +@end smallexample + +The general pattern for the name of a module init function is: +@samp{scm_init_}, followed by the name of the module where the +individual hierarchical components are concatenated with underscores, +followed by @samp{_module}. It should call +@code{scm_register_module_xxx} with the correct module name and the +appropriate initialization function. When that initialization function +will be called, a newly created module with the right name will be the +@emph{current module} so that all definitions that the initialization +functions makes will end up in the correct module. + +After @file{libbessel.so} has been rebuild, we need to place the shared +library into the right place. When Guile tries to autoload the +@samp{(math bessel)} module, it looks not only for a file called +@file{math/bessel.scm} in its @code{%load-path}, but also for +@file{math/libbessel.so}. So all we need to do is to create a directory +called @file{math} somewhere in Guile's @code{%load-path} and place +@file{libbessel.so} there. Normally, the current directory @file{.} is +in the @code{%load-path}, so we just use that for this example. + +@smallexample +% mkdir maths +% cd maths +% ln -s ../libbessel.so . +% cd .. +% guile +guile> (use-modules (math bessel)) +guile> (j0 2) +0.223890779141236 +guile> (apropos 'j0) +@print{} bessel: j0 #<primitive-procedure j0> +@end smallexample + +That's it! + +Note that we used a symlink to make @file{libbessel.so} appear in the +right spot. This is probably not a bad idea in general. The +directories that the @file{%load-path} normally contains are supposed to +contain only architecture independent files. They are not really the +right place for a shared library. You might want to install the +libraries somewhere below @samp{exec_prefix} and then symlink to them +from the architecture independent directory. This will at least work on +heterogenous systems where the architecture dependent stuff resides in +the same place on all machines (which seems like a good idea to me +anyway). + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-options.texi b/doc/ref/scheme-options.texi new file mode 100644 index 000000000..d591008fe --- /dev/null +++ b/doc/ref/scheme-options.texi @@ -0,0 +1,398 @@ +@page +@node Options and Config +@chapter Runtime Options and Configuration + +Guile's behaviour can be modified by setting options. For example, is +the language that Guile accepts case sensitive, or should the debugger +automatically show a backtrace on error? + +Guile has two levels of interface for managing options: a low-level +control interface, and a user-level interface which allows the enabling +or disabling of options. + +Moreover, the options are classified in groups according to whether they +configure @emph{reading}, @emph{printing}, @emph{debugging} or +@emph{evaluating}. + +@menu +* General option interface:: +* Reader options:: +* Printing options:: +* Debugger options:: +* Evaluator options:: +* Evaluator trap options:: +* Examples of option use:: +* Install Config:: Installation and configuration data. +@end menu + +@node General option interface +@section General option interface + +We will use the expression @code{<group>} to represent @code{read}, +@code{print}, @code{debug} or @code{evaluator}. + +@subheading Low level + +@c NJFIXME +@deffn primitive <group>-options-interface +@deffnx primitive read-options-interface [SOME-INT] +@deffnx primitive print-options-interface [SOME-INT] +@deffnx primitive evaluator-traps-interface [SOME-INT] +@deffnx primitive read-options-interface [SOME-INT] +[FIXME: I have just taken the comments for C routine scm_options that +implements all of these. It needs to be presented better.] + +If scm_options is called without arguments, the current option setting +is returned. If the argument is an option setting, options are altered +and the old setting is returned. If the argument isn't a list, a list +of sublists is returned, where each sublist contains option name, value +and documentation string. +@end deffn + + +@subheading User level + +@c @deftp {Data type} scm_option +@c @code{scm_option} is used to represent run time options. It can be a +@c @emph{boolean} type, in which case the option will be set by the strings +@c @code{"yes"} and @code{"no"}. It can be a +@c @end deftp + +@c NJFIXME +@deffn procedure <group>-options [arg] +@deffnx procedure read-options [arg] +@deffnx procedure print-options [arg] +@deffnx procedure debug-options [arg] +@deffnx procedure traps [arg] +These functions list the options in their group. The optional argument +@var{arg} is a symbol which modifies the form in which the options are +presented. + +With no arguments, @code{<group>-options} returns the values of the +options in that particular group. If @var{arg} is @code{'help}, a +description of each option is given. If @var{arg} is @code{'full}, +programmers' options are also shown. + +@var{arg} can also be a list representing the state of all options. In +this case, the list contains single symbols (for enabled boolean +options) and symbols followed by values. +@end deffn +[FIXME: I don't think 'full is ever any different from 'help. What's +up?] + +@c NJFIXME +@deffn procedure <group>-enable option-symbol +@deffnx procedure read-enable option-symbol +@deffnx procedure print-enable option-symbol +@deffnx procedure debug-enable option-symbol +@deffnx procedure trap-enable option-symbol +These functions set the specified @var{option-symbol} in their options +group. They only work if the option is boolean, and throw an error +otherwise. +@end deffn + +@c NJFIXME +@deffn procedure <group>-disable option-symbol +@deffnx procedure read-disable option-symbol +@deffnx procedure print-disable option-symbol +@deffnx procedure debug-disable option-symbol +@deffnx procedure trap-disable option-symbol +These functions turn off the specified @var{option-symbol} in their +options group. They only work if the option is boolean, and throw an +error otherwise. +@end deffn + +@c NJFIXME +@deffn syntax <group>-set! option-symbol value +@deffnx syntax read-set! option-symbol value +@deffnx syntax print-set! option-symbol value +@deffnx syntax debug-set! option-symbol value +@deffnx syntax trap-set! option-symbol value +These functions set a non-boolean @var{option-symbol} to the specified +@var{value}. +@end deffn + + +@node Reader options +@section Reader options +@cindex options - read +@cindex read options + +Here is the list of reader options generated by typing +@code{(read-options 'full)} in Guile. You can also see the default +values. + +@smalllisp +keywords #f Style of keyword recognition: #f or 'prefix +case-insensitive no Convert symbols to lower case. +positions yes Record positions of source code expressions. +copy no Copy source code expressions. +@end smalllisp + +Notice that while Standard Scheme is case insensitive, to ease +translation of other Lisp dialects, notably Emacs Lisp, into Guile, +Guile is case-sensitive by default. + +To make Guile case insensitive, you can type + +@smalllisp +(read-enable 'case-insensitive) +@end smalllisp + +@node Printing options +@section Printing options + +Here is the list of print options generated by typing +@code{(print-options 'full)} in Guile. You can also see the default +values. + +@smallexample +source no Print closures with source. +closure-hook #f Hook for printing closures. +@end smallexample + + +@node Evaluator options +@section Evaluator options +These are the evaluator options with their default values, as they are +printed by typing @code{(eval-options 'full)} in Guile. + +@smallexample +stack 22000 Size of thread stacks (in machine words). +@end smallexample + +@node Evaluator trap options +@section Evaluator trap options +[FIXME: These flags, together with their corresponding handlers, are not +user level options. Probably this entire section should be moved to the +documentation about the low-level programmer debugging interface.] + +Here is the list of evaluator trap options generated by typing +@code{(traps 'full)} in Guile. You can also see the default values. + +@smallexample +exit-frame no Trap when exiting eval or apply. +apply-frame no Trap when entering apply. +enter-frame no Trap when eval enters new frame. +traps yes Enable evaluator traps. +@end smallexample + +@deffn apply-frame-handler key cont tailp +Called when a procedure is being applied. + +Called if: + +@itemize @bullet +@item +evaluator traps are enabled [traps interface], and +@item +either +@itemize @minus +@item +@code{apply-frame} is enabled [traps interface], or +@item +trace mode is on [debug-options interface], and the procedure being +called has the trace property enabled. +@end itemize +@end itemize + +If cheap traps are enabled [debug-options interface], @var{cont} is a +debug object, otherwise it is a restartable continuation. + +@var{tailp} is true if this is a tail call +@end deffn + +@deffn exit-frame-handler key cont retval +Called when a value is returned from a procedure. + +Called if: + +@itemize @bullet +@item +evaluator traps are enabled [traps interface], and +@item +either +@itemize @minus +@item + @code{exit-frame} is enabled [traps interface], or +@item +trace mode is on [debug-options interface], and the procedure being +called has the trace property enabled. +@end itemize +@end itemize + +If cheap traps are enabled [debug-options interface], @var{cont} is a +debug object, otherwise it is a restartable continuation. + +@var{retval} is the return value. +@end deffn + +@node Debugger options +@section Debugger options + +Here is the list of print options generated by typing +@code{(debug-options 'full)} in Guile. You can also see the default +values. + +@smallexample +stack 20000 Stack size limit (0 = no check). +debug yes Use the debugging evaluator. +backtrace no Show backtrace on error. +depth 20 Maximal length of printed backtrace. +maxdepth 1000 Maximal number of stored backtrace frames. +frames 3 Maximum number of tail-recursive frames in backtrace. +indent 10 Maximal indentation in backtrace. +backwards no Display backtrace in anti-chronological order. +procnames yes Record procedure names at definition. +trace no *Trace mode. +breakpoints no *Check for breakpoints. +cheap yes *Flyweight representation of the stack at traps. +@end smallexample + + +@node Examples of option use +@section Examples of option use + +Here is an example of a session in which some read and debug option +handling procedures are used. In this example, the user + +@enumerate +@item +Notices that the symbols @code{abc} and @code{aBc} are not the same +@item +Examines the @code{read-options}, and sees that @code{case-insensitive} +is set to ``no''. +@item +Enables @code{case-insensitive} +@item +Verifies that now @code{aBc} and @code{abc} are the same +@item +Disables @code{case-insensitive} and enables debugging @code{backtrace} +@item +Reproduces the error of displaying @code{aBc} with backtracing enabled +[FIXME: this last example is lame because there is no depth in the +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 +"hello" +guile> aBc +ERROR: In expression aBc: +ERROR: Unbound variable: aBc +ABORT: (misc-error) + +Type "(backtrace)" to get more information. +guile> (read-options 'help) +keywords #f Style of keyword recognition: #f or 'prefix +case-insensitive no Convert symbols to lower case. +positions yes Record positions of source code expressions. +copy no Copy source code expressions. +guile> (debug-options 'help) +stack 20000 Stack size limit (0 = no check). +debug yes Use the debugging evaluator. +backtrace no Show backtrace on error. +depth 20 Maximal length of printed backtrace. +maxdepth 1000 Maximal number of stored backtrace frames. +frames 3 Maximum number of tail-recursive frames in backtrace. +indent 10 Maximal indentation in backtrace. +backwards no Display backtrace in anti-chronological order. +procnames yes Record procedure names at definition. +trace no *Trace mode. +breakpoints no *Check for breakpoints. +cheap yes *Flyweight representation of the stack at traps. +guile> (read-enable 'case-insensitive) +(keywords #f case-insensitive positions) +guile> aBc +"hello" +guile> (read-disable 'case-insensitive) +(keywords #f positions) +guile> (debug-enable 'backtrace) +(stack 20000 debug backtrace depth 20 maxdepth 1000 frames 3 indent 10 procnames cheap) +guile> aBc + +Backtrace: +0* aBc + +ERROR: In expression aBc: +ERROR: Unbound variable: aBc +ABORT: (misc-error) +guile> +@end smalllisp + + +@node Install Config +@section Installation and Configuration Data + +It is often useful to have site-specific information about the current +Guile installation. This chapter describes how to find out about +Guile's configuration at run time. + +@deffn primitive version +@deffnx primitive major-version +@deffnx primitive minor-version +@deffnx primitive micro-version +Return a string describing Guile's version number, or its major or minor +version numbers, respectively. + +@lisp +(version) @result{} "1.6.5" +(major-version) @result{} "1" +(minor-version) @result{} "6" +(micro-version) @result{} "5" +@end lisp +@end deffn + +@c NJFIXME not in libguile! +@deffn primitive libguile-config-stamp +Return a string describing the date on which @code{libguile} was +configured. This is used to determine whether the Guile core +interpreter and the ice-9 runtime have grown out of date with one +another. +@end deffn + +@deffn primitive %package-data-dir +Return the name of the directory where Scheme packages, modules and +libraries are kept. On most Unix systems, this will be +@samp{/usr/local/share/guile}. +@end deffn + +@deffn primitive %library-dir +Return the directory where the Guile Scheme library files are installed. +E.g., may return "/usr/share/guile/1.3.5". +@end deffn + +@deffn primitive %site-dir +Return the directory where the Guile site files are installed. +E.g., may return "/usr/share/guile/site". +@end deffn + +@deffn primitive parse-path path [tail] +Parse @var{path}, which is expected to be a colon-separated +string, into a list and return the resulting list with +@var{tail} appended. If @var{path} is @code{#f}, @var{tail} +is returned. +@end deffn + +@deffn primitive search-path path filename [extensions] +Search @var{path} for a directory containing a file named +@var{filename}. The file must be readable, and not a directory. +If we find one, return its full filename; otherwise, return +@code{#f}. If @var{filename} is absolute, return it unchanged. +If given, @var{extensions} is a list of strings; for each +directory in @var{path}, we search for @var{filename} +concatenated with each @var{extension}. +@end deffn + +@defvar %load-path +Return the list of directories which should be searched for Scheme +modules and libraries. +@end defvar + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-procedures.texi b/doc/ref/scheme-procedures.texi new file mode 100644 index 000000000..b6886a325 --- /dev/null +++ b/doc/ref/scheme-procedures.texi @@ -0,0 +1,778 @@ +@page +@node Procedures and Macros +@chapter Procedures and Macros + +@menu +* Lambda:: Basic procedure creation using lambda. +* Optional Arguments:: Handling keyword, optional and rest arguments. +* Procedure Properties:: Procedure properties and metainformation. +* Procedures with Setters:: Procedures with setters. +* Macros:: Lisp style macro definitions. +* Syntax Rules:: Support for R5RS @code{syntax-rules}. +* Syntax Case:: Support for the @code{syntax-case} system. +* Internal Macros:: Guile's internal representation. +@end menu + + +@node Lambda +@section Lambda: Basic Procedure Creation + +@c FIXME::martin: Review me! + +A @code{lambda} expression evaluates to a procedure. The environment +which is in effect when a @code{lambda} expression is evaluated is +enclosed in the newly created procedure, this is referred to as a +@dfn{closure} (@pxref{About Closure}). + +When a procedure created by @code{lambda} is called with some actual +arguments, the environment enclosed in the procedure is extended by +binding the variables named in the formal argument list to new locations +and storing the actual arguments into these locations. Then the body of +the @code{lambda} expression is evaluation sequentially. The result of +the last expression in the procedure body is then the result of the +procedure invocation. + +The following examples will show how procedures can be created using +@code{lambda}, and what you can do with these procedures. + +@lisp +(lambda (x) (+ x x)) @result{} @r{a procedure} +((lambda (x) (+ x x)) 4) @result{} 8 +@end lisp + +The fact that the environment in effect when creating a procedure is +enclosed in the procedure is shown with this example: + +@lisp +(define add4 + (let ((x 4)) + (lambda (y) (+ x y)))) +(add4 6) @result{} 10 +@end lisp + + +@deffn syntax lambda formals body +@var{formals} should be a formal argument list as described in the +following table. + +@table @code +@item (@var{variable1} @dots{}) +The procedure takes a fixed number of arguments; when the procedure is +called, the arguments will be stored into the newly created location for +the formal variables. +@item @var{variable} +The procedure takes any number of arguments; when the procedure is +called, the sequence of actual arguments will converted into a list and +stored into the newly created location for the formal variable. +@item (@var{variable1} @dots{} @var{variablen} . @var{variablen+1}) +If a space-delimited period precedes the last variable, then the +procedure takes @var{n} or more variablesm where @var{n} is the number +of formal arguments before the period. There must be at least one +argument before the period. The first @var{n} actual arguments will be +stored into the newly allocated locations for the first @var{n} formal +arguments and the sequence of the remaining actual arguments is +converted into a list and the stored into the location for the last +formal argument. If there are exactly @var{n} actual arguments, the +empty list is stored into the location of the last formal argument. +@end table + +@var{body} is a sequence of Scheme expressions which are evaluated in +order when the procedure is invoked. +@end deffn + + +@node Optional Arguments +@section Optional Arguments + +@c FIXME::martin: Review me! + +Scheme procedures, as defined in R5RS, can wither handle a fixed number +of actual arguments, or a fixed number of actual arguments followed by +arbitrarily many additional arguments. Writing procedures of variable +arity can be useful, but unfortunately, the syntactic means for handling +argument lists of varying length is a bit inconvenient. It is possible +to give names to the fixed number of argument, but the remaining +(optional) arguments can be only referenced as a list of values +(@pxref{Lambda}). + +Guile comes with the module @code{(ice-9 optargs)}, which makes using +optional arguments much more convenient. In addition, this module +provides syntax for handling keywords in argument lists +(@pxref{Keywords}). + +Before using any of the procedures or macros defined in this section, +you have to load the module @code{(ice-9 optargs)} with the statement: + +@lisp +(use-modules (ice-9 optargs)) +@end lisp + +@menu +* let-optional Reference:: Locally binding optional arguments. +* let-keywords Reference:: Locally binding keywords arguments. +* lambda* Reference:: Creating advanced argument handling procedures. +* define* Reference:: Defining procedures and macros. +@end menu + + +@node let-optional Reference +@subsection let-optional Reference + +@c FIXME::martin: Review me! + +The syntax @code{let-optional} and @code{let-optional*} are for +destructuring rest argument lists and giving names to the various list +elements. @code{let-optional} binds all variables simultaneously, while +@code{let-optional*} binds them sequentially, consistent with @code{let} +and @code{let*} (@pxref{Local Bindings}). + +@deffn {libary syntax} let-optional rest-arg (binding @dots{}) expr @dots{} +@deffnx {library syntax} let-optional* rest-arg (binding @dots{}) expr @dots{} +These two macros give you an optional argument interface that is very +@dfn{Schemey} and introduces no fancy syntax. They are compatible with +the scsh macros of the same name, but are slightly extended. Each of +@var{binding} may be of one of the forms @var{var} or @code{(@var{var} +@var{default-value})}. @var{rest-arg} should be the rest-argument of the +procedures these are used from. The items in @var{rest-arg} are +sequentially bound to the variable names are given. When @var{rest-arg} +runs out, the remaining vars are bound either to the default values or +left unbound if no default value was specified. @var{rest-arg} remains +bound to whatever may have been left of @var{rest-arg}. + +After binding the variables, the expressions @var{expr} @dots{} are +evaluated in order. +@end deffn + + +@node let-keywords Reference +@subsection let-keywords Reference + +@c FIXME::martin: Review me! + +@code{let-keywords} and @code{let-keywords*} are used for extracting +values from argument lists which use keywords instead of argument +position for binding local variables to argument values. + +@code{let-keywords} binds all variables simultaneously, while +@code{let-keywords*} binds them sequentially, consistent with @code{let} +and @code{let*} (@pxref{Local Bindings}). + +@deffn {library syntax} let-keywords rest-arg allow-other-keys? (binding @dots{}) expr @dots{} +@deffnx {library syntax} let-keywords rest-arg allow-other-keys? (binding @dots{}) expr @dots{} +These macros pick out keyword arguments from @var{rest-arg}, but do not +modify it. This is consistent at least with Common Lisp, which +duplicates keyword arguments in the rest argument. More explanation of what +keyword arguments in a lambda list look like can be found below in +the documentation for @code{lambda*} + (@pxref{lambda* Reference}). @var{binding}s can have the same form as +for @code{let-optional}. If @var{allow-other-keys?} is false, an error +will be thrown if anything that looks like a keyword argument but does +not match a known keyword parameter will result in an error. + +After binding the variables, the expressions @var{expr} @dots{} are +evaluated in order. +@end deffn + + +@node lambda* Reference +@subsection lambda* Reference + +@c FIXME::martin: Review me! + +When using optional and keyword argument lists, using @code{lambda} for +creating procedures and using @code{let-optional} or @code{let-keywords} +is a bit lengthy. Therefore, @code{lambda*} is provided, which combines +the features of those macros into a single convenient syntax. + +For quick reference, here is the syntax of the formal argument list for +@code{lambda*} (brackets are used to indicate grouping only): + +@example +ext-param-list ::= [identifier]* [#:optional [ext-var-decl]+]? + [#:key [ext-var-decl]+ [#:allow-other-keys]?]? + [[#:rest identifier]|[. identifier]]? + +ext-var-decl ::= identifier | ( identifier expression ) +@end example + +The characters `*', `+' and `?' are not to be taken literally; they mean +respectively, zero or more occurences, one or more occurences, and one +or zero occurences. + +@deffn {library syntax} lambda* formals body +@code{lambda*} creates a procedure that takes optional arguments. These +are specified by putting them inside brackets at the end of the +paramater list, but before any dotted rest argument. For example, + +@lisp +(lambda* (a b #:optional c d . e) '()) +@end lisp + +creates a procedure with fixed arguments @var{a} and @var{b}, optional +arguments @var{c} and @var{d}, and rest argument @var{e}. If the +optional arguments are omitted in a call, the variables for them are +unbound in the procedure. This can be checked with the @code{bound?} +macro (documented below). + +@code{lambda*} can also take keyword arguments. For example, a procedure +defined like this: + +@lisp +(lambda* (#:key xyzzy larch) '()) +@end lisp + +can be called with any of the argument lists @code{(#:xyzzy 11)} +@code{(#:larch 13)} @code{(#:larch 42 #:xyzzy 19)} @code{()}. Whichever +arguments are given as keywords are bound to values. + +Optional and keyword arguments can also be given default values +which they take on when they are not present in a call, by giving a +two-item list in place of an optional argument, for example in: + +@lisp +(lambda* (foo #:optional (bar 42) #:key (baz 73)) + (list foo bar baz)) +@end lisp + +@var{foo} is a fixed argument, @var{bar} is an optional argument with +default value 42, and baz is a keyword argument with default value 73. +Default value expressions are not evaluated unless they are needed and +until the procedure is called. + +@code{lambda*} also supports two more special parameter list keywords. + +@code{lambda*}-defined procedures now throw an error by default if a +keyword other than one of those specified is found in the actual +passed arguments. However, specifying @code{#:allow-other-keys} +immediately after the keyword argument declarations restores the +previous behavior of ignoring unknown keywords. @code{lambda*} also now +guarantees that if the same keyword is passed more than once, the +last one passed is the one that takes effect. For example, + +@lisp +((lambda* (#:key (heads 0) (tails 0)) (display (list heads tails))) + #:heads 37 #:tails 42 #:heads 99) +@end lisp + +would result in (99 47) being displayed. + +@code{#:rest} is also now provided as a synonym for the dotted syntax +rest argument. The argument lists @code{(a . b)} and @code{(a #:rest b)} +are equivalent in all respects to @code{lambda*}. This is provided for +more similarity to DSSSL, MIT-Scheme and Kawa among others, as well as +for refugees from other Lisp dialects. +@end deffn + +@deffn {library syntax} bound? variable +Check if a variable is bound in the current environment. + +The procedure @code{defined?} doesn't quite cut it as it stands, since +it only checks bindings in the top-level environment, not those in local +scope only. +@end deffn + + +@node define* Reference +@subsection define* Reference + +@c FIXME::martin: Review me! + +Just like @code{define} has a shorthand notation for defining procedures +(@pxref{Lambda Alternatives}), @code{define*} is provided as an +abbreviation of the combination of @code{define} and @code{lambda*}. + +@code{define*-public} is the @code{lambda*} version of +@code{define-public}; @code{defmacro*} and @code{defmacro*-public} exist +for defining macros with the improved argument list handling +possibilities. The @code{-public} versions not only define the +procedures/macros, but also export them from the current module. + +@deffn {library syntax} define* formals body +@deffnx {library syntax} define*-public formals body +@code{define*} and @code{define*-public} support optional arguments with +a similar syntax to @code{lambda*}. They also support arbitrary-depth +currying, just like Guile's define. Some examples: + +@lisp +(define* (x y #:optional a (z 3) #:key w . u) + (display (list y z u))) +@end lisp +defines a procedure @code{x} with a fixed argument @var{y}, an optional +agument @var{a}, another optional argument @var{z} with default value 3, +a keyword argument @var{w}, and a rest argument @var{u}. + +@lisp +(define-public* ((foo #:optional bar) #:optional baz) '()) +@end lisp + +This illustrates currying. A procedure @code{foo} is defined, which, +when called with an optional argument @var{bar}, returns a procedure +that takes an optional argument @var{baz}. + +Of course, @code{define*[-public]} also supports @code{#:rest} and +@code{#:allow-other-keys} in the same way as @code{lambda*}. +@end deffn + +@deffn {library syntax} defmacro* name formals body +@deffnx {library syntax} defmacro*-public name formals body +These are just like @code{defmacro} and @code{defmacro-public} except that they +take @code{lambda*}-style extended paramter lists, where @code{#:optional}, +@code{#:key}, @code{#:allow-other-keys} and @code{#:rest} are allowed with the usual +semantics. Here is an example of a macro with an optional argument: + +@lisp +(defmacro* transmorgify (a #:optional b) + (a 1)) +@end lisp +@end deffn + + +@node Procedure Properties +@section Procedure Properties and Metainformation + +@c FIXME::martin: Review me! + +Procedures always have attached the environment in which they were +created and information about how to apply them to actual arguments. In +addition to that, properties and metainformation can be stored with +procedures. The procedures in this section can be used to test whether +a given procedure satisfies a condition; and to access and set a +procedure's property. + +The first group of procedures are predicates to test whether a Scheme +object is a procedure, or a special procedure, respectively. +@code{procedure?} is the most general predicates, it returns @code{#t} +for any kind of procedure. @code{closure?} does not return @code{#t} +for primitive procedures, and @code{thunk?} only returns @code{#t} for +procedures which do not accept any arguments. + +@rnindex procedure? +@deffn primitive procedure? obj +Return @code{#t} if @var{obj} is a procedure. +@end deffn + +@deffn primitive closure? obj +Return @code{#t} if @var{obj} is a closure. +@end deffn + +@deffn primitive thunk? obj +Return @code{#t} if @var{obj} is a thunk. +@end deffn + +@c FIXME::martin: Is that true? +@cindex procedure properties +Procedure properties are general properties to be attached to +procedures. These can be the name of a procedure or other relevant +information, such as debug hints. + +@deffn primitive procedure-properties proc +Return @var{obj}'s property list. +@end deffn + +@deffn primitive procedure-property p k +Return the property of @var{obj} with name @var{key}. +@end deffn + +@deffn primitive set-procedure-properties! proc new_val +Set @var{obj}'s property list to @var{alist}. +@end deffn + +@deffn primitive set-procedure-property! p k v +In @var{obj}'s property list, set the property named @var{key} to +@var{value}. +@end deffn + +@cindex procedure documentation +Documentation for a procedure can be accessed with the procedure +@code{procedure-documentation}. + +@deffn primitive procedure-documentation proc +Return the documentation string associated with @code{proc}. By +convention, if a procedure contains more than one expression and the +first expression is a string constant, that string is assumed to contain +documentation for that procedure. +@end deffn + +@cindex source properties +@c FIXME::martin: Is the following true? +Source properties are properties which are related to the source code of +a procedure, such as the line and column numbers, the file name etc. + +@deffn primitive set-source-properties! obj plist +Install the association list @var{plist} as the source property +list for @var{obj}. +@end deffn + +@deffn primitive set-source-property! obj key datum +Set the source property of object @var{obj}, which is specified by +@var{key} to @var{datum}. Normally, the key will be a symbol. +@end deffn + +@deffn primitive source-properties obj +Return the source property association list of @var{obj}. +@end deffn + + +@deffn primitive source-property obj key +Return the source property specified by @var{key} from +@var{obj}'s source property list. +@end deffn + + +@node Procedures with Setters +@section Procedures with Setters + +@c FIXME::martin: Review me! + +@c FIXME::martin: Document `operator struct'. + +@cindex procedure with setter +@cindex setter +A @dfn{procedure with setter} is a special kind of procedure which +normally behaves like any accesor procedure, that is a procedure which +accesses a data structure. The difference is that this kind of +procedure has a so-called @dfn{setter} attached, which is a procedure +for storing something into a data structure. + +Procedures with setters are treated specially when the procedure appears +in the special form @code{set!} (REFFIXME). How it works is best shown +by example. + +Suppose we have a procedure called @code{foo-ref}, which accepts two +arguments, a value of type @code{foo} and an integer. The procedure +returns the value stored at the given index in the @code{foo} object. +Let @code{f} be a variable containing such a @code{foo} data +structure.@footnote{Working definitions would be: +@lisp +(define foo-ref vector-ref) +(define foo-set! vector-set!) +(define f (make-vector 2 #f)) +@end lisp +} + +@lisp +(foo-ref f 0) @result{} bar +(foo-ref f 1) @result{} braz +@end lisp + +Also suppose that a corresponding setter procedure called +@code{foo-set!} does exist. + +@lisp +(foo-set! f 0 'bla) +(foo-ref f 0) @result{} bla +@end lisp + +Now we could create a new procedure called @code{foo}, which is a +procedure with setter, by calling @code{make-procedure-with-setter} with +the accessor and setter procedures @code{foo-ref} and @code{foo-set!}. +Let us call this new procedure @code{foo}. + +@lisp +(define foo (make-procedure-with-setter foo-ref foo-set!)) +@end lisp + +@code{foo} can from now an be used to either read from the data +structure stored in @code{f}, or to write into the structure. + +@lisp +(set! (foo f 0) 'dum) +(foo f 0) @result{} dum +@end lisp + +@deffn primitive make-procedure-with-setter procedure setter +Create a new procedure which behaves like @var{procedure}, but +with the associated setter @var{setter}. +@end deffn + +@deffn primitive procedure-with-setter? obj +Return @code{#t} if @var{obj} is a procedure with an +associated setter procedure. +@end deffn + +@deffn primitive procedure proc +Return the procedure of @var{proc}, which must be either a +procedure with setter, or an operator struct. +@end deffn + +@deffn primitive setter proc +Return the setter of @var{proc}, which must be either a procedure with +setter or an operator struct. +@end deffn + + +@node Macros +@section Lisp Style Macro Definitions + +@cindex macros +@cindex transformation +Macros are objects which cause the expression that they appear in to be +transformed in some way @emph{before} being evaluated. In expressions +that are intended for macro transformation, the identifier that names +the relevant macro must appear as the first element, like this: + +@lisp +(@var{macro-name} @var{macro-args} @dots{}) +@end lisp + +In Lisp-like languages, the traditional way to define macros is very +similar to procedure definitions. The key differences are that the +macro definition body should return a list that describes the +transformed expression, and that the definition is marked as a macro +definition (rather than a procedure definition) by the use of a +different definition keyword: in Lisp, @code{defmacro} rather than +@code{defun}, and in Scheme, @code{define-macro} rather than +@code{define}. + +@fnindex defmacro +@fnindex define-macro +Guile supports this style of macro definition using both @code{defmacro} +and @code{define-macro}. The only difference between them is how the +macro name and arguments are grouped together in the definition: + +@lisp +(defmacro @var{name} (@var{args} @dots{}) @var{body} @dots{}) +@end lisp + +@noindent +is the same as + +@lisp +(define-macro (@var{name} @var{args} @dots{}) @var{body} @dots{}) +@end lisp + +@noindent +The difference is analogous to the corresponding difference between +Lisp's @code{defun} and Scheme's @code{define}. + +@code{false-if-exception}, from the @file{boot-9.scm} file in the Guile +distribution, is a good example of macro definition using +@code{defmacro}: + +@lisp +(defmacro false-if-exception (expr) + `(catch #t + (lambda () ,expr) + (lambda args #f))) +@end lisp + +@noindent +The effect of this definition is that expressions beginning with the +identifier @code{false-if-exception} are automatically transformed into +a @code{catch} expression following the macro definition specification. +For example: + +@lisp +(false-if-exception (open-input-file "may-not-exist")) +@equiv{} +(catch #t + (lambda () (open-input-file "may-not-exist")) + (lambda args #f)) +@end lisp + + +@node Syntax Rules +@section The R5RS @code{syntax-rules} System + +R5RS defines an alternative system for macro and syntax transformations +using the keywords @code{define-syntax}, @code{let-syntax}, +@code{letrec-syntax} and @code{syntax-rules}. + +The main difference between the R5RS system and the traditional macros +of the previous section is how the transformation is specified. In +R5RS, rather than permitting a macro definition to return an arbitrary +expression, the transformation is specified in a pattern language that + +@itemize @bullet +@item +does not require complicated quoting and extraction of components of the +source expression using @code{caddr} etc. + +@item +is designed such that the bindings associated with identifiers in the +transformed expression are well defined, and such that it is impossible +for the transformed expression to construct new identifiers. +@end itemize + +@noindent +The last point is commonly referred to as being @dfn{hygienic}: the R5RS +@code{syntax-case} system provides @dfn{hygienic macros}. + +For example, the R5RS pattern language for the @code{false-if-exception} +example of the previous section looks like this: + +@lisp +(syntax-rules () + ((_ expr) + (catch #t + (lambda () expr) + (lambda args #f)))) +@end lisp + +In Guile, the @code{syntax-rules} system is provided by the @code{(ice-9 +syncase)} module. To make these facilities available in your code, +include the expression @code{(use-modules (ice-9 syncase))} or +@code{(use-syntax (ice-9 syncase))} (@pxref{Using Guile Modules}) +before the first usage of @code{define-syntax} etc. If you are writing +a Scheme module, you can alternatively use one of the keywords +@code{#:use-module} and @code{#:use-syntax} in your @code{define-module} +declaration (@pxref{Creating Guile Modules}). + +@menu +* Pattern Language:: The @code{syntax-rules} pattern language. +* Define-Syntax:: Top level syntax definitions. +* Let-Syntax:: Local syntax definitions. +@end menu + + +@node Pattern Language +@subsection The @code{syntax-rules} Pattern Language + + +@node Define-Syntax +@subsection Top Level Syntax Definitions + +define-syntax: The gist is + + (define-syntax <keyword> <transformer-spec>) + +makes the <keyword> into a macro so that + + (<keyword> ...) + +expands at _compile_ or _read_ time (i.e. before any +evaluation begins) into some expression that is +given by the <transformer-spec>. + + +@node Let-Syntax +@subsection Local Syntax Definitions + + +@node Syntax Case +@section Support for the @code{syntax-case} System + + + +@node Internal Macros +@section Internal Representation of Macros and Syntax + +Internally, Guile uses three different flavours of macros. The three +flavours are called @dfn{acro} (or @dfn{syntax}), @dfn{macro} and +@dfn{mmacro}. + +Given the expression + +@lisp +(foo @dots{}) +@end lisp + +@noindent +with @code{foo} being some flavour of macro, one of the following things +will happen when the expression is evaluated. + +@itemize @bullet +@item +When @code{foo} has been defined to be an @dfn{acro}, the procedure used +in the acro definition of @code{foo} is passed the whole expression and +the current lexical environment, and whatever that procedure returns is +the value of evaluating the expression. You can think of this a +procedure that receives its argument as an unevaluated expression. + +@item +When @code{foo} has been defined to be a @dfn{macro}, the procedure used +in the macro definition of @code{foo} is passed the whole expression and +the current lexical environment, and whatever that procedure returns is +evaluated again. That is, the procedure should return a valid Scheme +expression. + +@item +When @code{foo} has been defined to be a @dfn{mmacro}, the procedure +used in the mmacro definition of `foo' is passed the whole expression +and the current lexical environment, and whatever that procedure returns +replaces the original expression. Evaluation then starts over from the +new expression that has just been returned. +@end itemize + +The key difference between a @dfn{macro} and a @dfn{mmacro} is that the +expression returned by a @dfn{mmacro} procedure is remembered (or +@dfn{memoized}) so that the expansion does not need to be done again +next time the containing code is evaluated. + +The primitives @code{procedure->syntax}, @code{procedure->macro} and +@code{procedure->memoizing-macro} are used to construct acros, macros +and mmacros respectively. However, if you do not have a very special +reason to use one of these primitives, you should avoid them: they are +very specific to Guile's current implementation and therefore likely to +change. Use @code{defmacro}, @code{define-macro} (@pxref{Macros}) or +@code{define-syntax} (@pxref{Syntax Rules}) instead. (In low level +terms, @code{defmacro}, @code{define-macro} and @code{define-syntax} are +all implemented as mmacros.) + +@deffn primitive procedure->syntax code +Return a macro which, when a symbol defined to this value appears as the +first symbol in an expression, returns the result of applying @var{code} +to the expression and the environment. +@end deffn + +@deffn primitive procedure->macro code +Return a macro which, when a symbol defined to this value appears as the +first symbol in an expression, evaluates the result of applying +@var{code} to the expression and the environment. For example: + +@lisp +(define trace + (procedure->macro + (lambda (x env) + `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x)))))) + +(trace @i{foo}) +@equiv{} +(set! @i{foo} (tracef @i{foo} '@i{foo})). +@end lisp +@end deffn + +@deffn primitive procedure->memoizing-macro code +Return a macro which, when a symbol defined to this value appears as the +first symbol in an expression, evaluates the result of applying +@var{code} to the expression and the environment. +@code{procedure->memoizing-macro} is the same as +@code{procedure->macro}, except that the expression returned by +@var{code} replaces the original macro expression in the memoized form +of the containing code. +@end deffn + +In the following primitives, @dfn{acro} flavour macros are referred to +as @dfn{syntax transformers}. + +@deffn primitive macro? obj +Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a +syntax transformer. +@end deffn + +@deffn primitive macro-type m +Return one of the symbols @code{syntax}, @code{macro} or +@code{macro!}, depending on whether @var{m} is a syntax +transformer, a regular macro, or a memoizing macro, +respectively. If @var{m} is not a macro, @code{#f} is +returned. +@end deffn + +@deffn primitive macro-name m +Return the name of the macro @var{m}. +@end deffn + +@deffn primitive macro-transformer m +Return the transformer of the macro @var{m}. +@end deffn + +@deffn primitive cons-source xorig x y +Create and return a new pair whose car and cdr are @var{x} and @var{y}. +Any source properties associated with @var{xorig} are also associated +with the new pair. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-reading.texi b/doc/ref/scheme-reading.texi new file mode 100644 index 000000000..eea049d2d --- /dev/null +++ b/doc/ref/scheme-reading.texi @@ -0,0 +1,27 @@ +@page +@node Further Reading +@chapter Further Reading + +@itemize @bullet +@item +Dorai Sitaram's online Scheme tutorial, @dfn{Teach Yourself Scheme in +Fixnum Days}, at +@url{http://www.cs.rice.edu/~dorai/t-y-scheme/t-y-scheme.html}. +Includes a nice explanation of continuations. + +@item +@url{http://wombat.doc.ic.ac.uk/foldoc/}. + +@item +The complete text of @dfn{Structure and Interpretation of Computer +Programs}, the classic introduction to computer science and Scheme by +Hal Abelson, Jerry Sussman and Julie Sussman, is now available online at +@url{http://mitpress.mit.edu/sicp/sicp.html}. This site also provides +teaching materials related to the book, and all the source code used in +the book, in a form suitable for loading and running. +@end itemize + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-scheduling.texi b/doc/ref/scheme-scheduling.texi new file mode 100644 index 000000000..e2cdd3d2a --- /dev/null +++ b/doc/ref/scheme-scheduling.texi @@ -0,0 +1,435 @@ +@page +@node Scheduling +@chapter 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. +* Dynamic Roots:: Root frames of execution. +* Threads:: Multiple threads of execution. +* Fluids:: Dynamically scoped variables. +@end menu + + +@node Arbiters +@section Arbiters + +@cindex arbiters + +@c FIXME::martin: Review me! + +Arbiters are synchronization objects. They are created with +@code{make-arbiter}. Two or more threads can synchronize on an arbiter +by trying to lock it using @code{try-arbiter}. This call will succeed +if no other thread has called @code{try-arbiter} on the arbiter yet, +otherwise it will fail and return @code{#f}. Once an arbiter is +successfully locked, it cannot be locked by another thread until the +thread holding the arbiter calls @code{release-arbiter} to unlock it. + +@deffn primitive make-arbiter name +Return an object of type arbiter and name @var{name}. Its +state is initially unlocked. Arbiters are a way to achieve +process synchronization. +@end deffn + +@deffn primitive try-arbiter arb +Return @code{#t} and lock the arbiter @var{arb} if the arbiter +was unlocked. Otherwise, return @code{#f}. +@end deffn + +@deffn primitive release-arbiter arb +Return @code{#t} and unlock the arbiter @var{arb} if the +arbiter was locked. Otherwise, return @code{#f}. +@end deffn + + +@node Asyncs +@section Asyncs + +@cindex asyncs +@cindex system asyncs + +@c FIXME::martin: Review me! + +An async is a pair of one thunk (a parameterless procedure) and a mark. +Setting the mark on an async guarantees that the thunk will be executed +somewhen in the future (@dfn{asynchronously}). Setting the mark more +than once is satisfied by one execution of the thunk. + +Guile supports two types of asyncs: Normal asyncs and system asyncs. +They differ in that marked system asyncs are executed implicitly as soon +as possible, whereas normal asyncs have to be invoked explicitly. +System asyncs are held in an internal data structure and are maintained +by Guile. + +Normal asyncs are created with @code{async}, system asyncs with +@code{system-async}. They are marked with @code{async-mark} or +@code{system-async-mark}, respectively. + +@deffn primitive async thunk +Create a new async for the procedure @var{thunk}. +@end deffn + +@deffn primitive system-async thunk +Create a new async for the procedure @var{thunk}. Also +add it to the system's list of active async objects. +@end deffn + +@deffn primitive async-mark a +Mark the async @var{a} for future execution. +@end deffn + +@deffn primitive system-async-mark a +Mark the async @var{a} for future execution. +@end deffn + +As already mentioned above, system asyncs are executed automatically. +Normal asyncs have to be explicitly invoked by storing one or more of +them into a list and passing them to @code{run-asyncs}. + +@deffn primitive run-asyncs list_of_a +Execute all thunks from the asyncs of the list @var{list_of_a}. +@end deffn + +Automatic invocation of system asyncs can be temporarily disabled by +calling @code{mask-signals} and @code{unmask-signals}. Setting the mark +while async execution is disabled will nevertheless cause the async to +run once execution is enabled again. Please note that calls to these +procedures should always be paired, and they must not be nested, e.g. no +@code{mask-signals} is allowed if another one is still active. + +@deffn primitive mask-signals +Mask signals. The returned value is not specified. +@end deffn + +@deffn primitive unmask-signals +Unmask signals. The returned value is not specified. +@end deffn + +@c FIXME::martin: Find an example for usage of `noop'. What is that +@c procedure for anyway? + +@deffn primitive noop . args +Do nothing. When called without arguments, return @code{#f}, +otherwise return the first argument. +@end deffn + + +@node Dynamic Roots +@section Dynamic Roots +@cindex dynamic roots + +A @dfn{dynamic root} is a root frame of Scheme evaluation. +The top-level repl, for example, is an instance of a dynamic root. + +Each dynamic root has its own chain of dynamic-wind information. Each +has its own set of continuations, jump-buffers, and pending CATCH +statements which are inaccessible from the dynamic scope of any +other dynamic root. + +In a thread-based system, each thread has its own dynamic root. Therefore, +continuations created by one thread may not be invoked by another. + +Even in a single-threaded system, it is sometimes useful to create a new +dynamic root. For example, if you want to apply a procedure, but to +not allow that procedure to capture the current continuation, calling +the procedure under a new dynamic root will do the job. + +@deffn primitive call-with-dynamic-root thunk handler +Evaluate @code{(thunk)} in a new dynamic context, returning its value. + +If an error occurs during evaluation, apply @var{handler} to the +arguments to the throw, just as @code{throw} would. If this happens, +@var{handler} is called outside the scope of the new root -- it is +called in the same dynamic context in which +@code{call-with-dynamic-root} was evaluated. + +If @var{thunk} captures a continuation, the continuation is rooted at +the call to @var{thunk}. In particular, the call to +@code{call-with-dynamic-root} is not captured. Therefore, +@code{call-with-dynamic-root} always returns at most one time. + +Before calling @var{thunk}, the dynamic-wind chain is un-wound back to +the root and a new chain started for @var{thunk}. Therefore, this call +may not do what you expect: + +@lisp +;; Almost certainly a bug: +(with-output-to-port + some-port + + (lambda () + (call-with-dynamic-root + (lambda () + (display 'fnord) + (newline)) + (lambda (errcode) errcode)))) +@end lisp + +The problem is, on what port will @samp{fnord} be displayed? You +might expect that because of the @code{with-output-to-port} that +it will be displayed on the port bound to @code{some-port}. But it +probably won't -- before evaluating the thunk, dynamic winds are +unwound, including those created by @code{with-output-to-port}. +So, the standard output port will have been re-set to its default value +before @code{display} is evaluated. + +(This function was added to Guile mostly to help calls to functions in C +libraries that can not tolerate non-local exits or calls that return +multiple times. If such functions call back to the interpreter, it should +be under a new dynamic root.) +@end deffn + + +@deffn primitive dynamic-root +Return an object representing the current dynamic root. + +These objects are only useful for comparison using @code{eq?}. +They are currently represented as numbers, but your code should +in no way depend on this. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "quit") +@deffn procedure quit [exit_val] +Throw back to the error handler of the current dynamic root. + +If integer @var{exit_val} is specified and if Guile is being used +stand-alone and if quit is called from the initial dynamic-root, +@var{exit_val} becomes the exit status of the Guile process and the +process exits. +@end deffn + +When Guile is run interactively, errors are caught from within the +read-eval-print loop. An error message will be printed and @code{abort} +called. A default set of signal handlers is installed, e.g., to allow +user interrupt of the interpreter. + +It is possible to switch to a "batch mode", in which the interpreter +will terminate after an error and in which all signals cause their +default actions. Switching to batch mode causes any handlers installed +from Scheme code to be removed. An example of where this is useful is +after forking a new process intended to run non-interactively. + +@c begin (scm-doc-string "boot-9.scm" "batch-mode?") +@deffn procedure batch-mode? +Returns a boolean indicating whether the interpreter is in batch mode. +@end deffn + +@c begin (scm-doc-string "boot-9.scm" "set-batch-mode?!") +@deffn procedure set-batch-mode?! arg +If @var{arg} is true, switches the interpreter to batch mode. +The @code{#f} case has not been implemented. +@end deffn + +@node Threads +@section Threads +@cindex threads +@cindex Guile threads + +@strong{[NOTE: this chapter was written for Cygnus Guile and has not yet +been updated for the Guile 1.x release.]} + +Here is a the reference for Guile's threads. In this chapter I simply +quote verbatim Tom Lord's description of the low-level primitives +written in C (basically an interface to the POSIX threads library) and +Anthony Green's description of the higher-level thread procedures +written in scheme. +@cindex posix threads +@cindex Lord, Tom +@cindex Green, Anthony + +When using Guile threads, keep in mind that each guile thread is +executed in a new dynamic root. + +@menu +* Low level thread primitives:: +* Higher level thread procedures:: +@end menu + + +@node Low level thread primitives +@subsection Low level thread primitives + +@c NJFIXME no current mechanism for making sure that these docstrings +@c are in sync. + +@c begin (texi-doc-string "guile" "call-with-new-thread") +@deffn primitive call-with-new-thread thunk error-handler +Evaluate @code{(thunk)} in a new thread, and new dynamic context, +returning a new thread object representing the thread. + +If an error occurs during evaluation, call error-handler, passing it an +error code describing the condition. [Error codes are currently +meaningless integers. In the future, real values will be specified.] +If this happens, the error-handler is called outside the scope of the new +root -- it is called in the same dynamic context in which +with-new-thread was evaluated, but not in the caller's thread. + +All the evaluation rules for dynamic roots apply to threads. +@end deffn + +@c begin (texi-doc-string "guile" "join-thread") +@deffn primitive join-thread thread +Suspend execution of the calling thread until the target @var{thread} +terminates, unless the target @var{thread} has already terminated. +@end deffn + +@c begin (texi-doc-string "guile" "yield") +@deffn primitive yield +If one or more threads are waiting to execute, calling yield forces an +immediate context switch to one of them. Otherwise, yield has no effect. +@end deffn + +@c begin (texi-doc-string "guile" "make-mutex") +@deffn primitive make-mutex +Create a new mutex object. +@end deffn + +@c begin (texi-doc-string "guile" "lock-mutex") +@deffn primitive lock-mutex mutex +Lock @var{mutex}. If the mutex is already locked, the calling thread +blocks until the mutex becomes available. The function returns when +the calling thread owns the lock on @var{mutex}. +@end deffn + +@c begin (texi-doc-string "guile" "unlock-mutex") +@deffn primitive unlock-mutex mutex +Unlocks @var{mutex} if the calling thread owns the lock on @var{mutex}. +Calling unlock-mutex on a mutex not owned by the current thread results +in undefined behaviour. Once a mutex has been unlocked, one thread +blocked on @var{mutex} is awakened and grabs the mutex lock. +@end deffn + +@c begin (texi-doc-string "guile" "make-condition-variable") +@deffn primitive make-condition-variable +@end deffn + +@c begin (texi-doc-string "guile" "wait-condition-variable") +@deffn primitive wait-condition-variable cond-var mutex +@end deffn + +@c begin (texi-doc-string "guile" "signal-condition-variable") +@deffn primitive signal-condition-variable cond-var +@end deffn + + +@node Higher level thread procedures +@subsection Higher level thread procedures + +@c new by ttn, needs review + +Higher level thread procedures are available by loading the +@code{(ice-9 threads)} module. These provide standardized +thread creation and mutex interaction. + +@deffn primitive %thread-handler tag args@dots{} + +This procedure is specified as the standard error-handler for +@code{make-thread} and @code{begin-thread}. If the number of @var{args} +is three or more, use @code{display-error}, otherwise display a message +"uncaught throw to @var{tag}". All output is sent to the port specified +by @code{current-error-port}. + +Before display, global var @code{the-last-stack} is set to @code{#f} +and signals are unmasked with @code{unmask-signals}. + +[FIXME: Why distinguish based on number of args?! Cue voodoo music here.] +@end deffn + +@deffn macro make-thread proc [args@dots{}] +Apply @var{proc} to @var{args} in a new thread formed by +@code{call-with-new-thread} using @code{%thread-handler} as the error +handler. +@end deffn + +@deffn macro begin-thread first [rest@dots{}] +Evaluate forms @var{first} and @var{rest} in a new thread formed by +@code{call-with-new-thread} using @code{%thread-handler} as the error +handler. +@end deffn + +@deffn macro with-mutex m [body@dots{}] +Lock mutex @var{m}, evaluate @var{body}, and then unlock @var{m}. +These sub-operations form the branches of a @code{dynamic-wind}. +@end deffn + +@deffn macro monitor first [rest@dots{}] +Evaluate forms @var{first} and @var{rest} under a newly created +anonymous mutex, using @code{with-mutex}. + +[FIXME: Is there any way to access the mutex?] +@end deffn + + +@node Fluids +@section Fluids + +@cindex fluids + +@c FIXME::martin: Review me! + +Fluids are objects to store values in. They have a few properties which +make them useful in certain situations: Fluids can have one value per +dynamic root (@pxref{Dynamic Roots}), so that changes to the value in a +fluid are only visible in the same dynamic root. Since threads are +executed in separate dynamic roots, fluids can be used for thread local +storage (@pxref{Threads}). + +Fluids can be used to simulate dynamically scoped variables. These are +used in several (especially in older) dialects of lisp, such as in Emacs +Lisp, and they work a bit like global variables in that they can be +modified by the caller of a procedure, and the called procedure will see +the changes. With lexically scoped variables---which are normally used +in Scheme---this cannot happen. See the description of +@code{with-fluids*} below for details. + +New fluids are created with @code{make-fluid} and @code{fluid?} is used +for testing whether an object is actually a fluid. + +@deffn primitive make-fluid +Return a newly created fluid. +Fluids are objects of a certain type (a smob) that can hold one SCM +value per dynamic root. That is, modifications to this value are +only visible to code that executes within the same dynamic root as +the modifying code. When a new dynamic root is constructed, it +inherits the values from its parent. Because each thread executes +in its own dynamic root, you can use fluids for thread local storage. +@end deffn + +@deffn primitive fluid? obj +Return @code{#t} iff @var{obj} is a fluid; otherwise, return +@code{#f}. +@end deffn + +The values stored in a fluid can be accessed with @code{fluid-ref} and +@code{fluid-set!}. + +@deffn primitive fluid-ref fluid +Return the value associated with @var{fluid} in the current +dynamic root. If @var{fluid} has not been set, then return +@code{#f}. +@end deffn + +@deffn primitive fluid-set! fluid value +Set the value associated with @var{fluid} in the current dynamic root. +@end deffn + +@code{with-fluids*} temporarily changes the values of one or more fluids, +so that the given procedure and each procedure called by it access the +given values. After the procedure returns, the old values are restored. + +@deffn primitive with-fluids* fluids values thunk +Set @var{fluids} to @var{values} temporary, and call @var{thunk}. +@var{fluids} must be a list of fluids and @var{values} must be the same +number of their values to be applied. Each substitution is done +one after another. @var{thunk} must be a procedure with no argument. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-translation.texi b/doc/ref/scheme-translation.texi new file mode 100644 index 000000000..c01b1491a --- /dev/null +++ b/doc/ref/scheme-translation.texi @@ -0,0 +1,44 @@ +@page +@node Translation +@chapter Support for Translating Other Languages + +[Describe translation framework.] + +@menu +* Emacs Lisp Support:: Helper primitives for Emacs Lisp. +@end menu + + +@node Emacs Lisp Support +@section Emacs Lisp Support + +@deffn primitive nil-car x +Return the car of @var{x}, but convert it to LISP nil if it +is Scheme's end-of-list. +@end deffn + +@deffn primitive nil-cdr x +Return the cdr of @var{x}, but convert it to LISP nil if it +is Scheme's end-of-list. +@end deffn + +@deffn primitive nil-cons x y +Create a new cons cell with @var{x} as the car and @var{y} as +the cdr, but convert @var{y} to Scheme's end-of-list if it is +a LISP nil. +@end deffn + +@deffn primitive nil-eq x y +Compare @var{x} and @var{y} and return LISP's t if they are +@code{eq?}, return LISP's nil otherwise. +@end deffn + +@deffn primitive null x +Return LISP's @code{t} if @var{x} is nil in the LISP sense, +return LISP's nil otherwise. +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scheme-utility.texi b/doc/ref/scheme-utility.texi new file mode 100644 index 000000000..93c76bdf1 --- /dev/null +++ b/doc/ref/scheme-utility.texi @@ -0,0 +1,295 @@ +@page +@node Utility Functions +@chapter General Utility Functions + +@c FIXME::martin: Review me! + +This chapter contains information about procedures which are not cleanly +tied to a specific data type. Because of their wide range of +applications, they are collected in a @dfn{utlity} chapter. + +@menu +* Equality:: When are two values `the same'? +* Property Lists:: Managing metainformation about Scheme objects. +* Primitive Properties:: A modern low-level interface to object properties. +* Sorting:: Sort utility procedures. +* Copying:: Copying deep structures. +* General Conversion:: Converting objects to strings. +@end menu + + +@node Equality +@section Equality + +@c FIXME::martin: Review me! + +@cindex sameness +@cindex equality + +Three different kinds of @dfn{sameness} are defined in Scheme. + +@itemize @bullet +@item +Two values can refer to exactly the same object. + +@item +Two objects can have the same @dfn{value}. + +@item +Two objects can be structurally equivalent. +@end itemize + +The differentiation between these three kinds is important, because +determining whether two values are the same objects is very efficient, +while determining structural equivalence can be quite expensive +(consider comparing two very long lists). Therefore, three different +procedures for testing for equality are provided, which correspond to +the three kinds of @dfn{sameness} defined above. + +@rnindex eq? +@deffn primitive eq? x y +Return @code{#t} iff @var{x} references the same object as @var{y}. +@code{eq?} is similar to @code{eqv?} except that in some cases it is +capable of discerning distinctions finer than those detectable by +@code{eqv?}. +@end deffn + +@rnindex eqv? +@deffn primitive eqv? x y +The @code{eqv?} procedure defines a useful equivalence relation on objects. +Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be +regarded as the same object. This relation is left slightly open to +interpretation, but works for comparing immediate integers, characters, +and inexact numbers. +@end deffn + +@rnindex equal? +@deffn primitive equal? x y +Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?} equivalent. +@code{equal?} recursively compares the contents of pairs, +vectors, and strings, applying @code{eqv?} on other objects such as +numbers and symbols. A rule of thumb is that objects are generally +@code{equal?} if they print the same. @code{equal?} may fail to +terminate if its arguments are circular data structures. +@end deffn + + +@node Property Lists +@section Property Lists + +Every object in the system can have a @dfn{property list} that may +be used for information about that object. For example, a +function may have a property list that includes information about +the source file in which it is defined. + +Property lists are implemented as assq lists (@pxref{Association Lists}). + +Currently, property lists are implemented differently for procedures and +closures than for other kinds of objects. Therefore, when manipulating +a property list associated with a procedure object, use the +@code{procedure} functions; otherwise, use the @code{object} functions. + +@deffn primitive object-properties obj +@deffnx primitive procedure-properties obj +Return @var{obj}'s property list. +@end deffn + +@deffn primitive set-object-properties! obj alist +@deffnx primitive set-procedure-properties! obj alist +Set @var{obj}'s property list to @var{alist}. +@end deffn + +@deffn primitive object-property obj key +@deffnx primitive procedure-property obj key +Return the property of @var{obj} with name @var{key}. +@end deffn + +@deffn primitive set-object-property! obj key value +@deffnx primitive set-procedure-property! obj key value +In @var{obj}'s property list, set the property named @var{key} +to @var{value}. +@end deffn + +[Interface bug: there should be a second level of interface in which +the user provides a "property table" that is possibly private.] + + +@node Primitive Properties +@section Primitive Properties + +@deffn primitive primitive-make-property not_found_proc +Create a @dfn{property token} that can be used with +@code{primitive-property-ref} and @code{primitive-property-set!}. +See @code{primitive-property-ref} for the significance of +@var{not_found_proc}. +@end deffn + +@deffn primitive primitive-property-ref prop obj +Return the property @var{prop} of @var{obj}. When no value +has yet been associated with @var{prop} and @var{obj}, call +@var{not-found-proc} instead (see @code{primitive-make-property}) +and use its return value. That value is also associated with +@var{obj} via @code{primitive-property-set!}. When +@var{not-found-proc} is @code{#f}, use @code{#f} as the +default value of @var{prop}. +@end deffn + +@deffn primitive primitive-property-set! prop obj val +Associate @var{code} with @var{prop} and @var{obj}. +@end deffn + +@deffn primitive primitive-property-del! prop obj +Remove any value associated with @var{prop} and @var{obj}. +@end deffn + + +@node Sorting +@section Sorting + +@c FIXME::martin: Review me! + +@cindex sorting +@cindex sorting lists +@cindex sorting vectors + +Sorting is very important in computer programs. Therefore, Guile comes +with several sorting procedures built-in. As always, procedures with +names ending in @code{!} are side-effecting, that means that they may +modify their parameters in order to produce their results. + +The first group of procedures can be used to merge two lists (which must +be already sorted on their own) and produce sorted lists containing +all elements of the input lists. + +@deffn primitive merge alist blist less +Take two lists @var{alist} and @var{blist} such that +@code{(sorted? alist less?)} and @code{(sorted? blist less?)} and +returns a new list in which the elements of @var{alist} and +@var{blist} have been stably interleaved so that +@code{(sorted? (merge alist blist less?) less?)}. +@end deffn + +@deffn primitive merge! alist blist less +Takes two lists @var{alist} and @var{blist} such that +@code{(sorted? alist less?)} and @code{(sorted? blist less?)} and +returns a new list in which the elements of @var{alist} and +@var{blist} have been stably interleaved so that + @code{(sorted? (merge alist blist less?) less?)}. +This is the destructive variant of @code{merge} +Note: this does _not_ accept vectors. +@end deffn + +The following procedures can operate on sequences which are either +vectors or list. According to the given arguments, they return sorted +vectors or lists, respectively. The first of the following procedures +determines whether a sequence is already sorted, the other sort a given +sequence. The variants with names starting with @code{stable-} are +special in that they maintain a special property of the input sequences: +If two or more elements are the same according to the comparison +predicate, they are left in the same order as they appeared in the +input. + +@deffn primitive sorted? items less +Return @code{#t} iff @var{items} is a list or a vector such that +for all 1 <= i <= m, the predicate @var{less} returns true when +applied to all elements i - 1 and i +@end deffn + +@deffn primitive sort items less +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence +elements. This is not a stable sort. +@end deffn + +@deffn primitive sort! items less +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence +elements. The sorting is destructive, that means that the +input sequence is modified to produce the sorted result. +This is not a stable sort. +@end deffn + +@deffn primitive stable-sort items less +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence elements. +This is a stable sort. +@end deffn + +@deffn primitive stable-sort! items less +Sort the sequence @var{items}, which may be a list or a +vector. @var{less} is used for comparing the sequence elements. +The sorting is destructive, that means that the input sequence +is modified to produce the sorted result. +This is a stable sort. +@end deffn + +The procedures in the last group only accept lists or vectors as input, +as their names indicate. + +@deffn primitive sort-list items less +Sort the list @var{items}, using @var{less} for comparing the +list elements. This is a stable sort. +@end deffn + +@deffn primitive sort-list! items less +Sort the list @var{items}, using @var{less} for comparing the +list elements. The sorting is destructive, that means that the +input list is modified to produce the sorted result. +This is a stable sort. +@end deffn + +@deffn primitive restricted-vector-sort! vec less startpos endpos +Sort the vector @var{vec}, using @var{less} for comparing +the vector elements. @var{startpos} and @var{endpos} delimit +the range of the vector which gets sorted. The return value +is not specified. +@end deffn + + +@node Copying +@section Copying Deep Structures + +@c FIXME::martin: Review me! + +The procedures for copying lists (@pxref{Lists}) only produce a flat +copy of the input list, and currently Guile does not even contain +procedures for copying vectors. @code{copy-tree} can be used for these +application, as it does not only copy the spine of a list, but also +copies any pairs in the cars of the input lists. + +@deffn primitive copy-tree obj +Recursively copy the data tree that is bound to @var{obj}, and return a +pointer to the new data structure. @code{copy-tree} recurses down the +contents of both pairs and vectors (since both cons cells and vector +cells may point to arbitrary objects), and stops recursing when it hits +any other object. +@end deffn + + +@node General Conversion +@section General String Conversion + +@c FIXME::martin: Review me! + +When debugging Scheme programs, but also for providing a human-friendly +interface, a procedure for converting any Scheme object into string +format is very useful. Conversion from/to strings can of course be done +with specialized procedures when the data type of the object to convert +is known, but with this procedure, it is often more comfortable. + +@code{object->string} converts an object by using a print procedure for +writing to a string port, and then returning the resulting string. +Converting an object back from the string is only possible if the object +type has a read syntax and the read syntax is preserved by the printing +procedure. + +@deffn primitive object->string obj [printer] +Return a Scheme string obtained by printing @var{obj}. +Printing function can be specified by the optional second +argument @var{printer} (default: @code{write}). +@end deffn + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scm.texi b/doc/ref/scm.texi new file mode 100644 index 000000000..c6a00d5c9 --- /dev/null +++ b/doc/ref/scm.texi @@ -0,0 +1,458 @@ +@page +@node Scheme Primitives +@c @chapter Writing Scheme primitives in C +@c - according to the menu in guile.texi - NJ 2001/1/26 +@chapter Relationship between Scheme and C functions + +@c Chapter contents contributed by Thien-Thi Nguyen <ttn@gnu.org>. + +Scheme procedures marked "primitive functions" have a regular interface +when calling from C, reflected in two areas: the name of a C function, and +the convention for passing non-required arguments to this function. + +@c Although the vast majority of functions support these relationships, +@c there are some exceptions. + +@menu +* Transforming Scheme name to C name:: +* Structuring argument lists for C functions:: +@c * Exceptions to the regularity:: +@end menu + +@node Transforming Scheme name to C name +@section Transforming Scheme name to C name + +Normally, the name of a C function can be derived given its Scheme name, +using some simple textual transformations: + +@itemize @bullet + +@item +Replace @code{-} (hyphen) with @code{_} (underscore). + +@item +Replace @code{?} (question mark) with "_p". + +@item +Replace @code{!} (exclamation point) with "_x". + +@item +Replace internal @code{->} with "_to_". + +@item +Replace @code{<=} (less than or equal) with "_leq". + +@item +Replace @code{>=} (greater than or equal) with "_geq". + +@item +Replace @code{<} (less than) with "_less". + +@item +Replace @code{>} (greater than) with "_gr". + +@item +Replace @code{@@} with "at". [Omit?] + +@item +Prefix with "gh_" (or "scm_" if you are ignoring the gh interface). + +@item +[Anything else? --ttn, 2000/01/16 15:17:28] + +@end itemize + +Here is an Emacs Lisp command that prompts for a Scheme function name and +inserts the corresponding C function name into the buffer. + +@example +(defun insert-scheme-to-C (name &optional use-gh) + "Transforms Scheme NAME, a string, to its C counterpart, and inserts it. +Prefix arg non-nil means use \"gh_\" prefix, otherwise use \"scm_\" prefix." + (interactive "sScheme name: \nP") + (let ((transforms '(("-" . "_") + ("?" . "_p") + ("!" . "_x") + ("->" . "_to_") + ("<=" . "_leq") + (">=" . "_geq") + ("<" . "_less") + (">" . "_gr") + ("@" . "at")))) + (while transforms + (let ((trigger (concat "\\(.*\\)" + (regexp-quote (caar transforms)) + "\\(.*\\)")) + (sub (cdar transforms)) + (m nil)) + (while (setq m (string-match trigger name)) + (setq name (concat (match-string 1 name) + sub + (match-string 2 name))))) + (setq transforms (cdr transforms)))) + (insert (if use-gh "gh_" "scm_") name)) +@end example + +@node Structuring argument lists for C functions +@section Structuring argument lists for C functions + +The C function's arguments will be all of the Scheme procedure's +argumements, both required and optional; if the Scheme procedure takes a +``rest'' argument, that will be a final argument to the C function. The +C function's arguments, as well as its return type, will be @code{SCM}. + +@c @node Exceptions to the regularity +@c @section Exceptions to the regularity +@c +@c There are some exceptions to the regular structure described above. + + +@page +@node I/O Extensions +@chapter Using and Extending Ports in C + +@menu +* C Port Interface:: Using ports from C. +* Port Implementation:: How to implement a new port type in C. +@end menu + + +@node C Port Interface +@section C Port Interface + +This section describes how to use Scheme ports from C. + +@subsection Port basics + +There are two main data structures. A port type object (ptob) is of +type @code{scm_ptob_descriptor}. A port instance is of type +@code{scm_port}. Given an @code{SCM} variable which points to a port, +the corresponding C port object can be obtained using the +@code{SCM_PTAB_ENTRY} macro. The ptob can be obtained by using +@code{SCM_PTOBNUM} to give an index into the @code{scm_ptobs} +global array. + +@subsection Port buffers + +An input port always has a read buffer and an output port always has a +write buffer. However the size of these buffers is not guaranteed to be +more than one byte (e.g., the @code{shortbuf} field in @code{scm_port} +which is used when no other buffer is allocated). The way in which the +buffers are allocated depends on the implementation of the ptob. For +example in the case of an fport, buffers may be allocated with malloc +when the port is created, but in the case of an strport the underlying +string is used as the buffer. + +@subsection The @code{rw_random} flag + +Special treatment is required for ports which can be seeked at random. +Before various operations, such as seeking the port or changing from +input to output on a bidirectional port or vice versa, the port +implemention must be given a chance to update its state. The write +buffer is updated by calling the @code{flush} ptob procedure and the +input buffer is updated by calling the @code{end_input} ptob procedure. +In the case of an fport, @code{flush} causes buffered output to be +written to the file descriptor, while @code{end_input} causes the +descriptor position to be adjusted to account for buffered input which +was never read. + +The special treatment must be performed if the @code{rw_random} flag in +the port is non-zero. + +@subsection The @code{rw_active} variable + +The @code{rw_active} variable in the port is only used if +@code{rw_random} is set. It's defined as an enum with the following +values: + +@table @code +@item SCM_PORT_READ +the read buffer may have unread data. + +@item SCM_PORT_WRITE +the write buffer may have unwritten data. + +@item SCM_PORT_NEITHER +neither the write nor the read buffer has data. +@end table + +@subsection Reading from a port. + +To read from a port, it's possible to either call existing libguile +procedures such as @code{scm_getc} and @code{scm_read_line} or to read +data from the read buffer directly. Reading from the buffer involves +the following steps: + +@enumerate +@item +Flush output on the port, if @code{rw_active} is @code{SCM_PORT_WRITE}. + +@item +Fill the read buffer, if it's empty, using @code{scm_fill_input}. + +@item Read the data from the buffer and update the read position in +the buffer. Steps 2) and 3) may be repeated as many times as required. + +@item Set rw_active to @code{SCM_PORT_READ} if @code{rw_random} is set. + +@item update the port's line and column counts. +@end enumerate + +@subsection Writing to a port. + +To write data to a port, calling @code{scm_lfwrite} should be sufficient for +most purposes. This takes care of the following steps: + +@enumerate +@item +End input on the port, if @code{rw_active} is @code{SCM_PORT_READ}. + +@item +Pass the data to the ptob implementation using the @code{write} ptob +procedure. The advantage of using the ptob @code{write} instead of +manipulating the write buffer directly is that it allows the data to be +written in one operation even if the port is using the single-byte +@code{shortbuf}. + +@item +Set @code{rw_active} to @code{SCM_PORT_WRITE} if @code{rw_random} +is set. +@end enumerate + + +@node Port Implementation +@section Port Implementation + +This section describes how to implement a new port type in C. + +As described in the previous section, a port type object (ptob) is +a structure of type @code{scm_ptob_descriptor}. A ptob is created by +calling @code{scm_make_port_type}. + +All of the elements of the ptob, apart from @code{name}, are procedures +which collectively implement the port behaviour. Creating a new port +type mostly involves writing these procedures. + +@code{scm_make_port_type} initialises three elements of the structure +(@code{name}, @code{fill_input} and @code{write}) from its arguments. +The remaining elements are initialised with default values and can be +set later if required. + +@table @code +@item name +A pointer to a NUL terminated string: the name of the port type. This +is the only element of @code{scm_ptob_descriptor} which is not +a procedure. Set via the first argument to @code{scm_make_port_type}. + +@item mark +Called during garbage collection to mark any SCM objects that a port +object may contain. It doesn't need to be set unless the port has +@code{SCM} components. Set using @code{scm_set_port_mark}. + +@item free +Called when the port is collected during gc. It +should free any resources used by the port. +Set using @code{scm_set_port_free}. + +@item print +Called when @code{write} is called on the port object, to print a +port description. e.g., for an fport it may produce something like: +@code{#<input: /etc/passwd 3>}. Set using @code{scm_set_port_print}. + +@item equalp +Not used at present. Set using @code{scm_set_port_equalp}. + +@item close +Called when the port is closed, unless it was collected during gc. It +should free any resources used by the port. +Set using @code{scm_set_port_close}. + +@item write +Accept data which is to be written using the port. The port implementation +may choose to buffer the data instead of processing it directly. +Set via the third argument to @code{scm_make_port_type}. + +@item flush +Complete the processing of buffered output data. Reset the value of +@code{rw_active} to @code{SCM_PORT_NEITHER}. +Set using @code{scm_set_port_flush}. + +@item end_input +Perform any synchronisation required when switching from input to output +on the port. Reset the value of @code{rw_active} to @code{SCM_PORT_NEITHER}. +Set using @code{scm_set_port_end_input}. + +@item fill_input +Read new data into the read buffer and return the first character. It +can be assumed that the read buffer is empty when this procedure is called. +Set via the second argument to @code{scm_make_port_type}. + +@item input_waiting +Return a lower bound on the number of bytes that could be read from the +port without blocking. It can be assumed that the current state of +@code{rw_active} is @code{SCM_PORT_NEITHER}. +Set using @code{scm_set_port_input_waiting}. + +@item seek +Set the current position of the port. The procedure can not make +any assumptions about the value of @code{rw_active} when it's +called. It can reset the buffers first if desired by using something +like: + +@example + if (pt->rw_active == SCM_PORT_READ) + scm_end_input (object); + else if (pt->rw_active == SCM_PORT_WRITE) + ptob->flush (object); +@end example + +However note that this will have the side effect of discarding any data +in the unread-char buffer, in addition to any side effects from the +@code{end_input} and @code{flush} ptob procedures. This is undesirable +when seek is called to measure the current position of the port, i.e., +@code{(seek p 0 SEEK_CUR)}. The libguile fport and string port +implementations take care to avoid this problem. + +The procedure is set using @code{scm_set_port_seek}. + +@item truncate +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 @code{scm_set_port_truncate}. + +@end table + + +@node Handling Errors +@chapter How to Handle Errors in C Code + +Error handling is based on @code{catch} and @code{throw}. Errors are +always thrown with a @var{key} and four arguments: + +@itemize @bullet +@item +@var{key}: a symbol which indicates the type of error. The symbols used +by libguile are listed below. + +@item +@var{subr}: the name of the procedure from which the error is thrown, or +@code{#f}. + +@item +@var{message}: a string (possibly language and system dependent) +describing the error. The tokens @code{~A} and @code{~S} can be +embedded within the message: they will be replaced with members of the +@var{args} list when the message is printed. @code{~A} indicates an +argument printed using @code{display}, while @code{~S} indicates an +argument printed using @code{write}. @var{message} can also be +@code{#f}, to allow it to be derived from the @var{key} by the error +handler (may be useful if the @var{key} is to be thrown from both C and +Scheme). + +@item +@var{args}: a list of arguments to be used to expand @code{~A} and +@code{~S} tokens in @var{message}. Can also be @code{#f} if no +arguments are required. + +@item +@var{rest}: a list of any additional objects required. e.g., when the +key is @code{'system-error}, this contains the C errno value. Can also +be @code{#f} if no additional objects are required. +@end itemize + +In addition to @code{catch} and @code{throw}, the following Scheme +facilities are available: + +@deffn primitive scm-error key subr message args rest +Throw an error, with arguments +as described above. +@end deffn + +@deffn procedure error msg arg @dots{} +Throw an error using the key @code{'misc-error}. The error +message is created by displaying @var{msg} and writing the @var{args}. +@end deffn + +The following are the error keys defined by libguile and the situations +in which they are used: + +@itemize @bullet +@item +@code{error-signal}: thrown after receiving an unhandled fatal signal +such as SIGSEV, SIGBUS, SIGFPE etc. The @var{rest} argument in the throw +contains the coded signal number (at present this is not the same as the +usual Unix signal number). + +@item +@code{system-error}: thrown after the operating system indicates an +error condition. The @var{rest} argument in the throw contains the +errno value. + +@item +@code{numerical-overflow}: numerical overflow. + +@item +@code{out-of-range}: the arguments to a procedure do not fall within the +accepted domain. + +@item +@code{wrong-type-arg}: an argument to a procedure has the wrong thpe. + +@item +@code{wrong-number-of-args}: a procedure was called with the wrong number +of arguments. + +@item +@code{memory-allocation-error}: memory allocation error. + +@item +@code{stack-overflow}: stack overflow error. + +@item +@code{regex-error}: errors generated by the regular expression library. + +@item +@code{misc-error}: other errors. +@end itemize + + +@section C Support + +SCM scm_error (SCM key, char *subr, char *message, SCM args, SCM rest) + +Throws an error, after converting the char * arguments to Scheme strings. +subr is the Scheme name of the procedure, NULL is converted to #f. +Likewise a NULL message is converted to #f. + +The following procedures invoke scm_error with various error keys and +arguments. The first three call scm_error with the system-error key +and automatically supply errno in the "rest" argument: scm_syserror +generates messages using strerror, scm_sysmissing is used when +facilities are not available. Care should be taken that the errno +value is not reset (e.g. due to an interrupt). + +@itemize @bullet +@item +void scm_syserror (char *subr); +@item +void scm_syserror_msg (char *subr, char *message, SCM args); +@item +void scm_sysmissing (char *subr); +@item +void scm_num_overflow (char *subr); +@item +void scm_out_of_range (char *subr, SCM bad_value); +@item +void scm_wrong_num_args (SCM proc); +@item +void scm_wrong_type_arg (char *subr, int pos, SCM bad_value); +@item +void scm_memory_error (char *subr); +@item +static void scm_regex_error (char *subr, int code); (only used in rgx.c). +@end itemize + +Exception handlers can also be installed from C, using +scm_internal_catch, scm_lazy_catch, or scm_stack_catch from +libguile/throw.c. These have not yet been documented, however the +source contains some useful comments. diff --git a/doc/ref/script-getopt.texi b/doc/ref/script-getopt.texi new file mode 100644 index 000000000..474394af7 --- /dev/null +++ b/doc/ref/script-getopt.texi @@ -0,0 +1,435 @@ +@page +@node Command Line Handling +@chapter Handling Command Line Options and Arguments + +@c This chapter was written and contributed by Martin Grabmueller. + +The ability to accept and handle command line arguments is very +important when writing Guile scripts to solve particular problems, such +as extracting information from text files or interfacing with existing +command line applications. This chapter describes how Guile makes +command line arguments available to a Guile script, and the utilities +that Guile provides to help with the processing of command line +arguments. + +@menu +* Command Line Args:: Using command line arguments. +* getopt-long:: The (ice-9 getopt-long) module. +@end menu + + +@node Command Line Args +@section Using Command Line Arguments + +When a Guile script is invoked, Guile makes the command line arguments +accessible via the procedure @code{command-line}, which returns the +arguments as a list of strings. + +For example, if the script + +@example +#! /usr/local/bin/guile -s +!# +(write (command-line)) +(newline) +@end example + +@noindent +is saved in a file @file{cmdline-test.scm} and invoked using the command +line @code{./cmdline-test.scm bar.txt -o foo -frumple grob}, the output +is + +@example +("./cmdline-test.scm" "bar.txt" "-o" "foo" "-frumple" "grob") +@end example + +If the script invocation includes a @code{-e} option, specifying a +procedure to call after loading the script, Guile will call that +procedure with @code{(command-line)} as its argument. So a script that +uses @code{-e} doesn't need to refer explicitly to @code{command-line} +in its code. For example, the script above would have identical +behaviour if it was written instead like this: + +@example +#! /usr/local/bin/guile \ +-e main -s +!# +(define (main args) + (write args) + (newline)) +@end example + +(Note the use of the meta switch @code{\} so that the script invocation +can include more than one Guile option: @xref{The Meta Switch}.) + +These scripts use the @code{#!} POSIX convention so that they can be +executed using their own file names directly, as in the example command +line @code{./cmdline-test.scm bar.txt -o foo -frumple grob}. But they +can also be executed by typing out the implied Guile command line in +full, as in: + +@example +$ guile -s ./cmdline-test.scm bar.txt -o foo -frumple grob +@end example + +@noindent +or + +@example +$ guile -e main -s ./cmdline-test2.scm bar.txt -o foo -frumple grob +@end example + +Even when a script is invoked using this longer form, the arguments that +the script receives are the same as if it had been invoked using the +short form. Guile ensures that the @code{(command-line)} or @code{-e} +arguments are independent of how the script is invoked, by stripping off +the arguments that Guile itself processes. + + +@node getopt-long +@section The (ice-9 getopt-long) Module + +A script is free to parse and handle its command line arguments in any +way that it chooses. Where the set of possible options and arguments is +complex, however, it can get tricky to extract all the options, check +the validity of given arguments, and so on. This task can be greatly +simplified by taking advantage of the module @code{(ice-9 getopt-long)}, +which is distributed with Guile. + +The @code{(ice-9 getopt-long)} module exports two procedures: +@code{getopt-long} and @code{option-ref}. + +@itemize @bullet +@item +@code{getopt-long} takes a list of strings --- the command line +arguments --- and an @dfn{option specification}. It parses the command +line arguments according to the option specification and returns a data +structure that encapsulates the results of the parsing. + +@item +@code{option-ref} then takes the parsed data structure and a specific +option's name, and returns information about that option in particular. +@end itemize + +To make these procedures available to your Guile script, include the +expression @code{(use-modules (ice-9 getopt-long))} somewhere near the +top, before the first usage of @code{getopt-long} or @code{option-ref}. + +@menu +* getopt-long Example:: A short getopt-long example. +* Option Specification:: How to write an option specification. +* Command Line Format:: The expected command line format. +* getopt-long Reference:: Full documentation for @code{getopt-long}. +* option-ref Reference:: Full documentation for @code{option-ref}. +@end menu + + +@node getopt-long Example +@subsection A Short getopt-long Example + +This subsection illustrates how @code{getopt-long} is used by presenting +and dissecting a simple example. The first thing that we need is an +@dfn{option specification} that tells @code{getopt-long} how to parse +the command line. This specification is an association list with the +long option name as the key. Here is how such a specification might +look: + +@lisp +(define option-spec + '((version (single-char #\v) (value #f)) + (help (single-char #\h) (value #f)))) +@end lisp + +This alist tells @code{getopt-long} that it should accept two long +options, called @emph{version} and @emph{help}, and that these options +can also be selected by the single-letter abbreviations @emph{v} and +@emph{h}, respectively. The @code{(value #f)} clauses indicate that +neither of the options accepts a value. + +With this specification we can use @code{getopt-long} to parse a given +command line: + +@lisp +(define options (getopt-long (command-line) option-spec)) +@end lisp + +After this call, @code{options} contains the parsed command line and is +ready to be examined by @code{option-ref}. @code{option-ref} is called +like this: + +@lisp +(option-ref options 'help #f) +@end lisp + +@noindent +It expects the parsed command line, a symbol indicating the option to +examine, and a default value. The default value is returned if the +option was not present in the command line, or if the option was present +but without a value; otherwise the value from the command line is +returned. Usually @code{option-ref} is called once for each possible +option that a script supports. + +The following example shows a main program which puts all this together +to parse its command line and figure out what the user wanted. + +@lisp +(define (main args) + (let* ((option-spec '((version (single-char #\v) (value #f)) + (help (single-char #\h) (value #f)))) + (options (getopt-long args option-spec)) + (help-wanted (option-ref options 'help #f)) + (version-wanted (option-ref options 'version #f))) + (if (or version-wanted help-wanted) + (begin + (if version-wanted + (display "getopt-long-example version 0.3\n")) + (if help-wanted + (display "\ +getopt-long-example [options] + -v, --version Display version + -h, --help Display this help +"))) + (begin + (display "Hello, World!") (newline))))) +@end lisp + + +@node Option Specification +@subsection How to Write an Option Specification + +An option specification is an association list (@pxref{Association +Lists}) with one list element for each supported option. The key of each +list element is a symbol that names the option, while the value is a +list of option properties: + +@lisp +OPTION-SPEC ::= '( (OPT-NAME1 (PROP-NAME PROP-VALUE) @dots{}) + (OPT-NAME2 (PROP-NAME PROP-VALUE) @dots{}) + (OPT-NAME3 (PROP-NAME PROP-VALUE) @dots{}) + @dots{} + ) +@end lisp + +Each @var{opt-name} specifies the long option name for that option. For +example, a list element with @var{opt-name} @code{background} specifies +an option that can be specified on the command line using the long +option @code{--background}. Further information about the option --- +whether it takes a value, whether it is required to be present in the +command line, and so on --- is specified by the option properties. + +In the example of the preceding subsection, we already saw that a long +option name can have a equivalent @dfn{short option} character. The +equivalent short option character can be set for an option by specifying +a @code{single-char} property in that option's property list. For +example, a list element like @code{'(output (single-char #\o) @dots{})} +specifies an option with long name @code{--output} that can also be +specified by the equivalent short name @code{-o}. + +The @code{value} property specifies whether an option requires or +accepts a value. If the @code{value} property is set to @code{#t}, the +option requires a value: @code{getopt-long} will signal an error if the +option name is present without a corresponding value. If set to +@code{#f}, the option does not take a value; in this case, a non-option +word that follows the option name in the command line will be treated as +a non-option argument. If set to the symbol @code{optional}, the option +accepts a value but does not require one: a non-option word that follows +the option name in the command line will be interpreted as that option's +value. If the option name for an option with @code{'(value optional)} +is immediately followed in the command line by @emph{another} option +name, the value for the first option is implicitly @code{#t}. + +The @code{required?} property indicates whether an option is required to +be present in the command line. If the @code{required?} property is +set to @code{#t}, @code{getopt-long} will signal an error if the option +is not specified. + +Finally, the @code{predicate} property can be used to constrain the +possible values of an option. If used, the @code{predicate} property +should be set to a procedure that takes one argument --- the proposed +option value as a string --- and returns either @code{#t} or @code{#f} +according as the proposed value is or is not acceptable. If the +predicate procedure returns @code{#f}, @code{getopt-long} will signal an +error. + +By default, options do not have single-character equivalents, are not +required, and do not take values. Where the list element for an option +includes a @code{value} property but no @code{predicate} property, the +option values are unconstrained. + + +@node Command Line Format +@subsection Expected Command Line Format + +In order for @code{getopt-long} to correctly parse a command line, that +command line must conform to a standard set of rules for how command +line options are specified. This subsection explains what those rules +are. + +@code{getopt-long} splits a given command line into several pieces. All +elements of the argument list are classified to be either options or +normal arguments. Options consist of two dashes and an option name +(so-called @dfn{long} options), or of one dash followed by a single +letter (@dfn{short} options). + +Options can behave as switches, when they are given without a value, or +they can be used to pass a value to the program. The value for an +option may be specified using an equals sign, or else is simply the next +word in the command line, so the following two invocations are +equivalent: + +@example +$ ./foo.scm --output=bar.txt +$ ./foo.scm --output bar.txt +@end example + +Short options can be used instead of their long equivalents and can be +grouped together after a single dash. For example, the following +commands are equivalent. + +@example +$ ./foo.scm --version --help +$ ./foo.scm -v --help +$ ./foo.scm -vh +@end example + +If an option requires a value, it can only be grouped together with other +short options if it is the last option in the group; the value is the +next argument. So, for example, with the following option +specification --- + +@lisp +((apples (single-char #\a)) + (blimps (single-char #\b) (value #t)) + (catalexis (single-char #\c) (value #t))) +@end lisp + +@noindent +--- the following command lines would all be acceptable: + +@example +$ ./foo.scm -a -b bang -c couth +$ ./foo.scm -ab bang -c couth +$ ./foo.scm -ac couth -b bang +@end example + +But the next command line is an error, because @code{-b} is not the last +option in its combination, and because a group of short options cannot +include two options that both require values: + +@example +$ ./foo.scm -abc couth bang +@end example + +If an option's value is optional, @code{getopt-long} decides whether the +option has a value by looking at what follows it in the argument list. +If the next element is a string, and it does not appear to be an option +itself, then that string is the option's value. + +If the option @code{--} appears in the argument list, argument parsing +stops there and subsequent arguments are returned as ordinary arguments, +even if they resemble options. So, with the command line + +@example +$ ./foo.scm --apples "Granny Smith" -- --blimp Goodyear +@end example + +@noindent +@code{getopt-long} will recognize the @code{--apples} option as having +the value "Granny Smith", but will not treat @code{--blimp} as an +option. The strings @code{--blimp} and @code{Goodyear} will be returned +as ordinary argument strings. + + +@node getopt-long Reference +@subsection Reference Documentation for @code{getopt-long} + +@deffn procedure getopt-long args grammar +Parse the command line given in @var{args} (which must be a list of +strings) according to the option specification @var{grammar}. + +The @var{grammar} argument is expected to be a list of this form: + +@code{((@var{option} (@var{property} @var{value}) @dots{}) @dots{})} + +where each @var{option} is a symbol denoting the long option, but +without the two leading dashes (e.g. @code{version} if the option is +called @code{--version}). + +For each option, there may be list of arbitrarily many property/value +pairs. The order of the pairs is not important, but every property may +only appear once in the property list. The following table lists the +possible properties: + +@table @asis +@item @code{(single-char @var{char})} +Accept @code{-@var{char}} as a single-character equivalent to +@code{--@var{option}}. This is how to specify traditional Unix-style +flags. +@item @code{(required? @var{bool})} +If @var{bool} is true, the option is required. @code{getopt-long} will +raise an error if it is not found in @var{args}. +@item @code{(value @var{bool})} +If @var{bool} is @code{#t}, the option accepts a value; if it is +@code{#f}, it does not; and if it is the symbol @code{optional}, the +option may appear in @var{args} with or without a value. +@item @code{(predicate @var{func})} +If the option accepts a value (i.e. you specified @code{(value #t)} for +this option), then @code{getopt-long} will apply @var{func} to the +value, and throw an exception if it returns @code{#f}. @var{func} +should be a procedure which accepts a string and returns a boolean +value; you may need to use quasiquotes to get it into @var{grammar}. +@end table +@end deffn + +@code{getopt-long}'s @var{args} parameter is expected to be a list of +strings like the one returned by @code{command-line}, with the first +element being the name of the command. Therefore @code{getopt-long} +ignores the first element in @var{args} and starts argument +interpretation with the second element. + +@code{getopt-long} signals an error if any of the following conditions +hold. + +@itemize @bullet +@item +The option grammar has an invalid syntax. + +@item +One of the options in the argument list was not specified by the +grammar. + +@item +A required option is omitted. + +@item +An option which requires an argument did not get one. + +@item +An option that doesn't accept an argument does get one (this can only +happen using the long option @code{--opt=@var{value}} syntax). + +@item +An option predicate fails. +@end itemize + + +@node option-ref Reference +@subsection Reference Documentation for @code{option-ref} + +@deffn procedure option-ref options key default +Search @var{options} for a command line option named @var{key} and +return its value, if found. If the option has no value, but was given, +return @code{#t}. If the option was not given, return @var{default}. +@var{options} must be the result of a call to @code{getopt-long}. +@end deffn + +@code{option-ref} always succeeds, either by returning the requested +option value from the command line, or the default value. + +The special key @code{'()} can be used to get a list of all +non-option arguments. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/scripts.texi b/doc/ref/scripts.texi new file mode 100644 index 000000000..e3f09f471 --- /dev/null +++ b/doc/ref/scripts.texi @@ -0,0 +1,213 @@ +@page +@node Guile Scripting +@chapter Guile Scripting + +Like AWK, Perl, or any shell, Guile can interpret script files. A Guile +script is simply a file of Scheme code with some extra information at +the beginning which tells the operating system how to invoke Guile, and +then tells Guile how to handle the Scheme code. + +@menu +* Invoking Guile:: How to start a Guile script. +* The Meta Switch:: Passing complex argument lists to Guile + from shell scripts. +@end menu + +@node Invoking Guile +@section Invoking Guile + +Here we describe Guile's command-line processing in detail. Guile +processes its arguments from left to right, recognizing the switches +described below. For examples, see @ref{Scripting Examples}. + +@table @code + +@item -s @var{script} @var{arg...} +Read and evaluate Scheme source code from the file @var{script}, as the +@code{load} function would. After loading @var{script}, exit. Any +command-line arguments @var{arg...} following @var{script} become the +script's arguments; the @code{command-line} function returns a list of +strings of the form @code{(@var{script} @var{arg...})}. + +@item -c @var{expr} @var{arg...} +Evaluate @var{expr} as Scheme code, and then exit. Any command-line +arguments @var{arg...} following @var{expr} become command-line arguments; the +@code{command-line} function returns a list of strings of the form +@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the +Guile executable. + +@item -- @var{arg...} +Run interactively, prompting the user for expressions and evaluating +them. Any command-line arguments @var{arg...} following the @code{--} +become command-line arguments for the interactive session; the +@code{command-line} function returns a list of strings of the form +@code{(@var{guile} @var{arg...})}, where @var{guile} is the path of the +Guile executable. + +@item -l @var{file} +Load Scheme source code from @var{file}, and continue processing the +command line. + +@item -e @var{function} +Make @var{function} the @dfn{entry point} of the script. After loading +the script file (with @code{-s}) or evaluating the expression (with +@code{-c}), apply @var{function} to a list containing the program name +and the command-line arguments --- the list provided by the +@code{command-line} function. + +A @code{-e} switch can appear anywhere in the argument list, but Guile +always invokes the @var{function} as the @emph{last} action it performs. +This is weird, but because of the way script invocation works under +POSIX, the @code{-s} option must always come last in the list. + +@xref{Scripting Examples}. + +@item -ds +Treat a final @code{-s} option as if it occurred at this point in the +command line; load the script here. + +This switch is necessary because, although the POSIX script invocation +mechanism effectively requires the @code{-s} option to appear last, the +programmer may well want to run the script before other actions +requested on the command line. For examples, see @ref{Scripting +Examples}. + +@item \ +Read more command-line arguments, starting from the second line of the +script file. @xref{The Meta Switch}. + +@item --emacs +Assume Guile is running as an inferior process of Emacs, and use a +special protocol to communicate with Emacs's Guile interaction mode. +This switch sets the global variable use-emacs-interface to @code{#t}. + +This switch is still experimental. + +@item --use-srfi=@var{list} +The option @code{--use-srfi} expects a comma-separated list of numbers, +each representing a SRFI number to be loaded into the interpreter +before starting evaluating a script file or the REPL. Additionally, +the feature identifier for the loaded SRFIs is recognized by +`cond-expand' when using this option. + +@example +guile --use-srfi=8,13 +@end example + +@item -h@r{, }--help +Display help on invoking Guile, and then exit. + +@item -v@r{, }--version +Display the current version of Guile, and then exit. + +@end table + + +@node The Meta Switch +@section The Meta Switch + +Guile's command-line switches allow the programmer to describe +reasonably complicated actions in scripts. Unfortunately, the POSIX +script invocation mechanism only allows one argument to appear on the +@samp{#!} line after the path to the Guile executable, and imposes +arbitrary limits on that argument's length. Suppose you wrote a script +starting like this: +@example +#!/usr/local/bin/guile -e main -s +!# +(define (main args) + (map (lambda (arg) (display arg) (display " ")) + (cdr args)) + (newline)) +@end example +The intended meaning is clear: load the file, and then call @code{main} +on the command-line arguments. However, the system will treat +everything after the Guile path as a single argument --- the string +@code{"-e main -s"} --- which is not what we want. + +As a workaround, the meta switch @code{\} allows the Guile programmer to +specify an arbitrary number of options without patching the kernel. If +the first argument to Guile is @code{\}, Guile will open the script file +whose name follows the @code{\}, parse arguments starting from the +file's second line (according to rules described below), and substitute +them for the @code{\} switch. + +Working in concert with the meta switch, Guile treats the characters +@samp{#!} as the beginning of a comment which extends through the next +line containing only the characters @samp{!#}. This sort of comment may +appear anywhere in a Guile program, but it is most useful at the top of +a file, meshing magically with the POSIX script invocation mechanism. + +Thus, consider a script named @file{/u/jimb/ekko} which starts like this: +@example +#!/usr/local/bin/guile \ +-e main -s +!# +(define (main args) + (map (lambda (arg) (display arg) (display " ")) + (cdr args)) + (newline)) +@end example + +Suppose a user invokes this script as follows: +@example +$ /u/jimb/ekko a b c +@end example + +Here's what happens: +@itemize @bullet + +@item +the operating system recognizes the @samp{#!} token at the top of the +file, and rewrites the command line to: +@example +/usr/local/bin/guile \ /u/jimb/ekko a b c +@end example +This is the usual behavior, prescribed by POSIX. + +@item +When Guile sees the first two arguments, @code{\ /u/jimb/ekko}, it opens +@file{/u/jimb/ekko}, parses the three arguments @code{-e}, @code{main}, +and @code{-s} from it, and substitutes them for the @code{\} switch. +Thus, Guile's command line now reads: +@example +/usr/local/bin/guile -e main -s /u/jimb/ekko a b c +@end example + +@item +Guile then processes these switches: it loads @file{/u/jimb/ekko} as a +file of Scheme code (treating the first three lines as a comment), and +then performs the application @code{(main "/u/jimb/ekko" "a" "b" "c")}. + +@end itemize + + +When Guile sees the meta switch @code{\}, it parses command-line +argument from the script file according to the following rules: +@itemize @bullet + +@item +Each space character terminates an argument. This means that two +spaces in a row introduce an argument @code{""}. + +@item +The tab character is not permitted (unless you quote it with the +backslash character, as described below), to avoid confusion. + +@item +The newline character terminates the sequence of arguments, and will +also terminate a final non-empty argument. (However, a newline +following a space will not introduce a final empty-string argument; +it only terminates the argument list.) + +@item +The backslash character is the escape character. It escapes backslash, +space, tab, and newline. The ANSI C escape sequences like @code{\n} and +@code{\t} are also supported. These produce argument constituents; the +two-character combination @code{\n} doesn't act like a terminating +newline. The escape sequence @code{\@var{NNN}} for exactly three octal +digits reads as the character whose ASCII code is @var{NNN}. As above, +characters produced this way are argument constituents. Backslash +followed by other characters is not allowed. + +@end itemize diff --git a/doc/ref/scsh.texi b/doc/ref/scsh.texi new file mode 100644 index 000000000..99afc0406 --- /dev/null +++ b/doc/ref/scsh.texi @@ -0,0 +1,25 @@ +@page +@node The Scheme shell (scsh) +@chapter The Scheme shell (scsh) + +An incomplete port of the Scheme shell (scsh) 0.5.1 is available for +Guile. The idea is to allow Scheme code using scsh interfaces to be run +inside the Guile interpreter. + +For information about scsh on the Web see +@url{http://www-swiss.ai.mit.edu/scsh/scsh.html}. +The original scsh is available by ftp from +@url{ftp://swiss-ftp.ai.mit.edu:/pub/su}. + +The scsh code is distributed as a separate module, guile-scsh, +which must be installed somewhere in Guile's load path before +it can be used. This is similar to the installation +of slib (you may want to install that first, since it's needed before +scsh can run in Guile: see @ref{SLIB} for details). + +This port of scsh does not currently use the Guile module system, but +can be initialized with: + +@smalllisp +(load-from-path "scsh/init") +@end smalllisp diff --git a/doc/ref/slib.texi b/doc/ref/slib.texi new file mode 100644 index 000000000..445b084c6 --- /dev/null +++ b/doc/ref/slib.texi @@ -0,0 +1,105 @@ +@page +@node SLIB +@chapter SLIB + +Before the the SLIB facilities can be used, the following Scheme +expression must be executed: + +@smalllisp +(use-modules (ice-9 slib)) +@end smalllisp + +@code{require} can then be used as described in +@ref{Top, , SLIB, slib, The SLIB Manual}. + +For example: + +@smalllisp +guile> (use-modules (ice-9 slib)) +guile> (require 'primes) +guile> (probably-prime? 13) +@end smalllisp + +@menu +* SLIB installation:: +* JACAL:: +@end menu + +@node SLIB installation +@section SLIB installation + +The following seems to work, at least with slib 2c7: + +@enumerate +@item +Unpack slib somewhere, e.g., /usr/local/lib/slib. + +@item +Create a symlink in the Guile site directory to slib, e.g.,: + +@example +ln -s /usr/local/lib/slib /usr/local/share/guile/site/slib +@end example + +@item +Use Guile to create the catalogue file, e.g.,: + +@example +# guile +guile> (use-modules (ice-9 slib)) +guile> (load "/usr/local/lib/slib/mklibcat.scm") +guile> (quit) +@end example + +The catalogue data should now be in +@code{/usr/local/share/guile/site/slibcat}. + +If instead you get an error such as: + +@example +Unbound variable: scheme-implementation-type +@end example + +then a solution is to get a newer version of Guile, +or to modify ice-9/slib.scm to use define-public for the +offending variables. + +@item +Install the documentation: + +@example +cd /usr/local/lib/slib +rm /usr/local/info/slib.info* +cp slib.info /usr/local/info +install-info slib.info /usr/local/info/dir +@end example +@end enumerate + +@node JACAL +@section JACAL + +@cindex Jaffer, Aubrey +@cindex symbolic math +@cindex math -- symbolic +Jacal is a symbolic math package written in Scheme by Aubrey Jaffer. It +is usually installed as an extra package in SLIB (@pxref{Packages not +shipped with Guile}). + +You can use Guile's interface to SLIB to invoke Jacal: + +@smalllisp +(use-modules (ice-9 slib)) +(slib:load "math") +(math) +@end smalllisp + +@noindent +For complete documentation on Jacal, please read the Jacal manual. If +it has been installed on line, you can look at @ref{Top, , Jacal, jacal, +The SLIB Manual}. Otherwise you can find it on the web at +@url{http://www-swiss.ai.mit.edu/~jaffer/JACAL.html} + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi new file mode 100644 index 000000000..2f48f7dd1 --- /dev/null +++ b/doc/ref/srfi-modules.texi @@ -0,0 +1,2241 @@ +@page +@node SRFI Support +@chapter SRFI Support Modules + +SRFI is an acronym for Scheme Request For Implementation. The SRFI +documents define a lot of syntactic and procedure extensions to standard +Scheme as defined in R5RS. + +Guile has support for a number of SRFIs. This chapter gives an overview +over the available SRFIs and some usage hints. For complete +documentation, design rationales and further examples, we advise you to +get the relevant SRFI documents from the SRFI home page +@url{http://srfi.schemers.org}. + +@menu +* About SRFI Usage:: What to know about Guile's SRFI support. +* SRFI-0:: cond-expand +* SRFI-1:: List library. +* SRFI-2:: and-let*. +* SRFI-4:: Homogeneous numeric vector datatypes. +* SRFI-6:: Basic String Ports. +* SRFI-8:: receive. +* SRFI-9:: define-record-type. +* SRFI-10:: Hash-Comma Reader Extension. +* SRFI-11:: let-values and let-values*. +* SRFI-13:: String library. +* SRFI-14:: Character-set library. +* SRFI-16:: case-lambda +* SRFI-17:: Generalized set! +@end menu + + +@node About SRFI Usage +@section About SRFI Usage + +@c FIXME::martin: Review me! + +SRFI support in Guile is currently implemented partly in the core +library, and partly as add-on modules. That means that some SRFIs are +automatically available when the interpreter is started, whereas the +other SRFIs require you to use the appropriate support module +explicitly. + +There are several reasons for this inconsistency. First, the feature +checking syntactic form @code{cond-expand} (@pxref{SRFI-0}) must be +available immediately, because it must be there when the user wants to +check for the Scheme implementation, that is, before she can know that +it is safe to use @code{use-modules} to load SRFI support modules. The +second reason is that some features defined in SRFIs had been +implemented in Guile before the developers started to add SRFI +implementations as modules (for example SRFI-6 (@pxref{SRFI-6})). In +the future, it is possible that SRFIs in the core library might be +factored out into separate modules, requiring explicit module loading +when they are needed. So you should be prepared to have to use +@code{use-modules} someday in the future to access SRFI-6 bindings. If +you want, you can do that already. We have included the module +@code{(srfi srfi-6)} in the distribution, which currently does nothing, +but ensures that you can write future-safe code. + +Generally, support for a specific SRFI is made available by using +modules named @code{(srfi srfi-@var{number})}, where @var{number} is the +number of the SRFI needed. Another possibility is to use the command +line option @code{--use-srfi}, which will load the necessary modules +automatically (@pxref{Invoking Guile}). + + +@node SRFI-0 +@section SRFI-0 - cond-expand + +@c FIXME::martin: Review me! + +SRFI-0 defines a means for checking whether a Scheme implementation has +support for a specified feature. The syntactic form @code{cond-expand}, +which implements this means, has the following syntax. + +@example +@group +<cond-expand> + --> (cond-expand <cond-expand-clause>+) + | (cond-expand <cond-expand-clause>* (else <command-or-definition>)) +<cond-expand-clause> + --> (<feature-requirement> <command-or-definition>*) +<feature-requirement> + --> <feature-identifier> + | (and <feature-requirement>*) + | (or <feature-requirement>*) + | (not <feature-requirement>) +<feature-identifier> + --> <a symbol which is the name or alias of a SRFI> +@end group +@end example + +When evaluated, this form checks all clauses in order, until it finds +one whose feature requirement is satisfied. Then the form expands into +the commands or definitions in the clause. A requirement is tested as +follows: + +@itemize @bullet +@item +If it is a symbol, it is satisfied if the feature identifier is +supported. + +@item +If it is an @code{and} form, all requirements must be satisfied. If no +requirements are given, it is satisfied, too. + +@item +If it is an @code{or} form, at least one of the requirements must be +satisfied. If no requirements are given, it is not satisfied. + +@item +If it is a @code{not} form, the feature requirement must @emph{not} be +satisfied. + +@item +If the feature requirement is the keyword @code{else} and it is the last +clause, it is satisfied if no prior clause matched. +@end itemize + +If no clause is satisfied, an error is signalled. + +Since @code{cond-expand} is needed to tell what a Scheme implementation +provides, it must be accessible without using any +implementation-dependant operations, such as @code{use-modules} in +Guile. Thus, it is not necessary to use any module to get access to +this form. + +Currently, the feature identifiers @code{guile}, @code{r5rs} and +@code{srfi-0} are supported. The other SRFIs are not in that list by +default, because the SRFI modules must be explicitly used before their +exported bindings can be used. + +So if a Scheme program wishes to use SRFI-8, it has two possibilities: +First, it can check whether the running Scheme implementation is Guile, +and if it is, it can use the appropriate module: + +@lisp +(cond-expand + (guile + (use-modules (srfi srfi-8))) + (srfi-8 + #t)) + ;; otherwise fail. +@end lisp + +The other possibility is to use the @code{--use-srfi} command line +option when invoking Guile (@pxref{Invoking Guile}). When you do that, +the specified SRFI support modules will be loaded and add their feature +identifier to the list of symbols checked by @code{cond-expand}. + +So, if you invoke Guile like this: + +@example +$ guile --use-srfi=8 +@end example + +the following snippet will expand to @code{'hooray}. + +@lisp +(cond-expand (srfi-8 'hooray)) +@end lisp + + +@node SRFI-1 +@section SRFI-1 - List library + +@c FIXME::martin: Review me! + +The list library defined in SRFI-1 contains a lot of useful list +processing procedures for construction, examining, destructuring and +manipulating lists and pairs. + +Since SRFI-1 also defines some procedures which are already contained +in R5RS and thus are supported by the Guile core library, some list +and pair procedures which appear in the SRFI-1 document may not appear +in this section. So when looking for a particular list/pair +processing procedure, you should also have a look at the sections +@ref{Lists} and @ref{Pairs}. + +@menu +* SRFI-1 Constructors:: Constructing new lists. +* SRFI-1 Predicates:: Testing list for specific properties. +* SRFI-1 Selectors:: Selecting elements from lists. +* SRFI-1 Length Append etc:: Length calculation and list appending. +* SRFI-1 Fold and Map:: Higher-order list processing. +* SRFI-1 Filtering and Partitioning:: Filter lists based on predicates. +* SRFI-1 Searching:: Search for elments. +* SRFI-1 Deleting:: Delete elements from lists. +* SRFI-1 Association Lists:: Handle association lists. +* SRFI-1 Set Operations:: Use lists for representing sets. +@end menu + +@node SRFI-1 Constructors +@subsection Constructors + +@c FIXME::martin: Review me! + +New lists can be constructed by calling one of the following +procedures. + +@deffn procedure xcons d a +Like @code{cons}, but with interchanged arguments. Useful mostly when +passed to higher-order procedures. +@end deffn + +@deffn procedure list-tabulate n init-proc +Return an @var{n}-element list, where each list element is produced by +applying the procedure @var{init-proc} to the corresponding list +index. The order in which @var{init-proc} is applied to the indices +is not specified. +@end deffn + +@deffn procedure circular-list elt1 elt2 @dots{} +Return a circular list containing the given arguments @var{elt1} +@var{elt2} @dots{}. +@end deffn + +@deffn procedure iota count [start step] +Return a list containing @var{count} elements, where each element is +calculated as follows: + +@var{start} + (@var{count} - 1) * @var{step} + +@var{start} defaults to 0 and @var{step} defaults to 1. +@end deffn + + +@node SRFI-1 Predicates +@subsection Predicates + +@c FIXME::martin: Review me! + +The procedures in this section test specific properties of lists. + +@deffn procedure proper-list? obj +Return @code{#t} if @var{obj} is a proper list, that is a finite list, +terminated with the empty list. Otherwise, return @code{#f}. +@end deffn + +@deffn procedure circular-list? obj +Return @code{#t} if @var{obj} is a circular list, otherwise return +@code{#f}. +@end deffn + +@deffn procedure dotted-list? obj +Return @code{#t} if @var{obj} is a dotted list, return @code{#f} +otherwise. A dotted list is a finite list which is not terminated by +the empty list, but some other value. +@end deffn + +@deffn procedure null-list? lst +Return @code{#t} if @var{lst} is the empty list @code{()}, @code{#f} +otherwise. If something else than a proper or circular list is passed +as @var{lst}, an error is signalled. This procedure is recommented +for checking for the end of a list in contexts where dotted lists are +not allowed. +@end deffn + +@deffn procedure not-pair? obj +Return @code{#t} is @var{obj} is not a pair, @code{#f} otherwise. +This is shorthand notation @code{(not (pair? @var{obj}))} and is +supposed to be used for end-of-list checking in contexts where dotted +lists are allowed. +@end deffn + +@deffn procedure list= elt= list1 @dots{} +Return @code{#t} if all argument lists are equal, @code{#f} otherwise. +List equality is determined by testing whether all lists have the same +length and the corresponding elements are equal in the sense of the +equality predicate @var{elt=}. If no or only one list is given, +@code{#t} is returned. +@end deffn + + +@node SRFI-1 Selectors +@subsection Selectors + +@c FIXME::martin: Review me! + +@deffn procedure first pair +@deffnx procedure second pair +@deffnx procedure third pair +@deffnx procedure fourth pair +@deffnx procedure fifth pair +@deffnx procedure sixth pair +@deffnx procedure seventh pair +@deffnx procedure eighth pair +@deffnx procedure ninth pair +@deffnx procedure tenth pair +These are synonyms for @code{car}, @code{cadr}, @code{caddr}, @dots{}. +@end deffn + +@deffn procedure car+cdr pair +Return two values, the @sc{car} and the @sc{cdr} of @var{pair}. +@end deffn + +@deffn procedure take lst i +@deffnx procedure take! lst i +Return a list containing the first @var{i} elements of @var{lst}. + +@code{take!} may modify the structure of the argument list @var{lst} +in order to produce the result. +@end deffn + +@deffn procedure drop lst i +Return a list containing all but the first @var{i} elements of +@var{lst}. +@end deffn + +@deffn procedure take-right lst i +Return the a list containing the @var{i} last elements of @var{lst}. +@end deffn + +@deffn procedure drop-right lst i +@deffnx procedure drop-right! lst i +Return the a list containing all but the @var{i} last elements of +@var{lst}. + +@code{drop-right!} may modify the structure of the argument list +@var{lst} in order to produce the result. +@end deffn + +@deffn procedure split-at lst i +@deffnx procedure split-at! lst i +Return two values, a list containing the first @var{i} elements of the +list @var{lst} and a list containing the remaining elements. + +@code{split-at!} may modify the structure of the argument list +@var{lst} in order to produce the result. +@end deffn + +@deffn procedure last lst +Return the last element of the non-empty, finite list @var{lst}. +@end deffn + + +@node SRFI-1 Length Append etc +@subsection Length, Append, Concatenate, etc. + +@c FIXME::martin: Review me! + +@deffn procedure length+ lst +Return the length of the argument list @var{lst}. When @var{lst} is a +circular list, @code{#f} is returned. +@end deffn + +@deffn procedure concatenate list-of-lists +@deffnx procedure concatenate! list-of-lists +Construct a list by appending all lists in @var{list-of-lists}. + +@code{concatenate!} may modify the structure of the given lists in +order to produce the result. +@end deffn + +@deffn procedure append-reverse rev-head tail +@deffnx procedure append-reverse! rev-head tail +Reverse @var{rev-head}, append @var{tail} and return the result. This +is equivalent to @code{(append (reverse @var{rev-head}) @var{tail})}, +but more efficient. + +@code{append-reverse!} may modify @var{rev-head} in order to produce +the result. +@end deffn + +@deffn procedure zip lst1 lst2 @dots{} +Return a list as long as the shortest of the argument lists, where +each element is a list. The first list contains the first elements of +the argument lists, the second list contains the second elements, and +so on. +@end deffn + +@deffn procedure unzip1 lst +@deffnx procedure unzip2 lst +@deffnx procedure unzip3 lst +@deffnx procedure unzip4 lst +@deffnx procedure unzip5 lst +@code{unzip1} takes a list of lists, and returns a list containing the +first elements of each list, @code{unzip2} returns two lists, the +first containing the first elements of each lists and the second +containing the second elements of each lists, and so on. +@end deffn + + +@node SRFI-1 Fold and Map +@subsection Fold, Unfold & Map + +@c FIXME::martin: Review me! + +@deffn procedure fold kons knil lst1 lst2 @dots{} +Fold the procedure @var{kons} across all elements of @var{lst1}, +@var{lst2}, @dots{}. Produce the result of + +@code{(@var{kons} @var{en1} @var{en2} @dots{} (@var{kons} @var{e21} +@var{e22} (@var{kons} @var{e11} @var{e12} @var{knil})))}, + +if @var{enm} are the elements of the lists @var{lst1}, @var{lst2}, +@dots{}. +@end deffn + +@deffn procedure fold-right kons knil lst1 lst2 @dots{} +Similar to @code{fold}, but applies @var{kons} in right-to-left order +to the list elements, that is: + +@code{(@var{kons} @var{e11} @var{e12}(@var{kons} @var{e21} +@var{e22} @dots{} (@var{kons} @var{en1} @var{en2} @var{knil})))}, +@end deffn + +@deffn procedure pair-fold kons knil lst1 lst2 @dots{} +Like @code{fold}, but apply @var{kons} to the pairs of the list +instead of the list elements. +@end deffn + +@deffn procedure pair-fold-right kons knil lst1 lst2 @dots{} +Like @code{fold-right}, but apply @var{kons} to the pairs of the list +instead of the list elements. +@end deffn + +@deffn procedure reduce f ridentity lst +@code{reduce} is a variant of @code{reduce}. If @var{lst} is +@code{()}, @var{ridentity} is returned. Otherwise, @code{(fold (car +@var{lst}) (cdr @var{lst}))} is returned. +@end deffn + +@deffn procedure reduce-right f ridentity lst +This is the @code{fold-right} variant of @var{reduce}. +@end deffn + +@deffn procedure unfold p f g seed [tail-gen] +@code{unfold} is defined as follows: + +@lisp +(unfold p f g seed) = + (if (p seed) (tail-gen seed) + (cons (f seed) + (unfold p f g (g seed)))) +@end lisp + +@table @var +@item p +Determines when to stop unfolding. + +@item f +Maps each seed value to the corresponding list element. + +@item g +Maps each seed value to next seed valu. + +@item seed +The state value for the unfold. + +@item tail-gen +Creates the tail of the list; defaults to @code{(lambda (x) '())}. +@end table + +@var{g} produces a series of seed values, which are mapped to list +elements by @var{f}. These elements are put into a list in +left-to-right order, and @var{p} tells when to stop unfolding. +@end deffn + +@deffn procedure unfold-right p f g seed [tail] +Construct a list with the following loop. + +@lisp +(let lp ((seed seed) (lis tail)) + (if (p seed) lis + (lp (g seed) + (cons (f seed) lis)))) +@end lisp + +@table @var +@item p +Determines when to stop unfolding. + +@item f +Maps each seed value to the corresponding list element. + +@item g +Maps each seed value to next seed valu. + +@item seed +The state value for the unfold. + +@item tail-gen +Creates the tail of the list; defaults to @code{(lambda (x) '())}. +@end table + +@end deffn + +@deffn procedure map f lst1 lst2 @dots{} +Map the procedure over the list(s) @var{lst1}, @var{lst2}, @dots{} and +return a list containing the results of the procedure applications. +This procedure is extended with respect to R5RS, because the argument +lists may have different lengths. The result list will have the same +length as the shortest argument lists. The order in which @var{f} +will be applied to the list element(s) is not specified. +@end deffn + +@deffn procedure for-each f lst1 lst2 @dots{} +Apply the procedure @var{f} to each pair of corresponding elements of +the list(s) @var{lst1}, @var{lst2}, @dots{}. The return value is not +specified. This procedure is extended with respect to R5RS, because +the argument lists may have different lengths. The shortest argument +list determines the number of times @var{f} is called. @var{f} will +be applied to tge list elements in left-to-right order. + +@end deffn + +@deffn procedure append-map f lst1 lst2 @dots{} +@deffnx procedure append-map! f lst1 lst2 @dots{} +Equivalent to + +@lisp +(apply append (map f clist1 clist2 ...)) +@end lisp + +and + +@lisp +(apply append! (map f clist1 clist2 ...)) +@end lisp + +Map @var{f} over the elements of the lists, just as in the @code{map} +function. However, the results of the applications are appended +together to make the final result. @code{append-map} uses +@code{append} to append the results together; @code{append-map!} uses +@code{append!}. + +The dynamic order in which the various applications of @var{f} are +made is not specified. +@end deffn + +@deffn procedure map! f lst1 lst2 @dots{} +Linear-update variant of @code{map} -- @code{map!} is allowed, but not +required, to alter the cons cells of @var{lst1} to construct the +result list. + +The dynamic order in which the various applications of @var{f} are +made is not specified. In the n-ary case, @var{lst2}, @var{lst3}, +@dots{} must have at least as many elements as @var{lst1}. +@end deffn + +@deffn procedure pair-for-each f lst1 lst2 @dots{} +Like @code{for-each}, but applies the procedure @var{f} to the pairs +from which the argument lists are constructed, instead of the list +elements. The return value is not specified. +@end deffn + +@deffn procedure filter-map f lst1 lst2 @dots{} +Like @code{map}, but only results from the applications of @var{f} +which are true are saved in the result list. +@end deffn + + +@node SRFI-1 Filtering and Partitioning +@subsection Filtering and Partitioning + +@c FIXME::martin: Review me! + +Filtering means to collect all elements from a list which satisfy a +specific condition. Partitioning a list means to make two groups of +list elements, one which contains the elements satisfying a condition, +and the other for the elements which don't. + +@deffn procedure filter pred lst +@deffnx procedure filter! pred lst +Return a list containing all elements from @var{lst} which satisfy the +predicate @var{pred}. The elements in the result list have the same +order as in @var{lst}. The order in which @var{pred} is applied to +the list elements is not specified. + +@code{filter!} is allowed, but not required to modify the structure of +@end deffn + +@deffn procedure partition pred lst +@deffnx procedure partition! pred lst +Return two lists, one containing all elements from @var{lst} which +satisfy the predicate @var{pred}, and one list containing the elements +which do not satisfy the predicated. The elements in the result lists +have the same order as in @var{lst}. The order in which @var{pred} is +applied to the list elements is not specified. + +@code{partition!} is allowed, but not required to modify the structure of +the input list. +@end deffn + +@deffn procedure remove pred lst +@deffnx procedure remove! pred lst +Return a list containing all elements from @var{lst} which do not +satisfy the predicate @var{pred}. The elements in the result list +have the same order as in @var{lst}. The order in which @var{pred} is +applied to the list elements is not specified. + +@code{remove!} is allowed, but not required to modify the structure of +the input list. +@end deffn + + +@node SRFI-1 Searching +@subsection Searching + +@c FIXME::martin: Review me! + +The procedures for searching elements in lists either accept a +predicate or a comparison object for determining which elements are to +be searched. + +@deffn procedure find pred lst +Return the first element of @var{lst} which satisfies the predicate +@var{pred} and @code{#f} if no such element is found. +@end deffn + +@deffn procedure find-tail pred lst +Return the first pair of @var{lst} whose @sc{car} satisfies the +predicate @var{pred} and @code{#f} if no such element is found. +@end deffn + +@deffn procedure take-while pred lst +@deffnx procedure take-while! pred lst +Return the longest initial prefix of @var{lst} whose elements all +satisfy the predicate @var{pred}. + +@code{take-while!} is allowed, but not required to modify the input +list while producing the result. +@end deffn + +@deffn procedure drop-while pred lst +Drop the longest initial prefix of @var{lst} whose elements all +satisfy the predicate @var{pred}. +@end deffn + +@deffn procedure span pred lst +@deffnx procedure span! pred lst +@deffnx procedure break pred lst +@deffnx procedure break! pred lst +@code{span} splits the list @var{lst} into the longest initial prefix +whose elements all satisfy the predicate @var{pred}, and the remaining +tail. @code{break} inverts the sense of the predicate. + +@code{span!} and @code{break!} are allowed, but not required to modify +the structure of the input list @var{lst} in order to produce the +result. +@end deffn + +@deffn procedure any pred lst1 lst2 @dots{} +Apply @var{pred} across the lists and return a true value if the +predicate returns true for any of the list elements(s); return +@code{#f} otherwise. The true value returned is always the result of +the first succesful application of @var{pred}. +@end deffn + +@deffn procedure every pred lst1 lst2 @dots{} +Apply @var{pred} across the lists and return a true value if the +predicate returns true for every of the list elements(s); return +@code{#f} otherwise. The true value returned is always the result of +the final succesful application of @var{pred}. +@end deffn + +@deffn procedure list-index pred lst1 lst2 @dots{} +Return the index of the leftmost element that satisfies @var{pred}. +@end deffn + +@deffn procedure member x lst [=] +Return the first sublist of @var{lst} whose @sc{car} is equal to +@var{x}. If @var{x} does no appear in @var{lst}, return @code{#f}. +Equality is determined by the equality predicate @var{=}, or +@code{equal?} if @var{=} is not given. +@end deffn + + +@node SRFI-1 Deleting +@subsection Deleting + +@c FIXME::martin: Review me! + +The procedures for deleting elements from a list either accept a +predicate or a comparison object for determining which elements are to +be removed. + +@deffn procedure delete x lst [=] +@deffnx procedure delete! x lst [=] +Return a list containing all elements from @var{lst}, but without the +elements equal to @var{x}. Equality is determined by the equality +predicate @var{=}, which defaults to @code{equal?} if not given. + +@code{delete!} is allowed, but not required to modify the structure of +the argument list in order to produce the result. +@end deffn + +@deffn procedure delete-duplicates lst [=] +@deffnx procedure delete-duplicates! lst [=] +Return a list containing all elements from @var{lst}, but without +duplicate elements. Equality of elements is determined by the +equality predicate @var{=}, which defaults to @code{equal?} if not +given. + +@code{delete-duplicates!} is allowed, but not required to modify the +structure of the argument list in order to produce the result. +@end deffn + + +@node SRFI-1 Association Lists +@subsection Association Lists + +@c FIXME::martin: Review me! + +Association lists are described in detail in section @ref{Association +Lists}. The present section only documents the additional procedures +for dealing with association lists defined by SRFI-1. + +@deffn procedure assoc key alist [=] +Return the pair from @var{alist} which matches @var{key}. Equality is +determined by @var{=}, which defaults to @code{equal?} if not given. +@var{alist} must be an association lists---a list of pairs. +@end deffn + +@deffn procedure alist-cons key datum alist +Equivalent to + +@lisp +(cons (cons @var{key} @var{datum}) @var{alist}) +@end lisp + +This procedure is used to coons a new pair onto an existing +association list. +@end deffn + +@deffn procedure alist-copy alist +Return a newly allocated copy of @var{alist}, that means that the +spine of the list as well as the pairs are copied. +@end deffn + +@deffn procedure alist-delete key alist [=] +@deffnx procedure alist-delete! key alist [=] +Return a list containing the pairs of @var{alist}, but without the +pairs whose @sc{cars} are equal to @var{key}. Equality is determined +by @var{=}, which defaults to @code{equal?} if not given. + +@code{alist-delete!} is allowed, but not required to modify the +structure of the list @var{alist} in order to produce the result. +@end deffn + + +@node SRFI-1 Set Operations +@subsection Set Operations on Lists + +@c FIXME::martin: Review me! + +Lists can be used for representing sets of objects. The procedures +documented in this section can be used for such set representations. +Man combinding several sets or adding elements, they make sure that no +object is contained more than once in a given list. Please note that +lists are not a too efficient implementation method for sets, so if +you need high performance, you should think about implementing a +custom data structure for representing sets, such as trees, bitsets, +hash tables or something similar. + +All these procedures accept an equality predicate as the first +argument. This predicate is used for testing the objects in the list +sets for sameness. + +@deffn procedure lset<= = list1 @dots{} +Return @code{#t} if every @var{listi} is a subset of @var{listi+1}, +otherwise return @code{#f}. Returns @code{#t} if called with less +than two arguments. @var{=} is used for testing element equality. +@end deffn + +@deffn procedure lset= = list1 list2 @dots{} +Return @code{#t} if all argument lists are equal. @var{=} is used for +testing element equality. +@end deffn + +@deffn procedure lset-adjoin = list elt1 @dots{} +@deffnx procedure lset-adjoin! = list elt1 @dots{} +Add all @var{elts} to the list @var{list}, suppressing duplicates and +return the resulting list. @code{lset-adjoin!} is allowed, but not +required to modify its first argument. @var{=} is used for testing +element equality. +@end deffn + +@deffn procedure lset-union = list1 @dots{} +@deffnx procedure lset-union! = list1 @dots{} +Return the union of all argument list sets. The union is the set of +all elements which appear in any of the argument sets. +@code{lset-union!} is allowed, but not required to modify its first +argument. @var{=} is used for testing element equality. +@end deffn + +@deffn procedure lset-intersection = list1 list2 @dots{} +@deffnx procedure lset-intersection! = list1 list2 @dots{} +Return the intersection of all argument list sets. The intersection +is the set containing all elements which appear in all argument sets. +@code{lset-intersection!} is allowed, but not required to modify its +first argument. @var{=} is used for testing element equality. +@end deffn + +@deffn procedure lset-difference = list1 list2 @dots{} +@deffnx procedure lset-difference! = list1 list2 @dots{} +Return the difference of all argument list sets. The difference is +the the set containing all elements of the first list which do not +appear in the other lists. @code{lset-difference!} is allowed, but +not required to modify its first argument. @var{=} is used for testing +element equality. +@end deffn + +@deffn procedure lset-xor = list1 @dots{} +@deffnx procedure lset-xor! = list1 @dots{} +Return the set containing all elements which appear in the first +argument list set, but not in the second; or, more generally: which +appear in an odd number of sets. @code{lset-xor!} is allowed, but +not required to modify its first argument. @var{=} is used for testing +element equality. +@end deffn + +@deffn procedure lset-diff+intersection = list1 list2 @dots{} +@deffnx procedure lset-diff+intersection! = list1 list2 @dots{} +Return two values, the difference and the intersection of the argument +list sets. This works like a combination of @code{lset-difference} and +@code{lset-intersection}, but is more efficient. +@code{lset-diff+intersection!} is allowed, but not required to modify +its first argument. @var{=} is used for testing element equality. You +have to use some means to deal with the multiple values these +procedures return (@pxref{Multiple Values}). +@end deffn + + +@node SRFI-2 +@section SRFI-2 - and-let* + +@c FIXME::martin: Review me! + +The syntactic form @code{and-let*} combines the conditional evaluation +form @code{and} with the binding form @var{let*}. Each argument +expression will be evaluated sequentially, bound to a variable (if a +variable name is given), but only as long as no expression returns +the false value @code{#f}. + +Use @code{(use-modules (srfi srfi-2)} to access this syntax form. + +A short example will demonstrate how it works. In the first expression, +@var{x} will get bound to 1, but the next expression (@code{#f}) is +false, so evaluation of the form is stopped, and @code{#f} is returned. +In the next expression, @var{x} is bound to 1, @var{y} is bound to +@code{#t} and since no expression in the binding section was false, the +body of the @code{and-let*} expression is evaluated, which in this case +returns the value of @var{x}. + +@lisp +(and-let* ((x 1) (y #f)) 42) +@result{} +#f +(and-let* ((x 1) (y #t)) x) +@result{} +1 +@end lisp + + +@node SRFI-4 +@section SRFI-4 - Homogeneous numeric vector datatypes. + +@c FIXME::martin: Review me! + +SRFI-4 defines a set of datatypes for vectors whose elements are all +of the same numeric type. Vectors for signed and unsigned exact +integer or inexact real numbers in several precisions are available. + +Procedures similar to the vector procedures (@pxref{Vectors}) are +provided for handling these homogeneous vectors, but they are distinct +datatypes. + +The reason for providing this set of datatypes is that with the +limitation (all elements must have the same type), it is possible to +implement them much more memory-efficient than normal, heterogenous +vectors. + +If you want to use these datatypes and the corresponding procedures, +you have to use the module @code{(srfi srfi-4)}. + +Ten vector data types are provided: Unsigned and signed integer values +with 8, 16, 32 and 64 bits and floating point values with 32 and 64 +bits. In the following descriptions, the tags @code{u8}, @code{s8}, +@code{u16}, @code{s16}, @code{u32}, @code{s32}, @code{u64}, +@code{s64}, @code{f32}, @code{f64}, respectively, are used for +denoting the various types. + +@menu +* SRFI-4 - Read Syntax:: How to write homogeneous vector literals. +* SRFI-4 - Procedures:: Available homogeneous vector procedures. +@end menu + + +@node SRFI-4 - Read Syntax +@subsection SRFI-4 - Read Syntax + +Homogeneous numeric vectors have an external representation (read +syntax) similar to normal Scheme vectors, but with an additional tag +telling the vector's type. + +@lisp +#u16(1 2 3) +@end lisp + +denotes a homogeneous numeric vector of three elements, which are the +values 1, 2 and 3, represented as 16-bit unsigned integers. +Correspondingly, + +@lisp +#f64(3.1415 2.71) +@end lisp + +denotes a vector of two elements, which are the values 3.1415 and +2.71, represented as floating-point values of 64 bit precision. + +Please note that the read syntax for floating-point vectors conflicts +with Standard Scheme, because there @code{#f} is defined to be the +literal false value. That means, that with the loaded SRFI-4 module, +it is not possible to enter some list like + +@lisp +'(1 #f3) +@end lisp + +and hope that it will be parsed as a three-element list with the +elements 1, @code{#f} and 3. In normal use, this should be no +problem, because people tend to terminate tokens sensibly when writing +Scheme expressions. + +@node SRFI-4 - Procedures +@subsection SRFI-4 Procedures + +The procedures listed in this section are provided for all homogeneous +numeric vector datatypes. For brevity, they are not all documented, +but a summary of the procedures is given. In the following +descriptions, you can replace @code{TAG} by any of the datatype +indicators @code{u8}, @code{s8}, @code{u16}, @code{s16}, @code{u32}, +@code{s32}, @code{u64}, @code{s64}, @code{f32} and @code{f64}. + +For example, you can use the procedures @code{u8vector?}, +@code{make-s8vector}, @code{u16vector}, @code{u32vector-length}, +@code{s64vector-ref}, @code{f32vector-set!} or @code{f64vector->list}. + +@deffn primitive TAGvector? obj +Return @code{#t} if @var{obj} is a homogeneous numeric vector of type +@code{TAG}. +@end deffn + +@deffn primitive make-TAGvector n [value] +Create a newly allocated homogeneous numeric vector of type +@code{TAG}, which can hold @var{n} elements. If @var{value} is given, +the vector is initialized with the value, otherwise, the contents of +the returned vector is not specified. +@end deffn + +@deffn primitive TAGvector value1 @dots{} +Create a newly allocated homogeneous numeric vector of type +@code{TAG}. The returned vector is as long as the number of arguments +given, and is initialized with the argument values. +@end deffn + +@deffn primitive TAGvector-length TAGvec +Return the number of elements in @var{TAGvec}. +@end deffn + +@deffn primitive TAGvector-ref TAGvec i +Return the element at index @var{i} in @var{TAGvec}. +@end deffn + +@deffn primitive TAGvector-ref TAGvec i value +Set the element at index @var{i} in @var{TAGvec} to @var{value}. The +return value is not specified. +@end deffn + +@deffn primitive TAGvector->list TAGvec +Return a newly allocated list holding all elements of @var{TAGvec}. +@end deffn + +@deffn primitive list->TAGvector lst +Return a newly allocated homogeneous numeric vector of type @code{TAG}, +initialized with the elements of the list @var{lst}. +@end deffn + + +@node SRFI-6 +@section SRFI-6 - Basic String Ports + +SRFI-6 defines the procedures @code{open-input-string}, +@code{open-output-string} and @code{get-output-string}. These +procedures are included in the Guile core, so using this module does not +make any difference at the moment. But it is possible that support for +SRFI-6 will be factored out of the core library in the future, so using +this module does not hurt, after all. + +@node SRFI-8 +@section SRFI-8 - receive + +@code{receive} is a syntax for making the handling of multiple-value +procedures easier. It is documented in @xref{Multiple Values}. + + +@node SRFI-9 +@section SRFI-9 - define-record-type + +This is the SRFI way for defining record types. The Guile +implementation is a layer above Guile's normal record construction +procedures (@pxref{Records}). The nice thing about this kind of record +definition method is that no new names are implicitly created, all +constructor, accessor and predicates are explicitly given. This reduces +the risk of variable capture. + +The syntax of a record type definition is: + +@example +@group +<record type definition> + -> (define-record-type <type name> + (<constructor name> <field tag> ...) + <predicate name> + <field spec> ...) +<field spec> -> (<field tag> <accessor name>) + -> (<field tag> <accessor name> <modifier name>) +<field tag> -> <identifier> +<... name> -> <identifier> +@end group +@end example + +Usage example: + +@example +guile> (use-modules (srfi srfi-9)) +guile> (define-record-type :foo (make-foo x) foo? + (x get-x) (y get-y set-y!)) +guile> (define f (make-foo 1)) +guile> f +#<:foo x: 1 y: #f> +guile> (get-x f) +1 +guile> (set-y! f 2) +2 +guile> (get-y f) +2 +guile> f +#<:foo x: 1 y: 2> +guile> (foo? f) +#t +guile> (foo? 1) +#f +@end example + + +@node SRFI-10 +@section SRFI-10 - Hash-Comma Reader Extension + +@cindex hash-comma +@cindex #,() +The module @code{(srfi srfi-10)} implements the syntax extension +@code{#,()}, also called hash-comma, which is defined in SRFI-10. + +The support for SRFI-10 consists of the procedure +@code{define-reader-ctor} for defining new reader constructors and the +read syntax form + +@example +#,(@var{ctor} @var{datum} ...) +@end example + +where @var{ctor} must be a symbol for which a read constructor was +defined previouly, using @code{define-reader-ctor}. + +Example: + +@lisp +(define-reader-ctor 'file open-input-file) +(define f '#,(file "/etc/passwd")) +(read-line f) +@result{} +"root:x:0:0:root:/root:/bin/bash" +@end lisp + +Please note the quote before the @code{#,(file ...)} expression. This +is necessary because ports are not self-evaluating in Guile. + +@deffn procedure define-reader-ctor symbol proc +Define @var{proc} as the reader constructor for hash-comma forms with a +tag @var{symbol}. @var{proc} will be applied to the datum(s) following +the tag in the hash-comma expression after the complete form has been +read in. The result of @var{proc} is returned by the Scheme reader. +@end deffn + + +@node SRFI-11 +@section SRFI-11 - let-values + +This module implements the binding forms for multiple values +@code{let-values} and @code{let-values*}. These forms are similar to +@code{let} and @code{let*} (@pxref{Local Bindings}), but they support +binding of the values returned by multiple-valued expressions. + +Write @code{(use-modules (srfi srfi-11))} to make the bindings +available. + +@lisp +(let-values (((x y) (values 1 2)) + ((z f) (values 3 4))) + (+ x y z f)) +@result{} +10 +@end lisp + +@code{let-values} performs all bindings simultaneously, which means that +no expression in the binding clauses may refer to variables bound in the +same clause list. @code{let-values*}, on the other hand, performs the +bindings sequentially, just like @code{let*} does for single-valued +expressions. + + +@node SRFI-13 +@section SRFI-13 - String Library + +In this section, we will describe all procedures defined in SRFI-13 +(string library) and implemented by the module @code{(srfi srfi-13)}. + +Note that only the procedures from SRFI-13 are documented here which are +not already contained in Guile. For procedures not documented here +please refer to the relevant chapters in the Guile Reference Manual, for +example the documentation of strings and string procedures +(@pxref{Strings}). + +All of the procedures defined in SRFI-13, which are not already included +in the Guile core library, are implemented in the module @code{(srfi +srfi-13)}. The procedures which are both in Guile and in SRFI-13, but +which are slightly extended, have been implemented in this module, and +the bindings overwrite those in the Guile core. + +The procedures which are defined in the section @emph{Low-level +procedures} of SRFI-13 for parsing optional string indices, substring +specification checking and Knuth-Morris-Pratt-Searching are not +implemented. + +The procedures @code{string-contains} and @code{string-contains-ci} are +not implemented very efficiently at the moment. This will be changed as +soon as possible. + +@menu +* Loading SRFI-13:: How to load SRFI-13 support. +* SRFI-13 Predicates:: String predicates. +* SRFI-13 Constructors:: String constructing procedures. +* SRFI-13 List/String Conversion:: Conversion from/to lists. +* SRFI-13 Selection:: Selection portions of strings. +* SRFI-13 Modification:: Modfify strings in-place. +* SRFI-13 Comparison:: Compare strings. +* SRFI-13 Prefixes/Suffixes:: Detect common pre-/suffixes. +* SRFI-13 Searching:: Searching for substrings. +* SRFI-13 Case Mapping:: Mapping to lower-/upper-case. +* SRFI-13 Reverse/Append:: Reverse and append strings. +* SRFI-13 Fold/Unfold/Map:: Construct/deconstruct strings. +* SRFI-13 Replicate/Rotate:: Replacate and rotate portions of strings. +* SRFI-13 Miscellaneous:: Left-over string procedures. +* SRFI-13 Filtering/Deleting:: Filter and delete characters from strings. +@end menu + + +@node Loading SRFI-13 +@subsection Loading SRFI-13 + +When Guile is properly installed, SRFI-13 support can be loaded into a +running Guile by using the @code{(srfi srfi-13)} module. + +@example +$ guile +guile> (use-modules (srfi srfi-13)) +guile> +@end example + +When this step causes any errors, Guile is not properly installed. + +One possible reason is that Guile cannot find either the Scheme module +file @file{srfi-13.scm}, or it cannot find the shared object file +@file{libguile-srfi-srfi-13-14.so}. Make sure that the former is in the +Guile load path and that the latter is either installed in some default +location like @file{/usr/local/lib} or that the directory it was +installed to is in your @code{LTDL_LIBRARY_PATH}. The same applies to +@file{srfi-14.scm}. + +Now you can test whether the SRFI-13 procedures are working by calling +the @code{string-concatenate} procedure. + +@example +guile> (string-concatenate '("Hello" " " "World!")) +"Hello World!" +@end example + +@node SRFI-13 Predicates +@subsection Predicates + +In addition to the primitives @code{string?} and @code{string-null?}, +which are already in the Guile core, the string predicates +@code{string-any} and @code{string-every} are defined by SRFI-13. + +@deffn primitive string-any pred s [start end] +Check if the predicate @var{pred} is true for any character in +the string @var{s}, proceeding from left (index @var{start}) to +right (index @var{end}). If @code{string-any} returns true, +the returned true value is the one produced by the first +successful application of @var{pred}. +@end deffn + +@deffn primitive string-every pred s [start end] +Check if the predicate @var{pred} is true for every character +in the string @var{s}, proceeding from left (index @var{start}) +to right (index @var{end}). If @code{string-every} returns +true, the returned true value is the one produced by the final +application of @var{pred} to the last character of @var{s}. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Constructors +@subsection Constructors + +SRFI-13 defines several procedures for constructing new strings. In +addition to @code{make-string} and @code{string} (available in the Guile +core library), the procedure @code{string-tabulate} does exist. + +@deffn primitive string-tabulate proc len +@var{proc} is an integer->char procedure. Construct a string +of size @var{len} by applying @var{proc} to each index to +produce the corresponding string element. The order in which +@var{proc} is applied to the indices is not specified. +@end deffn + + +@c =================================================================== + +@node SRFI-13 List/String Conversion +@subsection List/String Conversion + +The procedure @code{string->list} is extended by SRFI-13, that is why it +is included in @code{(srfi srfi-13)}. The other procedures are new. +The Guile core already contains the procedure @code{list->string} for +converting a list of characters into a string (@pxref{List/String +Conversion}). + +@deffn primitive string->list str [start end] +Convert the string @var{str} into a list of characters. +@end deffn + +@deffn primitive reverse-list->string chrs +An efficient implementation of @code{(compose string->list +reverse)}: + +@smalllisp +(reverse-list->string '(#\a #\B #\c)) @result{} "cBa" +@end smalllisp +@end deffn + +@deffn primitive string-join ls [delimiter grammar] +Append the string in the string list @var{ls}, using the string +@var{delim} as a delimiter between the elements of @var{ls}. +@var{grammar} is a symbol which specifies how the delimiter is +placed between the strings, and defaults to the symbol +@code{infix}. + +@table @code +@item infix +Insert the separator between list elements. An empty string +will produce an empty list. + +@item string-infix +Like @code{infix}, but will raise an error if given the empty +list. + +@item suffix +Insert the separator after every list element. + +@item prefix +Insert the separator before each list element. +@end table +@end deffn + + +@c =================================================================== + +@node SRFI-13 Selection +@subsection Selection + +These procedures are called @dfn{selectors}, because they access +information about the string or select pieces of a given string. + +Additional selector procedures are documented in the Strings section +(@pxref{String Selection}), like @code{string-length} or +@code{string-ref}. + +@code{string-copy} is also available in core Guile, but this version +accepts additional start/end indices. + +@deffn primitive string-copy str [start end] +Return a freshly allocated copy of the string @var{str}. If +given, @var{start} and @var{end} delimit the portion of +@var{str} which is copied. +@end deffn + +@deffn primitive substring/shared str start [end] +Like @code{substring}, but the result may share memory with the +argument @var{str}. +@end deffn + +@deffn primitive string-copy! target tstart s [start end] +Copy the sequence of characters from index range [@var{start}, +@var{end}) in string @var{s} to string @var{target}, beginning +at index @var{tstart}. The characters are copied left-to-right +or right-to-left as needed - the copy is guaranteed to work, +even if @var{target} and @var{s} are the same string. It is an +error if the copy operation runs off the end of the target +string. +@end deffn + +@deffn primitive string-take s n +@deffnx primitive string-take-right s n +Return the @var{n} first/last characters of @var{s}. +@end deffn + +@deffn primitive string-drop s n +@deffnx primitive string-drop-right s n +Return all but the first/last @var{n} characters of @var{s}. +@end deffn + +@deffn primitive string-pad s len [chr start end] +@deffnx primitive string-pad-right s len [chr start end] +Take that characters from @var{start} to @var{end} from the +string @var{s} and return a new string, right(left)-padded by the +character @var{chr} to length @var{len}. If the resulting +string is longer than @var{len}, it is truncated on the right (left). +@end deffn + +@deffn primitive string-trim s [char_pred start end] +@deffnx primitive string-trim-right s [char_pred start end] +@deffnx primitive string-trim-both s [char_pred start end] +Trim @var{s} by skipping over all characters on the left/right/both +sides of the string that satisfy the parameter @var{char_pred}: + +@itemize @bullet +@item +if it is the character @var{ch}, characters equal to +@var{ch} are trimmed, + +@item +if it is a procedure @var{pred} characters that +satisfy @var{pred} are trimmed, + +@item +if it is a character set, characters in that set are trimmed. +@end itemize + +If called without a @var{char_pred} argument, all whitespace is +trimmed. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Modification +@subsection Modification + +The procedure @code{string-fill!} is extended from R5RS because it +accepts optional start/end indices. This bindings shadows the procedure +of the same name in the Guile core. The second modification procedure +@code{string-set!} is documented in the Strings section (@pxref{String +Modification}). + +@deffn primitive string-fill! str chr [start end] +Stores @var{chr} in every element of the given @var{str} and +returns an unspecified value. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Comparison +@subsection Comparison + +The procedures in this section are used for comparing strings in +different ways. The comparison predicates differ from those in R5RS in +that they do not only return @code{#t} or @code{#f}, but the mismatch +index in the case of a true return value. + +@code{string-hash} and @code{string-hash-ci} are for calculating hash +values for strings, useful for implementing fast lookup mechanisms. + +@deffn primitive string-compare s1 s2 proc_lt proc_eq proc_gt [start1 end1 start2 end2] +@deffnx primitive string-compare-ci s1 s2 proc_lt proc_eq proc_gt [start1 end1 start2 end2] +Apply @var{proc_lt}, @var{proc_eq}, @var{proc_gt} to the +mismatch index, depending upon whether @var{s1} is less than, +equal to, or greater than @var{s2}. The mismatch index is the +largest index @var{i} such that for every 0 <= @var{j} < +@var{i}, @var{s1}[@var{j}] = @var{s2}[@var{j}] - that is, +@var{i} is the first position that does not match. The +character comparison is done case-insensitively. +@end deffn + +@deffn primitive string= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string<> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string< s1 s2 [start1 end1 start2 end2] +@deffnx primitive string> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string<= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string>= s1 s2 [start1 end1 start2 end2] +Compare @var{s1} and @var{s2} and return @code{#f} if the predicate +fails. Otherwise, the mismatch index is returned (or @var{end1} in the +case of @code{string=}. +@end deffn + +@deffn primitive string-ci= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci<> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci< s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci> s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci<= s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-ci>= s1 s2 [start1 end1 start2 end2] +Compare @var{s1} and @var{s2} and return @code{#f} if the predicate +fails. Otherwise, the mismatch index is returned (or @var{end1} in the +case of @code{string=}. These are the case-insensitive variants. +@end deffn + +@deffn primitive string-hash s [bound start end] +@deffnx primitive string-hash-ci s [bound start end] +Return a hash value of the string @var{s} in the range 0 @dots{} +@var{bound} - 1. @code{string-hash-ci} is the case-insensitive variant. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Prefixes/Suffixes +@subsection Prefixes/Suffixes + +Using these procedures you can determine whether a given string is a +prefix or suffix of another string or how long a common prefix/suffix +is. + +@deffn primitive string-prefix-length s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-prefix-length-ci s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix-length s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix-length-ci s1 s2 [start1 end1 start2 end2] +Return the length of the longest common prefix/suffix of the two +strings. @code{string-prefix-length-ci} and +@code{string-suffix-length-ci} are the case-insensitive variants. +@end deffn + +@deffn primitive string-prefix? s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-prefix-ci? s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix? s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-suffix-ci? s1 s2 [start1 end1 start2 end2] +Is @var{s1} a prefix/suffix of @var{s2}. @code{string-prefix-ci?} and +@code{string-suffix-ci?} are the case-insensitive variants. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Searching +@subsection Searching + +Use these procedures to find out whether a string contains a given +character or a given substring, or a character from a set of characters. + +@deffn primitive string-index s char_pred [start end] +@deffnx primitive string-index-right s char_pred [start end] +Search through the string @var{s} from left to right (right to left), +returning the index of the first (last) occurence of a character which + +@itemize @bullet +@item +equals @var{char_pred}, if it is character, + +@item +satisifies the predicate @var{char_pred}, if it is a +procedure, + +@item +is in the set @var{char_pred}, if it is a character set. +@end itemize +@end deffn + +@deffn primitive string-skip s char_pred [start end] +@deffnx primitive string-skip-right s char_pred [start end] +Search through the string @var{s} from left to right (right to left), +returning the index of the first (last) occurence of a character which + +@itemize @bullet +@item +does not equal @var{char_pred}, if it is character, + +@item +does not satisify the predicate @var{char_pred}, if it is +a procedure. + +@item +is not in the set if @var{char_pred} is a character set. +@end itemize +@end deffn + +@deffn primitive string-count s char_pred [start end] +Return the count of the number of characters in the string +@var{s} which + +@itemize @bullet +@item +equals @var{char_pred}, if it is character, + +@item +satisifies the predicate @var{char_pred}, if it is a procedure. + +@item +is in the set @var{char_pred}, if it is a character set. +@end itemize +@end deffn + +@deffn primitive string-contains s1 s2 [start1 end1 start2 end2] +@deffnx primitive string-contains-ci s1 s2 [start1 end1 start2 end2] +Does string @var{s1} contain string @var{s2}? Return the index +in @var{s1} where @var{s2} occurs as a substring, or false. +The optional start/end indices restrict the operation to the +indicated substrings. + +@code{string-contains-ci} is the case-insensitive variant. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Case Mapping +@subsection Alphabetic Case Mapping + +These procedures convert the alphabetic case of strings. They are +similar to the procedures in the Guile core, but are extended to handle +optional start/end indices. + +@deffn primitive string-upcase s [start end] +@deffnx primitive string-upcase! s [start end] +Upcase every character in @var{s}. @code{string-upcase!} is the +side-effecting variant. +@end deffn + +@deffn primitive string-downcase s [start end] +@deffnx primitive string-downcase! s [start end] +Downcase every character in @var{s}. @code{string-downcase!} is the +side-effecting variant. +@end deffn + +@deffn primitive string-titlecase s [start end] +@deffnx primitive string-titlecase! s [start end] +Upcase every first character in every word in @var{s}, downcase the +other characters. @code{string-titlecase!} is the side-effecting +variant. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Reverse/Append +@subsection Reverse/Append + +One appending procedure, @code{string-append} is the same in R5RS and in +SRFI-13, so it is not redefined. + +@deffn primitive string-reverse str [start end] +@deffnx primitive string-reverse! str [start end] +Reverse the string @var{str}. The optional arguments +@var{start} and @var{end} delimit the region of @var{str} to +operate on. + +@code{string-reverse!} modifies the argument string and returns an +unspecified value. +@end deffn + +@deffn primitive string-append/shared ls @dots{} +Like @code{string-append}, but the result may share memory +with the argument strings. +@end deffn + +@deffn primitive string-concatenate ls +Append the elements of @var{ls} (which must be strings) +together into a single string. Guaranteed to return a freshly +allocated string. +@end deffn + +@deffn primitive string-concatenate/shared ls +Like @code{string-concatenate}, but the result may share memory +with the strings in the list @var{ls}. +@end deffn + +@deffn primitive string-concatenate-reverse ls final_string end +Without optional arguments, this procedure is equivalent to + +@smalllisp +(string-concatenate (reverse ls)) +@end smalllisp + +If the optional argument @var{final_string} is specified, it is +consed onto the beginning to @var{ls} before performing the +list-reverse and string-concatenate operations. If @var{end} +is given, only the characters of @var{final_string} up to index +@var{end} are used. + +Guaranteed to return a freshly allocated string. +@end deffn + +@deffn primitive string-concatenate-reverse/shared ls final_string end +Like @code{string-concatenate-reverse}, but the result may +share memory with the the strings in the @var{ls} arguments. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Fold/Unfold/Map +@subsection Fold/Unfold/Map + +@code{string-map}, @code{string-for-each} etc. are for iterating over +the characters a string is composed of. The fold and unfold procedures +are list iterators and constructors. + +@deffn primitive string-map proc s [start end] +@var{proc} is a char->char procedure, it is mapped over +@var{s}. The order in which the procedure is applied to the +string elements is not specified. +@end deffn + +@deffn primitive string-map! proc s [start end] +@var{proc} is a char->char procedure, it is mapped over +@var{s}. The order in which the procedure is applied to the +string elements is not specified. The string @var{s} is +modified in-place, the return value is not specified. +@end deffn + +@deffn primitive string-fold kons knil s [start end] +@deffnx primitive string-fold-right kons knil s [start end] +Fold @var{kons} over the characters of @var{s}, with @var{knil} as the +terminating element, from left to right (or right to left, for +@code{string-fold-right}). @var{kons} must expect two arguments: The +actual character and the last result of @var{kons}' application. +@end deffn + +@deffn primitive string-unfold p f g seed [base make_final] +@deffnx primitive string-unfold-right p f g seed [base make_final] +These are the fundamental string constructors. +@itemize @bullet +@item @var{g} is used to generate a series of @emph{seed} +values from the initial @var{seed}: @var{seed}, (@var{g} +@var{seed}), (@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}), +@dots{} +@item @var{p} tells us when to stop - when it returns true +when applied to one of these seed values. +@item @var{f} maps each seed value to the corresponding +character in the result string. These chars are assembled into the +string in a left-to-right (right-to-left) order. +@item @var{base} is the optional initial/leftmost (rightmost) + portion of the constructed string; it default to the empty string. +@item @var{make_final} is applied to the terminal seed +value (on which @var{p} returns true) to produce the final/rightmost +(leftmost) portion of the constructed string. It defaults to +@code{(lambda (x) "")}. +@end itemize +@end deffn + +@deffn primitive string-for-each proc s [start end] +@var{proc} is mapped over @var{s} in left-to-right order. The +return value is not specified. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Replicate/Rotate +@subsection Replicate/Rotate + +These procedures are special substring procedures, which can also be +used for replicating strings. They are a bit tricky to use, but +consider this code fragment, which replicates the input string +@code{"foo"} so often that the resulting string has a length of six. + +@lisp +(xsubstring "foo" 0 6) +@result{} +"foofoo" +@end lisp + +@deffn primitive xsubstring s from [to start end] +This is the @emph{extended substring} procedure that implements +replicated copying of a substring of some string. + +@var{s} is a string, @var{start} and @var{end} are optional +arguments that demarcate a substring of @var{s}, defaulting to +0 and the length of @var{s}. Replicate this substring up and +down index space, in both the positive and negative directions. +@code{xsubstring} returns the substring of this string +beginning at index @var{from}, and ending at @var{to}, which +defaults to @var{from} + (@var{end} - @var{start}). +@end deffn + +@deffn primitive string-xcopy! target tstart s sfrom [sto start end] +Exactly the same as @code{xsubstring}, but the extracted text +is written into the string @var{target} starting at index +@var{tstart}. The operation is not defined if @code{(eq? +@var{target} @var{s})} or these arguments share storage - you +cannot copy a string on top of itself. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Miscellaneous +@subsection Miscellaneous + +@code{string-replace} is for replacing a portion of a string with +another string and @code{string-tokenize} splits a string into a list of +strings, breaking it up at a specified character. + +@deffn primitive string-replace s1 s2 [start1 end1 start2 end2] +Return the string @var{s1}, but with the characters +@var{start1} @dots{} @var{end1} replaced by the characters +@var{start2} @dots{} @var{end2} from @var{s2}. +@end deffn + +@deffn primitive string-tokenize s [token_char start end] +Split the string @var{s} into a list of substrings, where each +substring is a maximal non-empty contiguous sequence of +characters equal to the character @var{token_char}, or +whitespace, if @var{token_char} is not given. If +@var{token_char} is a character set, it is used for finding the +token borders. +@end deffn + + +@c =================================================================== + +@node SRFI-13 Filtering/Deleting +@subsection Filtering/Deleting + +@dfn{Filtering} means to remove all characters from a string which do +not match a given criteria, @dfn{deleting} means the opposite. + +@deffn primitive string-filter s char_pred [start end] +Filter the string @var{s}, retaining only those characters that +satisfy the @var{char_pred} argument. If the argument is a +procedure, it is applied to each character as a predicate, if +it is a character, it is tested for equality and if it is a +character set, it is tested for membership. +@end deffn + +@deffn primitive string-delete s char_pred [start end] +Filter the string @var{s}, retaining only those characters that +do not satisfy the @var{char_pred} argument. If the argument +is a procedure, it is applied to each character as a predicate, +if it is a character, it is tested for equality and if it is a +character set, it is tested for membership. +@end deffn + + +@node SRFI-14 +@section SRFI-14 - Character-set Library + +SRFI-14 defines the data type @dfn{character set}, and also defines a +lot of procedures for handling this character type, and a few standard +character sets like whitespace, alphabetic characters and others. + +All procedures from SRFI-14 (character-set library) are implemented in +the module @code{(srfi srfi-14)}, as well as the standard variables +@code{char-set:letter}, @code{char-set:digit} etc. + +@menu +* Loading SRFI-14:: How to make charsets available. +* SRFI-14 Character Set Data Type:: Underlying data type for charsets. +* SRFI-14 Predicates/Comparison:: Charset predicates. +* SRFI-14 Iterating Over Character Sets:: Enumerate charset elements. +* SRFI-14 Creating Character Sets:: Makeing new charsets. +* SRFI-14 Querying Character Sets:: Test charsets for membership etc. +* SRFI-14 Character-Set Algebra:: Calculating new charsets. +* SRFI-14 Standard Character Sets:: Variables containing predefined charsets. +@end menu + + +@node Loading SRFI-14 +@subsection Loading SRFI-14 + +When Guile is properly installed, SRFI-14 support can be loaded into a +running Guile by using the @code{(srfi srfi-14)} module. + +@example +$ guile +guile> (use-modules (srfi srfi-14)) +guile> (char-set-union (char-set #\f #\o #\o) (string->char-set "bar")) +#<charset @{#\a #\b #\f #\o #\r@}> +guile> +@end example + + +@node SRFI-14 Character Set Data Type +@subsection Character Set Data Type + +The data type @dfn{charset} implements sets of characters +(@pxref{Characters}). Because the internal representation of character +sets is not visible to the user, a lot of procedures for handling them +are provided. + +Character sets can be created, extended, tested for the membership of a +characters and be compared to other character sets. + +The Guile implementation of character sets deals with 8-bit characters. +In the standard variables, only the ASCII part of the character range is +really used, so that for example @dfn{Umlaute} and other accented +characters are not considered to be letters. In the future, as Guile +may get support for international character sets, this will change, so +don't rely on these ``features''. + + +@c =================================================================== + +@node SRFI-14 Predicates/Comparison +@subsection Predicates/Comparison + +Use these procedures for testing whether an object is a character set, +or whether several character sets are equal or subsets of each other. +@code{char-set-hash} can be used for calculating a hash value, maybe for +usage in fast lookup procedures. + +@deffn primitive char-set? obj +Return @code{#t} if @var{obj} is a character set, @code{#f} +otherwise. +@end deffn + +@deffn primitive char-set= cs1 @dots{} +Return @code{#t} if all given character sets are equal. +@end deffn + +@deffn primitive char-set<= cs1 @dots{} +Return @code{#t} if every character set @var{cs}i is a subset +of character set @var{cs}i+1. +@end deffn + +@deffn primitive char-set-hash cs [bound] +Compute a hash value for the character set @var{cs}. If +@var{bound} is given and not @code{#f}, it restricts the +returned value to the range 0 @dots{} @var{bound - 1}. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Iterating Over Character Sets +@subsection Iterating Over Character Sets + +Character set cursors are a means for iterating over the members of a +character sets. After creating a character set cursor with +@code{char-set-cursor}, a cursor can be dereferenced with +@code{char-set-ref}, advanced to the next member with +@code{char-set-cursor-next}. Whether a cursor has passed past the last +element of the set can be checked with @code{end-of-char-set?}. + +Additionally, mapping and (un-)folding procedures for character sets are +provided. + +@deffn primitive char-set-cursor cs +Return a cursor into the character set @var{cs}. +@end deffn + +@deffn primitive char-set-ref cs cursor +Return the character at the current cursor position +@var{cursor} in the character set @var{cs}. It is an error to +pass a cursor for which @code{end-of-char-set?} returns true. +@end deffn + +@deffn primitive char-set-cursor-next cs cursor +Advance the character set cursor @var{cursor} to the next +character in the character set @var{cs}. It is an error if the +cursor given satisfies @code{end-of-char-set?}. +@end deffn + +@deffn primitive end-of-char-set? cursor +Return @code{#t} if @var{cursor} has reached the end of a +character set, @code{#f} otherwise. +@end deffn + +@deffn primitive char-set-fold kons knil cs +Fold the procedure @var{kons} over the character set @var{cs}, +initializing it with @var{knil}. +@end deffn + +@deffn primitive char-set-unfold p f g seed [base_cs] +@deffnx primitive char-set-unfold! p f g seed base_cs +This is a fundamental constructor for character sets. +@itemize @bullet +@item @var{g} is used to generate a series of ``seed'' values +from the initial seed: @var{seed}, (@var{g} @var{seed}), +(@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}), @dots{} +@item @var{p} tells us when to stop -- when it returns true +when applied to one of the seed values. +@item @var{f} maps each seed value to a character. These +characters are added to the base character set @var{base_cs} to +form the result; @var{base_cs} defaults to the empty set. +@end itemize + +@code{char-set-unfold!} is the side-effecting variant. +@end deffn + +@deffn primitive char-set-for-each proc cs +Apply @var{proc} to every character in the character set +@var{cs}. The return value is not specified. +@end deffn + +@deffn primitive char-set-map proc cs +Map the procedure @var{proc} over every character in @var{cs}. +@var{proc} must be a character -> character procedure. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Creating Character Sets +@subsection Creating Character Sets + +New character sets are produced with these procedures. + +@deffn primitive char-set-copy cs +Return a newly allocated character set containing all +characters in @var{cs}. +@end deffn + +@deffn primitive char-set char1 @dots{} +Return a character set containing all given characters. +@end deffn + +@deffn primitive list->char-set char_list [base_cs] +@deffnx primitive list->char-set! char_list base_cs +Convert the character list @var{list} to a character set. If +the character set @var{base_cs} is given, the character in this +set are also included in the result. + +@code{list->char-set!} is the side-effecting variant. +@end deffn + +@deffn primitive string->char-set s [base_cs] +@deffnx primitive string->char-set! s base_cs +Convert the string @var{str} to a character set. If the +character set @var{base_cs} is given, the characters in this +set are also included in the result. + +@code{string->char-set!} is the side-effecting variant. +@end deffn + +@deffn primitive char-set-filter pred cs [base_cs] +@deffnx primitive char-set-filter! pred cs base_cs +Return a character set containing every character from @var{cs} +so that it satisfies @var{pred}. If provided, the characters +from @var{base_cs} are added to the result. + +@code{char-set-filter!} is the side-effecting variant. +@end deffn + +@deffn primitive ucs-range->char-set lower upper [error? base_cs] +@deffnx primitive uce-range->char-set! lower upper error? base_cs +Return a character set containing all characters whose +character codes lie in the half-open range +[@var{lower},@var{upper}). + +If @var{error} is a true value, an error is signalled if the +specified range contains characters which are not contained in +the implemented character range. If @var{error} is @code{#f}, +these characters are silently left out of the resultung +character set. + +The characters in @var{base_cs} are added to the result, if +given. + +@code{ucs-range->char-set!} is the side-effecting variant. +@end deffn + +@deffn procedure ->char-set x +Coerce @var{x} into a character set. @var{x} may be a string, a +character or a character set. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Querying Character Sets +@subsection Querying Character Sets + +Access the elements and other information of a character set with these +procedures. + +@deffn primitive char-set-size cs +Return the number of elements in character set @var{cs}. +@end deffn + +@deffn primitive char-set-count pred cs +Return the number of the elements int the character set +@var{cs} which satisfy the predicate @var{pred}. +@end deffn + +@deffn primitive char-set->list cs +Return a list containing the elements of the character set +@var{cs}. +@end deffn + +@deffn primitive char-set->string cs +Return a string containing the elements of the character set +@var{cs}. The order in which the characters are placed in the +string is not defined. +@end deffn + +@deffn primitive char-set-contains? cs char +Return @code{#t} iff the character @var{ch} is contained in the +character set @var{cs}. +@end deffn + +@deffn primitive char-set-every pred cs +Return a true value if every character in the character set +@var{cs} satisfies the predicate @var{pred}. +@end deffn + +@deffn primitive char-set-any pred cs +Return a true value if any character in the character set +@var{cs} satisfies the predicate @var{pred}. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Character-Set Algebra +@subsection Character-Set Algebra + +Character sets can be manipulated with the common set algebra operation, +such as union, complement, intersection etc. All of these procedures +provide side-effecting variants, which modify their character set +argument(s). + +@deffn primitive char-set-adjoin cs char1 @dots{} +@deffnx primitive char-set-adjoin! cs char1 @dots{} +Add all character arguments to the first argument, which must +be a character set. +@end deffn + +@deffn primitive char-set-delete cs char1 @dots{} +@deffnx primitive char-set-delete! cs char1 @dots{} +Delete all character arguments from the first argument, which +must be a character set. +@end deffn + +@deffn primitive char-set-complement cs +@deffnx primitive char-set-complement! cs +Return the complement of the character set @var{cs}. +@end deffn + +@deffn primitive char-set-union cs1 @dots{} +@deffnx primitive char-set-union! cs1 @dots{} +Return the union of all argument character sets. +@end deffn + +@deffn primitive char-set-intersection cs1 @dots{} +@deffnx primitive char-set-intersection! cs1 @dots{} +Return the intersection of all argument character sets. +@end deffn + +@deffn primitive char-set-difference cs1 @dots{} +@deffnx primitive char-set-difference! cs1 @dots{} +Return the difference of all argument character sets. +@end deffn + +@deffn primitive char-set-xor cs1 @dots{} +@deffnx primitive char-set-xor! cs1 @dots{} +Return the exclusive-or of all argument character sets. +@end deffn + +@deffn primitive char-set-diff+intersection cs1 @dots{} +@deffnx primitive char-set-diff+intersection! cs1 @dots{} +Return the difference and the intersection of all argument +character sets. +@end deffn + + +@c =================================================================== + +@node SRFI-14 Standard Character Sets +@subsection Standard Character Sets + +In order to make the use of the character set data type and procedures +useful, several predefined character set variables exist. + +@defvar char-set:lower-case +All lower-case characters. +@end defvar + +@defvar char-set:upper-case +All upper-case characters. +@end defvar + +@defvar char-set:title-case +This is empty, because ASCII has no titlecase characters. +@end defvar + +@defvar char-set:letter +All letters, e.g. the union of @code{char-set:lower-case} and +@code{char-set:upper-case}. +@end defvar + +@defvar char-set:digit +All digits. +@end defvar + +@defvar char-set:letter+digit +The union of @code{char-set:letter} and @code{char-set:digit}. +@end defvar + +@defvar char-set:graphic +All characters which would put ink on the paper. +@end defvar + +@defvar char-set:printing +The union of @code{char-set:graphic} and @code{char-set:whitespace}. +@end defvar + +@defvar char-set:whitespace +All whitespace characters. +@end defvar + +@defvar char-set:blank +All horizontal whitespace characters, that is @code{#\space} and +@code{#\tab}. +@end defvar + +@defvar char-set:iso-control +The ISO control characters with the codes 0--31 and 127. +@end defvar + +@defvar char-set:punctuation +The characters @code{!"#%&'()*,-./:;?@@[\\]_@{@}} +@end defvar + +@defvar char-set:symbol +The characters @code{$+<=>^`|~}. +@end defvar + +@defvar char-set:hex-digit +The hexadecimal digits @code{0123456789abcdefABCDEF}. +@end defvar + +@defvar char-set:ascii +All ASCII characters. +@end defvar + +@defvar char-set:empty +The empty character set. +@end defvar + +@defvar char-set:full +This character set contains all possible characters. +@end defvar + +@node SRFI-16 +@section SRFI-16 - case-lambda + +@c FIXME::martin: Review me! + +The syntactic form @code{case-lambda} creates procedures, just like +@code{lambda}, but has syntactic extensions for writing procedures of +varying arity easier. + +The syntax of the @code{case-lambda} form is defined in the following +EBNF grammar. + +@example +@group +<case-lambda> + --> (case-lambda <case-lambda-clause>) +<case-lambda-clause> + --> (<formals> <definition-or-command>*) +<formals> + --> (<identifier>*) + | (<identifier>* . <identifier>) + | <identifier> +@end group +@end example + +The value returned by a @code{case-lambda} form is a procedure which +matches the number of actual arguments against the formals in the +various clauses, in order. @dfn{Formals} means a formal argument list +just like with @code{lambda} (@pxref{Lambda}). The first matching clause +is selected, the corresponding values from the actual parameter list are +bound to the variable names in the clauses and the body of the clause is +evaluated. If no clause matches, an error is signalled. + +The following (silly) definition creates a procedure @var{foo} which +acts differently, depending on the number of actual arguments. If one +argument is given, the constant @code{#t} is returned, two arguments are +added and if more arguments are passed, their product is calculated. + +@lisp +(define foo (case-lambda + ((x) #t) + ((x y) (+ x y)) + (z + (apply * z)))) +(foo 'bar) +@result{} +#t +(foo 2 4) +@result{} +6 +(foo 3 3 3) +@result{} +27 +(foo) +@result{} +1 +@end lisp + +The last expression evaluates to 1 because the last clause is matched, +@var{z} is bound to the empty list and the following multiplication, +applied to zero arguments, yields 1. + + +@node SRFI-17 +@section SRFI-17 - Generalized set! + +This is an implementation of SRFI-17: Generalized set! + +It exports the Guile procedure @code{make-procedure-with-setter} under +the SRFI name @code{getter-with-setter} and exports the standard +procedures @code{car}, @code{cdr}, @dots{}, @code{cdddr}, +@code{string-ref} and @code{vector-ref} as procedures with setters, as +required by the SRFI. + +SRFI-17 was heavily criticized during its discussion period but it was +finalized anyway. One issue was its concept of globally associating +setter @dfn{properties} with (procedure) values, which is non-Schemy. +For this reason, this implementation chooses not to provide a way to set +the setter of a procedure. In fact, @code{(set! (setter @var{proc}) +@var{setter})} signals an error. The only way to attach a setter to a +procedure is to create a new object (a @dfn{procedure with setter}) via +the @code{getter-with-setter} procedure. This procedure is also +specified in the SRFI. Using it avoids the described problems. + diff --git a/doc/ref/tcltk.texi b/doc/ref/tcltk.texi new file mode 100644 index 000000000..efc38ea9d --- /dev/null +++ b/doc/ref/tcltk.texi @@ -0,0 +1,3 @@ +@page +@node Tcl/Tk Interface +@chapter Tcl/Tk Interface |