This is bigloo.info, produced by makeinfo version 6.8 from bigloo.texi.

INFO-DIR-SECTION Programming Language
START-INFO-DIR-ENTRY
* bigloo 4.4c: (bigloo).  The Bigloo Scheme compiler
END-INFO-DIR-ENTRY

4.4c

  This file documents Bigloo, an implementation of an extended version
of the Scheme programming language.

  Copyright (C) 1992-99, 2000-17 Manuel Serrano

     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 of the License, 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 program; if not, write to the Free
     Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
     MA 02111-1307, USA.


File: bigloo.info,  Node: Top,  Next: Acknowledgements,  Prev: (dir),  Up: (dir)

Bigloo 4.4c, January 2022


                                         ,-^,
                                   _ ___/ /|/
                               ,;'( )__, ) '
                              ;;  //   L__.
                              '   \    /  '
                                   ^   ^



* Menu:

* Acknowledgements::               Brief history and helpers
* Overview::                       A brief summary of Bigloo facilities
* Modules::                        Modules description
* Core Language::                  Syntax, expressions and definitions
* DSSSL Support::                  DSSSL keyword and optional arguments
* Standard Library::               The Bigloo standard library
* Pattern Matching::               Non linear Bigloo pattern matching
* Fast search::                    Fast string search algorithms.
* Structures and Records::         Various Record data types.
* Object System::                  Documentation for the Bigloo object layer
* Regular Parsing::                Pre-compiled regular grammars
* Lalr Parsing::                   Pre-compiled Lalr grammars
* Posix Regular Expressions::      Posix Regular Expressions
* Command Line Parsing::           Parsing binaries command line invocation
* Cryptography::                   Cryptography
* Errors Assertions and Traces::   Bigloo error handling and Bigloo assertions
* Threads::                        Bigloo multi-threading
* Database::                       Database access
* Multimedia::                     Multimedia programming
* Mail::                           Mail related technologies
* Text::                           Text processing facilities
* CSV::                            Spreadsheet parsers
* Eval::                           Use of the interpreter
* Macro Expansion::                The two available macro schemes
* Parameters::                     Controlling the global programs behaviors
* Explicit Typing::                Improving the compiler's code quality
* C Interface::                    Interfacing to C
* Java Interface::                 Interfacing to Java
* SRFIs::                          SRFIs supported by Bigloo
* Bigloo Libraries::               Creating and using your own libraries
* Extending the Runtime System::   Adding new primitive data types
* Compiler Description::           Interfacing with the compiler
* Cross Compilation::              Compiling for different platforms
* User Extensions::                User compiler extensions
* Bee::                            The Bigloo development environment
* Global Index::                   Global Bigloo document index
* Library Index::                  Index for forms, functions and variables
* Bibliography::


File: bigloo.info,  Node: Acknowledgements,  Next: Overview,  Prev: Top,  Up: Top

Acknowledgements
****************

Bigloo has been developed at Inria-Rocquencourt by the Icsla team from
1991 to 1994, at the University of Montreal in 1995 and at Digital's
Western Research laboratory in 1996, University of Geneva during 1997
and from the end of 1997 at the University of Nice.

  I would like to express my gratitude to _Hans J. Boehm_ for his
Garbage Collector [BoehmWeiser88, Boehm91], _Jean-Marie Geffroy_ for his
pattern-matching compiler [QueinnecGeffroy92], _Dominique Boucher_ for
his Lalr grammar compiler, _William Clinger_ for his syntax expansion
implementation and _Dorai Sitaram_ for his contribution with the
'pregexp' package and its documentation.  I also especially thank
_Christian Queinnec_ for all his useful remarks, help, suggestions and
teaching.

  Other people have helped me by providing useful remarks, bug fixes or
code improvements.  I thank all of them and especially _Luc Moreau_,
_John Gerard Malecki_, _David Halls_ and _David Gurr_.

  I thank _Barrie Stott_ for his help in making much of the
documentation more idiomatic.  Of course, any remaining errors are still
mine.

  This release of Bigloo may still contain bugs.  If you notice any,
please forgive me and send a mail message to the following address:
<bigloo@sophia.inria.fr>.

  This is Bigloo documentation version 4.4c, January 2022.


File: bigloo.info,  Node: Overview,  Next: Modules,  Prev: Acknowledgements,  Up: Top

1 Overview of Bigloo
********************

Bigloo is an implementation of an extended version of the Scheme
programming language.  Without its extensions Bigloo does not entirely
conform to Scheme as defined in the Revised(5) Report on on the
Algorithmic Language Scheme (henceforth R5RS) (*note (r5rs.info)Top::).
The two reasons are:

   * Bigloo produces C files.  C code uses the C stack, so some programs
     can't be properly tail recursive.  Nevertheless all simple tail
     recursions are compiled without stack consumption.

   * Alternatively, Bigloo may produce JVM (Java Virtual Machine byte
     code) class files.  These classes may use regular Java classes.

   * Bigloo is a module compiler.  It compiles modules into '.o' or
     '.class' files that must be linked together to produce stand alone
     executable programs or JVM jar files.

  However, we designed Bigloo to be as close as possible to the R5RS.
Hence, when Bigloo includes a feature that is extracted from Scheme and
implemented as normal, this feature is only mentioned in this document
and not fully described.

1.1 SRFI
========

The Bigloo version 4.4c supports the following SRFIs:

   * 'srfi-0' (conditional execution).
   * 'srfi-2' (AND-LET*: an AND with local bindings, a guarded LET*
     special form).
   * 'srfi-6' (Basic String Ports).
   * 'srfi-8' (Binding to multiple values).
   * 'srfi-9' (_Records_ specification).
   * 'srfi-18' (Multithreading support).
   * 'srfi-22' (script interpreter invocation).
   * 'srfi-28' (Basic Format Strings).
   * 'srfi-30' (Multi-line comments).

1.2 Separate compilation
========================

To allow and stimulate separate compilation, Bigloo compiles modules
instead of entire programs.  A module is composed of a module
declaration and a module body, where a module body can be thought of as
an incomplete Scheme program.

  Bigloo strictly enforces variable bindings.  That is, it is illegal in
a body to refer to unbound variables.

  In a module declaration, some variables can be declared to be
immutable functions.  For such variables, the compiler can then check if
the number of arguments for some function calls are correct or not.
When an arity mismatch is detected, Bigloo signals an error and aborts
the compilation process.

1.3 C interface
===============

The goal of the design of Bigloo is to allow the merging of high and low
level programming.  This means that Bigloo is designed to be fully
connected to the already existing outside world of C.

  This connection has two components: a function call interface and a
data storage interface.  Bigloo code is able to call C code and vice
versa; Bigloo data storage is accessible from C and vice versa.  There
are no frontiers between the Bigloo and C worlds.  See *note C
Interface:: for details.

1.4 Java interface
==================

Since release 2.3, Bigloo is able to produce Java Virtual Machine byte
codes in addition to C code.  By producing class files, it is possible
to connect Scheme code and Java code in the same spirit as the Scheme
and C connection.

  This connection has two components: a function call interface and a
data storage interface.  Bigloo code is able to call Java code and vice
versa; Bigloo data storage is accessible from Java and vice versa.
There are no frontiers between the Bigloo and Java worlds.  See *note
Java Interface:: for extra details.

1.5 Object language
===================

Since release 1.9, Bigloo has included an object system.  This system
belongs to the CLOS [Bobrow et al.  88] object system family but whose
design has been mainly inspired by C. Queinnec's MEROON [Queinnec93].
It is based on _ad-hoc_ polymorphism (generic functions and methods),
uses single inheritance and mono-dispatch, and provides the user with
introspection facilities.

1.6 Threads
===========

Since release 2.4d, Bigloo supports multi-threading.  It fully supports
posix threads (preemptive threads) and fair threads (cooperative
threads).

1.7 SQL
=======

Since release 2.7b, Bigloo includes a SQL binding.  Namely, the C Bigloo
runtime system can access the facilities offered by SQLite
(<http://www.sqlite.org/>).

1.8 Type annotations
====================

Type information, related to variable or function definitions, can be
added to the source code.  If no type information is provided, runtime
checks will be introduced by the compiler to ensure normal execution,
provided that the user has not used compilation flags to prevents this.
If type information is added, the compiler statically type checks the
program and refuses ones that prove to be incorrect.

1.9 Unicode support
===================

Bigloo supports UCS-2 Character encoding and also provides conversion
functions between UTF-8 and UCS-2.  It still maintains traditional
ISO-LATIN1 characters and strings.

1.10 DSSSL
==========

Bigloo helps the DSSSL programmer by supporting keywords, named
constants and keyword functions.


File: bigloo.info,  Node: Modules,  Next: Core Language,  Prev: Overview,  Up: Top

2 Modules
*********

A modules is a compiler and interpreter entity.  Modules have been first
designed for the compiler that compiles modules and then, links them
against libraries in order to produce executables.  A module may be
split into several files but a file cannot contain more than _one_
module.  A module is made of a module clause that is a list for which
the 'car' is the symbol 'module' and followed by any Bigloo expression
(that is definitions or expressions).  The module clause names the
module and defines the scope of the definitions.  At last, the module
clause is also the place where foreign bindings are defined and where
classes are defined.  Recent versions of Bigloo (since 2.7b) fully
supports modules from the interpreter.

* Menu:

* Program Structure::
* Module Declaration::
* Module Initialization::
* Qualified Notation::
* Inline Procedures::
* Module Access File::
* Reading Path::


File: bigloo.info,  Node: Program Structure,  Next: Module Declaration,  Prev: Modules,  Up: Modules

2.1 Program Structure
=====================

A Bigloo program is composed of one or more Bigloo modules where a
module is defined by the following grammar:

     <module>             ==> <module-declaration> <module-body>
     <module-declaration> ==> the module declaration
     <module-body>        ==> the module body

  A module is not related to a specific file and can be spread over
several files if that is convenient.  In particular, there is no
relationship between module names and file names.  The module
declaration (see *note Module Declaration::) must be the first
expression in the first of the files containing the module; other
expressions form the body of the module.  The module body (see *note
Core Language::) contains global variables, function definitions and
_top level_ expressions (see *note Expressions::).


File: bigloo.info,  Node: Module Declaration,  Next: Module Initialization,  Prev: Program Structure,  Up: Modules

2.2 Module declaration
======================

The module declaration form is

 -- bigloo syntax: module name clause ...

     This form defines a module and must be the first in the file.  The
     argument NAME is a symbol naming the module.  If the same module
     name is used more than once, Bigloo signals an error.  The runtime
     library is composed of modules that are read when a user module is
     compiled and hence, if a user module has the same name as one of
     the library modules, an error is signaled.

     A simple module can be:

          (module foo)

          (display "this is a module")

     The first line here is the complete module definition, the last
     line is the complete module body and together they form a complete
     Bigloo program.  If these lines were stored in file 'zz.scm',
     invoking 'bigloo zz.scm' would create the executable 'a.out' which,
     when obeyed, would display 'this is a module' on the terminal.

     _Note_: Some special identifiers are reserved and can't be used to
     name modules.  If such an identifier is used, the compiler will
     produce the message:

          #(module t
          #^
          # *** ERROR:bigloo:TOP-LEVEL:Parse error
          # Illegal module name -- (MODULE eval ...

     The list of reserved identifiers may be enlarged for next release.
     For the current release that list is made of: 'eval', 'foreign' and
     't'.

  Module CLAUSEs can be:

 -- bigloo module clause: main name

     This clause defines the entry point for a stand alone application
     to be procedure NAME of arity one.  Bigloo invokes this procedure
     at the beginning of execution providing the list, composed of the
     shell command line arguments, as its single argument.

          (module foo
             (main start))

          (define (start argv)
             (display argv)
             (newline))

     Then if this program is compiled into 'foo' and invoked using the
     command 'foo -t bar', the list which is the argument for the main
     procedure 'start' would be '("foo" "-t" "bar")'.

     The special form 'args-parse' helps main function argument parsing
     (*note Command Line Parsing::).

 -- bigloo module clause: include file-name ...

     This is a list of FILE-NAMEs to be included in the source file.
     Include files are not modules and may have a special syntax.  Thus,
     besides containing Bigloo expressions, they can contain import and
     include clauses, which must be written in a single list whose first
     element is the keyword 'directives'.  Includes files can be used to
     include implementation-neutral Scheme expressions and definitions
     in a Bigloo module.  Here is an example of an include file.

          ;; 'foo.sch'
          (define-struct point x y)

     and the module that includes the 'foo.sch' file:

          ;; 'foo.scm'
          (module foo
             (include "foo.sch"))

          (print (point 1 2))

     Include files, may contain module information.  This is the role of
     the include 'directives' clause here illustrated with the 'bar.sch'
     example:

          ;; 'bar.sch'
          ;; the directives
          (directives (include "foobar.sch")
                      (import  hux))

          ;; expressions
          (define (gee x) (print x))

 -- bigloo module clause: import import ...

     An IMPORT is a list of the form:

          <import>      ==> <iclause> ...
          <iclause>     ==> (<bind-name> ... <bind-name> <module-name> <file-name> ...)
                          | (<bind-name> ... <bind-name> <module-name>)
                          | <module-name>
                          | (<module-name> <file-name> ...)
          <bind-name>   ==> <r5rs-ident>
                          | <alias-name>
          <alias-name>  ==> (<r5rs-ident> <r5rs-ident>)
          <module-name> ==> <r5rs-ident>
          <file-name>   ==> <string>

     The first alternative in ICLAUSE imports the variable named
     BIND-NAME which is defined in the module MODULE-NAME, located in
     the files FILE-NAME ....  The second does the same but without
     specifying the name of the file where the module is located.  The
     third and the fourth form import all the exported variables of the
     module MODULE-NAME.

     _Note_: The need for specifying in which files modules are located
     comes from the fact that there is no automatic mapping between
     module names and files names.  Such a mapping can be defined in a
     "module access file" (*note Module Access File::) or in the import
     clause itself, as in the first and fourth alternatives in ICLAUSE
     above.

     Here is an example of an import clause:

          (module foo
             (import
                ;; import all 'bar' exported bindings:
                bar
                ;; import the 'hux' binding exported by
                ;; the module 'hux':
                (hux hux)
                ;; import the 'fun1', 'fun2' and 'fun3' bindings exported by
                ;; the module 'mod':
                (fun1 fun2 fun3 mod)
                ;; import the 'fun4' bindings that will be known in this module
                ;; under the alias name 'f'
                ((f fun4) mod)
                ;; import all 'gee' bindings. the 'gee' module
                ;; is located in a file called 'gee.scm':
                (gee "gee.scm")))

 -- bigloo module clause: use use ...

     'use' has the same meaning as 'import' except that modules which
     are _used_ are not initialized (*note Module Initialization::).
     Used modules are read before imported modules.

 -- bigloo module clause: with with ...

     This clause specifies a list of modules which have to be
     initialized at runtime and is used to force the initialization of
     modules which are never imported but which are required by an
     application (*note Embedded Bigloo applications::).

 -- bigloo module clause: export export ...

     In order to make a module's global bindings available to other
     modules, they have to be _exported_.  Export clauses are in charge
     of this task and an EXPORT is a list of the form:

          <export>      ==> <eclause> ...
          <eclause>     ==> <varexport>
                          | <funexport>
                          | <macroexport>
                          | <classexport>
          <varexport>   ==> <ident>
          <funexport>   ==> | (<ident> <ident> ...)
                          | (inline <ident> <ident> ...)
                          | (generic <ident> <ident> <ident> ...)
          <classexport> ==> <class>
          <macroexport> ==> (macro <ident> <ident> ...)
                          | (expander <ident>)
                          | (syntax <ident>)

     Note: Only bindings defined in module 'm' can be _exported_ by 'm'
     (i.e.  bindings _imported_ by 'm' cannot be _exported_ by 'm').

     The first form of VAREXPORT allows the variable IDENT be exported.
     Exported variables are mutable.  That is, modules importing a
     variable can change its value.

     The form FUNEXPORT exports functions.  An exported function is
     read-only.  No module can modify its value.  The prototype of
     exported functions must be explicitly specified.

     Type information, specified in any IDENT in an export clause, is
     used by Bigloo.  Where no type information is given, a default
     generic type named 'obj' is used.

     Note: The last formal argument of a multiple arity function can not
     be typed because this argument is bound to be a 'pair' or 'null'.
     This union cannot be denoted by any type.

     Inline functions (*note Inline Procedures::) prototypes are
     prefixed by the 'inline' keyword.  Pay attention that in order to
     export an inline function, all the variables used in that function
     body must be exported too.  It is an error to export a non-inline
     function using the 'inline' keyword.  Example:

          (module mod-exp
             (export
                ;; export the 'bar' mutable variable
                bar
                ;; export the 'hux' function. this
                ;; function takes exactly two arguments
                (hux x y)
                ;; export the inline function 'gee'
                ;; that takes at least one argument.
                (inline gee x . z)))

     Generic functions (*note Generic functions::) are exported by using
     the 'generic' keyword.  Note that methods are not exported.  Only
     the generic function they are attached to are.  It is an error to
     export a non-generic function using the 'inline' keyword.  Example:

          (module mod-exp-object
             (export
                ;; define tow classes an export them
                (class point2d x y)
                (class point3d::point2d z)
                ;; export a generic function
                (generic show ::point2d ::output-port)))

     It is an error to export an inline or a generic function without
     using the proper keyword.

     The last form MACROEXPORT enables macro and expanders to be
     exported.  The prototype of the macro should be specified on the
     export clause.  Example:

          (module mod-exp-macros
             (export
                ;; exports the "add" macro
                (macro add x y)
                ;; exports the "+" expander
                (expander +)))

          (define-macro (add x y)
             (if (and (number? x) (number? y))
                 (+ x y)
                 `(+ ,x ,y)))

          (define-expander +
             (lambda (x e)
                (match-case x
                   ((+ ?n ?m) (+ n m))
                   (else (map (lambda (z e) (e z e)) x)))))

 -- bigloo module clause: static static ...

     A 'static' clause has exactly the same syntax as an export clause.
     However, bindings declared static are local to the module.  Since
     the default scope of all bindings is static, 'static' module
     clauses are useful only for program documentation.

 -- bigloo module clause: from from ...

     'from' clauses have the syntax of 'import' clauses.  The allow the
     re-exportation of imported bindings.  That is, any module can
     export any bindings imported via a FROM clause.

     As an example, suppose we have module 'bar':

          (module bar
             (export (fun)))

          (define (fun) "bar")

     Now, suppose we have a module 'foo' that imports 'bar', by the
     means of a 'from' clause.  Module 'foo' is able to re-export the
     'bar' binding of module 'bar':

          (module foo
             (from (fun bar "bar.scm")))

     A third module, let's name it 'gee', importing module 'foo', can
     see the binding for function 'bar':

          (module gee
             (import (foo "foo.scm")))

          (print (fun))

     This feature is very useful when compiling modules exporting
     functions with type annotations.  In particular, one may write:

          (module foo
            (export (class c1 x)))

     Then,
          (module bar
            (import foo)
            (from foo)
            (export (fun::c1)))

          (define (fun)
             (instantiate::c1 (x 10)))

     And,

          (module gee
             (import bar)
             (main main))

          (define (main x)
             (let ((o (fun)))
                (print o)
                (print (c1? o))))

 -- bigloo module clause: load load ...

     A LOAD is a list of the form:

          <load>    ==> <lclause> ...
          <lclause> ==> (<module-name> <file-name>)
                      | <module-name>

     This clause forces Bigloo to load the module specified in the
     LCLAUSE in the environment used by the macro expansion mechanism.
     This means that the user's macros can use all the bindings of all
     the 'load'ed modules but the 'load'ed bindings remains unknown to
     the compiler.

     If the module 'foo' is defined by:

          (module foo
             (export (foo x)))

          (define (foo x)
             `(cons ,x ,x))

     then,

          (module gee
             (load (foo "foo.scm")))

          (define-macro (gee x)
             `(cons ,(-fx x 1) ,(foo x)))

          (gee 5)   ==> (cons 4 (cons 5 5))
                    => (4 5 . 5)

 -- bigloo module clause: eval eval...

     This form allows interactions between compiled code and interpreted
     code.  (See the Section *note Eval command line options: Eval. for
     a presentation of compilation flags that enable compilation tuning
     for 'eval'.)  Each EVAL has the following syntax:

          <eval> ==> (export-all)
                   | (export-module)
                   | (export-exports)
                   | (export <bind-name>)
                   | (export (@ <bind-name> <module-name>))
                   | (import <bind-name>)
                   | (class <bind-name>)
                   | (library lib1 ...)

     The first clause, '(export-all)', exports all the variables bound
     in the module (i.e., the variables defined in the module and the
     imported variables).  The second clause, '(export-module)', exports
     the module to eval to so that it can be imported by other evaluated
     modules; the third exports all the exports (i.e.  the ones present
     inside an 'export' clause) variables to the interpreter; the fourth
     and fifth clause each export one variable to the interpreter.  The
     last clause imports a variable from the interpreter and all such
     imported variables are immutable (i.e. they cannot be the first
     argument of a 'set!' expression with the compiled code).  Variables
     that are exported to the evaluators _must_ be exported.  If a
     variable is exported to the evaluators but not exported within an
     'export' clause, the compiler will produce an error message.  The
     'library' clause makes the variables and functions of a library
     accessible from the interpreter.

          (module foo
             (export (fib x))
             (eval (export fib)
                   (import bar)))

          (define (fib x) ...)
          (print bar)

     The clause '(class <bind-name>)' exports a class definition to the
     interpreter.  This makes the class constructor, the class predicate
     and the slots access functions available from the interpreter.  The
     form '(instantiate::CLASS ...)' and '(with-access::CLASS ...)' are
     also available from the interpreter.

 -- bigloo module clause: extern extern ...

     Extern (aka foreign) clauses will be explained in the foreign
     interface (*note C Interface::).

 -- bigloo module clause: java java ...

     Java clauses will be explained in the Java interface (*note Java
     Interface::).

 -- bigloo module clause: option option ...

     This clause enables variables which affect compilation to be set
     from inside a module and since the expressions, OPTION ..., are
     evaluated _when compiling_, no code is compiled for them.  They are
     allowed to make side effects and to change the values of the global
     variables which describe how the compiler must compile.  Usually
     they allow the control variables, which are described when Bigloo
     is invoked with the '-help2' option, to be set as in the following
     example:

          (module examplar
             (option (set! *debug* 3)
                     (set! *verbose* 2)))

          (print 'dummy)

     Whatever arguments are passed on the command line, Bigloo will
     compile this module in both verbose mode and debug mode.

 -- bigloo module clause: library library ...

     This clause enables libraries (*note Bigloo Libraries::) when
     compiling and linking Bigloo modules.  The expressions LIBRARY ...
     are symbols naming the libraries to be used.

     Here is an example of a module declaration which makes use of a
     library named 'format':

          (module test
             (library format)
             (main    test-format)
             (import  (test2 "test2.scm")))

     Using a library does not automatically binds its variables and
     functions to the interpreter.  In order to make these available to
     the interpreter an explicit use of an eval 'library' clause must be
     used.

 -- bigloo module clause: type type ...
     This forms is used to define builtin Bigloo types.  It is not
     recommended to use it in user programs.  So, it is left
     undocumented.


File: bigloo.info,  Node: Module Initialization,  Next: Qualified Notation,  Prev: Module Declaration,  Up: Modules

2.3 Module initialization
=========================

_Initializing_ a module means evaluating, at runtime, its top level
forms (global bindings are top level forms).

  When a module, MODULE1, imports a module, MODULE2, MODULE2 is
initialized before MODULE1.  Modules are initialized only once, nothing
being done if a module already met during initialization is met again.
Library modules are initialized before user modules and imported modules
are initialized in the same order as they appear in import clauses.

  Here is a first example with two modules.  First the module 'foo':

     ;; module foo
     (module foo
        (main main)
        (import (bar "bar.scm")))

     (define (main argv)
        (print "argv: " argv))
     (print "foo")

  Then the module 'bar'
     ;; module bar
     (module bar)

     (print "bar")

  These can be compiled into the executable A.OUT with:
     $ bigloo -c foo.scm
     $ bigloo -c bar.scm
     $ bigloo foo.o bar.o

  Execution of A.OUT produces:
     $ a.out
        -| bar
           foo
           argv: (a.out)

  The explanation is:
   * module 'foo' contains the program entry point so this is where
     initialization begins.
   * because 'foo' imports module 'bar', 'bar' must be initialized
     _before_ 'foo'.  This explains why the word 'bar' is printed before
     anything else.
   * module initialization for 'foo' is completed before 'main' is
     called.  This explains why word 'foo' is printed before 'main' is
     entered.

  Let's consider another example with 3 modules:
     ;; 'module1'
     (module module1
        (main main)
        (import (module2 "module2.scm")))

     (define (main argv)
        (print "argv: " argv))

     (print "module1")

  The second module:
     ;; 'module2'
     (module module2
        (import (module3 "module3.scm")))

     (print "module2")

  The third module:
     ;; 'module3'
     (module module3
        (import (module1 "module1.scm")))

     (print "module3")

  Compile with:
     $ bigloo module1.scm -c
     $ bigloo module2.scm -c
     $ bigloo module3.scm -c
     $ bigloo module1.o module2.o module3.o

  Execution produces:

     $ a.out
        -| module3
           module2
           module1
           argv: (a.out)

  The order of module initialization can be explicitly specified using
'with' and 'use' clauses.


File: bigloo.info,  Node: Qualified Notation,  Next: Inline Procedures,  Prev: Module Initialization,  Up: Modules

2.4 Qualified notation
======================

Global variables can be referenced using implicit notation or using
_qualified_ notation.  Implicit notation is used when variables are
referenced just by their name whereas qualified notation is used when
variables are referenced by their name and the name of the module which
defines them.  Qualified notation has the following syntax:

     (@ <bind-name> <module-name>)

and is useful when several imported modules export a variable with the
same name.  Using qualified notations instead of short notation only
affects compilation.

  When several variables are defined under the same identifier, the
compiler uses the two following rules in order to decide which variable
is selected by an implicit reference: 1) the variable defined in a
module has a higher precedence than all imported variables, 2) imported
variables have a higher precedence than library variables.


File: bigloo.info,  Node: Inline Procedures,  Next: Module Access File,  Prev: Qualified Notation,  Up: Modules

2.5 Inline procedures
=====================

Bigloo allows procedures called _inline_ and which differ from normal
ones only in the type of code planted.  An inline procedure is a first
class object which can be manipulated in the same way as any other
procedure but when Bigloo sees a reference to one, rather than
generating a C function call to the function, the body of the inline
procedure is open-coded.  The definition of an inline is given in the
following way:

 -- bigloo syntax: define-inline (name args ...) body
 -- bigloo syntax: define-inline (name args ... . arg) body

     Apart from the initial word, this form has the same syntax as that
     used by 'define' for procedures.  Inline procedures are exportable
     which means that the compiler scans imported files to find the
     bodies of all inline procedures.  Here is a small example of a
     module which exports an inline and a module which imports it.

          ;; the exporter module
          (module exporter
                  (export (inline make-list . objs)))

          (define-inline (make-list . objs) objs)

          ;; the importer module
          (module importer
                  (import exporter))

          (print (make-list 1 2 3 4 5))

     Because of the open-coding of the exporter procedure, the above
     print statement is equivalent to:

          (print (let ((objs (list 1 2 3 4 5)))
                    objs))

     Any procedure can be an inline.  Also any exported procedure can be
     an inline provided all global variables and functions it uses are
     also exported.

     Note: Bigloo can decide to inline procedures declared with 'define'
     but this can be achieved only with local procedures whereas
     procedures declared with the 'define-inline' form are open-coded
     even through module importation.

     Note: Procedures declared _inline_ are macro expanded with the
     macro defined in the module where they are invoked.  That is, if
     module 'module1' declares an inline procedure 'p' and module
     'module2' imports it, 'p' may have two different macro-expansions:
     one for 'module1' and one for 'module2'.


File: bigloo.info,  Node: Module Access File,  Next: Reading Path,  Prev: Inline Procedures,  Up: Modules

2.6 Module access file
======================

Bigloo is different from languages such as C where a module is defined
by a file.  For Bigloo, the module name is not necessarily the name of
the file where the text of the module is written and modules can even be
split across several files.

  Since modules are defined independently of files, it is necessary to
make a link between a module and its files and there are two ways of
doing this.  Choosing an import clause where the file-names are
specified or creating a "module access file".  Such a file must contain
only one LIST, each element of the list being of the form:

     (module-name "file-name" ... "file-name")

Use the '-afile <file>' option to specify the "module access file" when
compiling.  By default Bigloo checks if a file named '.afile' exists.
If it exists it is loaded as a module access file.

  *Note The Bigloo command line: Compiler Description.

  Note: The Bigloo distribution contains a tool, 'bglafile', that can
automatically build a "module access file".  See the manpage for
'bglafile' for details.


File: bigloo.info,  Node: Reading Path,  Prev: Module Access File,  Up: Modules

2.7 Reading path
================

Imported, included or loaded files are sought first in the current
directory and then in the directories, sequentially from start to end,
of the list in the '*load-path*' variable.  This variable, initially set
to the empty list, can be reset by the '-I' option of the compiler.


File: bigloo.info,  Node: Core Language,  Next: DSSSL Support,  Prev: Modules,  Up: Top

3 Core Language
***************

This chapter presents the Bigloo basics.  It presents the elements that
compose the body of a module (see *note Modules::).

* Menu:

* Syntax::                      Identifiers and typed identifiers
* Comments::                    Bigloo comments
* Expressions::                 Expressions
* Definitions::                 Global definitions


File: bigloo.info,  Node: Syntax,  Next: Comments,  Prev: Core Language,  Up: Core Language

3.1 Syntax
==========

The syntax of Bigloo is that of Scheme (a parenthesis based one) with
two exceptions: type information and multi-line comments.  Type
information is supplied when identifiers are introduced (via 'lambda',
'let', 'define', ...)  and those identifiers holding type information
are referred to as typed identifiers.

  They are defined by the following grammar:

     <ident>        ==> <r5rs-ident> | <typed-ident>
     <typed-ident>  ==> <r5rs-ident>::<r5rs-ident>
     <r5rs-ident>   ==> the standard Scheme identifiers

  For details of the standard Scheme identifiers, see *note token:
(r5rs.info)Lexical structure.

  Multi-lines comments (see <http://srfi.schemers.org/srfi-30/>) are
defined as:

     <ident>        ==> <r5rs-ident> | <typed-ident>
     <comment>      ==> ;<all subsequent characters up to a line break>
            	       | #| <comment-text> (<comment> <comment-text>)* |#
     <comment-text> ==> <character sequence not containing #| or |#>


File: bigloo.info,  Node: Comments,  Next: Expressions,  Prev: Syntax,  Up: Core Language

3.1.1 Comments
--------------

Comments and whitespaces are the same as in *note r5rs.info:
(R5RS)Whitespace and comments.

     ;;; The FACT procedure computes the factorial
     ;;; of a non-negative integer.
     (define fact
       (lambda (n)
         (if (= n 0)
             1        ;; Base case: return 1
             (* n (fact (- n 1))))))

  In addition, Bigloo supports _s-expressions_ comments.  These are
introduced with the '#;' syntax:

     ;;; The FACT procedure computes the factorial
     ;;; of a non-negative integer.
     (define fact
       (lambda (n)
         #;(if (< n 2) 1 (* #;n (fact (- n 1))))
         (if (= n 0)
             1
             (* n (fact (- n 1))))))


File: bigloo.info,  Node: Expressions,  Next: Definitions,  Prev: Comments,  Up: Core Language

3.1.2 Expressions
-----------------

Bigloo expressions are the same as in *note r5rs.info:
(R5RS)Expressions.  Bigloo has more syntactic keywords than Scheme.  The
Bigloo syntactic keywords are:

     =>                      do                    or
     and                     else                  quasiquote
     begin                   if                    quote
     case                    lambda                set!
     cond                    let                   unquote
     unquote-splicing        define                let*
     delay                   letrec                module
     labels                  try                   define-struct
     unwind-protect          bind-exit             define-inline
     regular-grammar         lalr-grammar          regular-search
     define-expander         define-macro          match-case
     match-lambda            pragma                failure
     assert                  define-generic        define-method
     instantiate             duplicate             with-access
     widen!                  shrink!               multiple-value-bind
     let-syntax              letrec-syntax         define-syntax
     cond-expand             receive               args-parse
     define-record-type      and-let*              letrec*

All other non atomic Bigloo forms are evaluated as function calls or
macro class.

 -- syntax: <variable>
 -- syntax: quote datum
 -- syntax: 'datum
 -- syntax: <constant>
          (define x 28)                          =>
          x                                      => 28
          (quote a)                              => A
          (quote #(a b c))                       => #(A B C)
          (quote (+ 1 2))                        => (+ 1 2)
          'a                                     => A
          '#(a b c)                              => #(A B C)
          '()                                    => ()
          '(+ 1 2)                               => (+ 1 2)
          '(quote a)                             => (QUOTE A)
          '"abc"                                 => "abc"
          "abc"                                  => "abc"
          '145932                                => 145932
          145932                                 => 145932
          '#t                                    => #t
          #t                                     => #t

 -- syntax: operator operand ...
          (+ 3 4)                                => 7
          ((if #f + *) 3 4)                      => 12
          ((lambda (x) (+ 1 x)) 5)               => 6

 -- syntax: lambda formals body
          (lambda (x) (+ x x))                   => _a procedure_
          ((lambda (x) (+ x x)) 4)               => 8

          (define reverse-subtract
            (lambda (x y) (- y x)))
          (reverse-subtract 7 10)                => 3

          (define add4
            (let ((x 4))
              (lambda (y) (+ x y))))
          (add4 6)                               => 10

          ((lambda x x) 3 4 5 6)                 => (3 4 5 6)
          ((lambda (x y . z) z)
           3 4 5 6)                              => (5 6)

 -- syntax: if test consequent [alternate]
          (if (> 3 2) 'yes 'no)                  => yes
          (if (> 2 3) 'yes 'no)                  => no
          (if (> 3 2)
              (- 3 2)
              (+ 3 2))                           => 1

 -- syntax: set! variable expression
          (define x 2)
          (+ x 1)                                => 3
          (set! x 4)                             => _unspecified_
          (+ x 1)                                => 5

 -- library syntax: cond clause clause ...

     Bigloo considers 'else' as a keyword.  It thus ignores clauses
     following an 'else'-clause.

          (cond ((> 3 2) 'greater)
                ((< 3 2) 'less))                 => greater

          (cond ((> 3 3) 'greater)
                ((< 3 3) 'less)
                (else 'equal))                   => equal

          (cond ((assv 'b '((a 1) (b 2))) => cadr)
                (else #f))                       => 2

 -- library syntax: case key clause clause ...
          (case (* 2 3)
            ((2 3 5 7) 'prime)
            ((1 4 6 8 9) 'composite))            => composite
          (case (car '(c d))
            ((a) 'a)
            ((b) 'b))                            => _unspecified_
          (case (car '(c d))
            ((a e i o u) 'vowel)
            ((w y) 'semivowel)
            (else 'consonant))                   => consonant

 -- library syntax: and test ...
          (and (= 2 2) (> 2 1))                  => #t
          (and (= 2 2) (< 2 1))                  => #f
          (and 1 2 'c '(f g))                    => (f g)
          (and)                                  => #t

 -- bigloo syntax: and-let* test ...

          (and-let* ((x 1) (y 2)) (cons x y))    => (1 . 2)
          (and-let* ((x 1) (z #f)) x)            => #f

          (and-let* ((my-list (compute-list)) ((not (null? my-list))))
                    (do-something my-list))

          (define (look-up key alist)
            (and-let* ((x (assq key alist))) (cdr x)))

          (or (and-let* ((c (read-char))
                         ((not (eof-object? c))))
                        (string-set! some-str i c)
                        (set! i (+ 1 i)))

 -- library syntax: or test ...
          (or (= 2 2) (> 2 1))                   => #t
          (or (= 2 2) (< 2 1))                   => #t
          (or #f #f #f)                          => #f
          (or (memq 'b '(a b c))
              (/ 3 0))                           => (b c)

 -- library syntax: let [name] (binding ...) body
          (let ((x 2) (y 3))
            (* x y))                             => 6

          (let ((x 2) (y 3))
            (let ((x 7)
                  (z (+ x y)))
              (* z x)))                          => 35

          (let loop ((l '(1 2 3)))
             (if (null? l)
                 '()
                 (cons (+ 1 (car l))
                       (loop (cdr l)))))         => (2 3 4)

     If a BINDING is a symbol, then, it introduces a variable bound to
     the '#unspecified' value.

          (let (x)
             x)                                 => #unspecified

     Bigloo's named let differs from R5Rs named let because NAME is
     bound in BINDING.  That is,

          (let ((l 'a-symbol))
            (let l ((x l))
               x))                               => #<procedure>

     while R5Rs states that,

          (let ((l 'a-symbol))
            (let l ((x l))
               x))                               => a-symbol

 -- library syntax: let* (binding ...) body
          (let ((x 2) (y 3))
            (let* ((x 7)
                   (z (+ x y)))
              (* z x)))                          => 70

 -- library syntax: letrec (binding ...) body
          (letrec ((even?
                    (lambda (n)
                      (if (zero? n)
                          #t
                          (odd? (- n 1)))))
                   (odd?
                    (lambda (n)
                      (if (zero? n)
                          #f
                          (even? (- n 1))))))
            (even? 88))
                                                 => #t

 -- bigloo syntax: letrec* (binding ...) body

     Each binding has the form

          ((<variable1> <init1>) ...)

     Each '<init>' is an expression.Any variable must not appear more
     than once in the '<variable>'s.

     The '<variable>'s are bound to fresh locations, each <variable> is
     assigned in left-to-right order to the result of evaluating the
     corresponding '<init>', the '<body>' is evaluated in the resulting
     environment, and the values of the last expression in <body> are
     returned.  Despite the left-to-right evaluation and assignment
     order, each binding of a <variable> has the entire letrec*
     expression as its region, making it possible to define mutually
     recursive procedures.

     Examples:

          (letrec* ((x 1)
                    (f (lambda (y) (+ x y))))
             (f 3))
                                                 => 4
          (letrec* ((p (lambda (x)
                          (+ 1 (q (- x 1)))))
                    (q (lambda (y)
                          (if (zero? y)
                              0
                              (+ 1 (p (- y 1))))))
                    (x (p 5))
                    (y x))
            y)
                                                 => 5

     It must be possible to evaluate each '<init>' without assigning or
     referring to the value of the corresponding <variable> or the
     '<variable>' of any of the bindings that follow it in <bindings>.
     Another restriction is that the continuation of each '<init>'
     should not be invoked more than once.

 -- bigloo syntax: labels ((name (arg ...) body) ...) body
     The syntax is similar to the Common Lisp one [Steele90], where
     created bindings are immutable.

          (labels ((loop (f l acc)
                         (if (null? l)
                             (reverse! acc)
                             (loop f (cdr l) (cons (f (car l)) acc)))))
             (loop (lambda (x) (+ 1 x)) (list 1 2 3) '()))
             => (2 3 4)

 -- library syntax: begin expression expression ...
          (define x 0)

          (begin (set! x 5)
                 (+ x 1))                        => 6

          (begin (display "4 plus 1 equals ")
                 (display (+ 4 1)))              => _unspecified_
                                                 -| 4 plus 1 equals 5

 -- library syntax: do ((variable init step) ...) (test expression ...)
          body
          (do ((vec (make-vector 5))
               (i 0 (+ i 1)))
              ((= i 5) vec)
            (vector-set! vec i i))               => #(0 1 2 3 4)

          (let ((x '(1 3 5 7 9)))
            (do ((x x (cdr x))
                 (sum 0 (+ sum (car x))))
                ((null? x) sum)))                => 25

 -- library syntax: delay expression

 -- syntax: quasiquote template
 -- syntax: ` template
          `(list ,(+ 1 2) 4)                     => (list 3 4)
          (let ((name 'a)) `(list ,name ',name))
                    => (list a (quote a))
          `(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)
                    => (a 3 4 5 6 b)
          `(('foo' ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))
                    => ((foo 7) . cons)
          `#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8)
                    => #(10 5 2 4 3 8)
          `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
                    => (a `(b ,(+ 1 2) ,(foo 4 d) e) f)
          (let ((name1 'x)
                (name2 'y))
            `(a `(b ,,name1 ,',name2 d) e))
                    => (a `(b ,x ,'y d) e)
          (quasiquote (list (unquote (+ 1 2)) 4))
                    => (list 3 4)
          '(quasiquote (list (unquote (+ 1 2)) 4))
                    => `(list ,(+ 1 2) 4)
               __i.e., (quasiquote (list (unquote (+ 1 2)) 4))


File: bigloo.info,  Node: Definitions,  Prev: Expressions,  Up: Core Language

3.1.3 Definitions
-----------------

Global bindings are introduced by the 'define' form:
 -- syntax: define variable expression
 -- syntax: define (variable arg ...) body
          (define add3
            (lambda (x) (+ x 3)))
          (add3 3)                               => 6
          (define first car)
          (first '(1 2))                         => 1

  *Note r5rs.info: Definitions, for more details.  The Bigloo module
language (See *note Module Declaration::) enables _exports_ and
_imports_ of global definitions.


File: bigloo.info,  Node: DSSSL Support,  Next: Standard Library,  Prev: Core Language,  Up: Top

4 DSSSL support
***************

Bigloo supports extensions for the DSSSL expression language [Dsssl96]:

   * Keywords.  Bigloo supports full Dsssl keywords.
   * Named constants.  Bigloo implements the three DSSSL named
     constants: '#!optional', '#!rest' and '#!key'.
   * Dsssl formal argument lists.

  In addition, Bigloo extends DSSSL formal parameters.  It supports
'#!rest' argument following '!key' arguments.  In that case, the
'#!rest' formal parameter is bound to the list of non-keyword values.

4.1 DSSSL formal argument lists
===============================

DSSSL formal argument lists are defined by the following grammar:

     <formal-argument-list> ==> <required-formal-argument>*
       [(#!optional <optional-formal-argument>*)]
       [(#!rest <rest-formal-argument>)]
       [(#!key <key-formal-argument>*) (#!rest <rest-formal-argument>?)]
     <required-formal-argument> ==> <ieee-ident>
     <optional-formal-argument> ==> <ieee-ident>
          | (<ieee-ident> <initializer>)
     <rest-formal-argument> ==> <ieee-ident>
     <key-formal-argument> ==> <ieee-ident>
          | (<ieee-ident> <initializer>)
     <initializer> ==> <expr>

  When a procedure is applied to a list of actual arguments, the formal
and actual arguments are processed from left to right as follows:

   * _Variables_ in _required-formal-arguments_ are bound to successive
     actual arguments starting with the first actual argument.  It shall
     be an error if there are fewer actual arguments than
     _required-formal-arguments_.

   * Next, _variables_ in _optional-formal-arguments_ are bound to any
     remaining actual arguments.  If there are fewer remaining actual
     arguments than _optional-formal-arguments_, then variables are
     bound to the result of the evaluation of _initializer_, if one was
     specified, and otherwise to '#f'.  The _initializer_ is evaluated
     in an environment in which all previous optional formal arguments
     have been bound.

   * If there is a _rest-formal-argument_, then it is bound to a list of
     all remaining actual arguments.  The remaining actual arguments are
     also eligible to be bound to _keyword-formal-arguments_.  If there
     is no _rest-formal-argument_ and there are no
     _keyword-formal-arguments_, the it shall be an error if there are
     any remaining actual arguments.

   * If '#!key' was specified in the _formal-argument-list_, there shall
     be an even number of remaining actual arguments.  These are
     interpreted as a series of pairs, where the first member of each
     pair is a keyword specifying the argument name, and the second is
     the corresponding value.  It shall be an error if the first member
     of a pair is not a keyword.  It shall be an error if the argument
     name is not the same as a variable in a _keyword-formal-argument_,
     unless there is a _rest-formal-argument_.  If the same argument
     name occurs more than once in the list of actual arguments, then
     the first value is used.  If there is no actual argument for a
     particular _keyword-formal-argument_, then the variable is bound to
     the result of evaluating _initializer_ if one was specified, and
     otherwise '#f'.  The _initializer_ is evaluated in an environment
     in which all previous formal key arguments have been bound.

   * If '#!rest' was specified in the _formal-argument-list_ _after_ a
     '#!key' formal parameter, it is bound to the list of optional
     _non-keyword_ arguments.

  It shall be an error for an <ieee-ident> to appear more than once in a
_formal-argument-list_.

  Example:

     ((lambda (x y #!rest z) z)
      3 4 5 6)                    => (5 6)
     ((lambda (x y #!optional z #!rest r #!key i (j 1))
         (list x y z i: i j: j))
      3 4 5 i: 6 i: 7)            => (3 4 5 i: 6 j: 1)
     ((lambda (x y #!optional z #!key i (j 1) #!rest r)
         (list x y z i: i j: j r))
      3 4 5 i: 6 i: 7 8 9)        => (3 4 5 i: 6 j: 1 (8 9))

4.2 Modules and DSSSL formal argument lists
===========================================

Functions using DSSSL formal argument lists can be exported or imported
in the same way as all regular Bigloo functions.  When exporting such a
Dsssl function the exact prototype of the function must be duplicated in
the export clause.  That is, for instance, the exportation prototype for
the function:

     (define (foo x y #!optional z #!key i (j 1)) ...)

is:

     (export (foo x y #!optional z #!key i (j 1)))


File: bigloo.info,  Node: Standard Library,  Next: Pattern Matching,  Prev: DSSSL Support,  Up: Top

5 Standard Library
******************

This chapter presents the Bigloo standard library.  Bigloo is mostly
R5RS compliant but it proposes many extensions to this standard.  In a
first section *note Scheme Library:: the Bigloo R5RS support is
presented.  This section also contains various function that are not
standard (for instance, various functions used to manage a file system).
Then, in the following sections *note Serialization::, *note Bit
Manipulation::, and *note System Programming:: Bigloo specific
extensions are presented.  Bigloo input and output facilities constitute
a large superset of the standard Scheme definition.  For this reason
they are presented in a separate section *note Input and Output::.

* Menu:

* Scheme Library::
* Input and Output::
* Serialization::
* Bit Manipulation::
* Weak Pointers::
* Hash Tables::
* System Programming::
* Date::
* Digest::
* CRC::
* Internet::


File: bigloo.info,  Node: Scheme Library,  Next: Input and Output,  Up: Standard Library

5.1 Scheme Library
==================

When the definition of a procedure or a special form is the same in
Bigloo and Scheme, we just mention its name; otherwise, we explain it
and qualify it as a "bigloo procedure".

* Menu:

* Booleans::
* Equivalence Predicates::
* Pairs And Lists::
* Symbols::
* Keywords::
* Numbers::
* Characters::
* UCS-2 Characters::
* Strings::
* Unicode (UCS-2) Strings::
* Vectors::
* Homogeneous Vectors (SRFI-4)::
* Control Features::


File: bigloo.info,  Node: Booleans,  Next: Equivalence Predicates,  Up: Scheme Library

5.1.1 Booleans
--------------

The standard boolean objects are '#t' and '#f'.

  _Note_: the empty list is true.

 -- library procedure: not obj
     'not' returns #t if OBJ is false, and returns '#f' otherwise.

          (not #t)                               => #f
          (not 3)                                => #f
          (not (list 3))                         => #f
          (not #f)                               => #t
          (not '())                              => #f
          (not (list))                           => #f
          (not 'nil)                             => #f

 -- library procedure: boolean? obj
     'Boolean?' returns #t if OBJ is either #t or #f and returns #f
     otherwise.

          (boolean? #f)                          => #t
          (boolean? 0)                           => #f
          (boolean? '())                         => #f


File: bigloo.info,  Node: Equivalence Predicates,  Next: Pairs And Lists,  Prev: Booleans,  Up: Scheme Library

5.1.2 Equivalence predicates
----------------------------

 -- procedure: eqv? obj1 obj2
 -- procedure: eq? obj1 obj2
     'eqv?' and 'eq?' are equivalent in Bigloo.

          (eq? 'a 'a)                            =>  #t
          (eq? '(a) '(a))                        =>  _unspecified_
          (eq? (list 'a) (list 'a))              =>  #f
          (eq? "a" "a")                          =>  _unspecified_
          (eq? "" "")                            =>  _unspecified_
          (eq? '() '())                          =>  #t
          (eq? 2 2)                              =>  _unspecified_
          (eq? #\A #\A)                          =>  _unspecified_
          (eq? car car)                          =>  #t
          (let ((n (+ 2 3)))
            (eq? n n))                           =>  _unspecified_
          (let ((x '(a)))
            (eq? x x))                           =>  #t
          (let ((x '#()))
            (eq? x x))                           =>  #t
          (let ((p (lambda (x) x)))
            (eq? p p))                           =>  #t

     Since Bigloo implements 'eqv?' as 'eq?', the behavior is not always
     conforming to R5RS.
          (eqv? 'a 'a)                           =>  #t
          (eqv? 'a 'b)                           =>  #f
          (eqv? 2 2)                             =>  #t
          (eqv? '() '())                         =>  #t
          (eqv? 100000000 100000000)             =>  #t
          (eqv? (cons 1 2) (cons 1 2))           =>  #f
          (eqv? (lambda () 1)
                (lambda () 2))                   =>  #f
          (eqv? #f 'nil)                         =>  #f
          (let ((p (lambda (x) x)))
            (eqv? p p))                          =>  _unspecified_

     The following examples illustrate cases in which the above rules do
     not fully specify the behavior of 'eqv?'.  All that can be said
     about such cases is that the value returned by 'eqv?' must be a
     boolean.

          (eqv? "" "")                           =>  _unspecified_
          (eqv? '#() '#())                       =>  _unspecified_
          (eqv? (lambda (x) x)
                (lambda (x) x))                  =>  _unspecified_
          (eqv? (lambda (x) x)
                (lambda (y) y))                  =>  _unspecified_

          (define gen-counter
            (lambda ()
              (let ((n 0))
                (lambda () (set! n (+ n 1)) n))))
          (let ((g (gen-counter)))
            (eqv? g g))                          =>  #t
          (eqv? (gen-counter) (gen-counter))
                                                 =>  #f
          (define gen-loser
            (lambda ()
              (let ((n 0))
                (lambda () (set! n (+ n 1)) 27))))
          (let ((g (gen-loser)))
            (eqv? g g))                          =>  #t
          (eqv? (gen-loser) (gen-loser))
                                                 =>  _unspecified_

          (letrec ((f (lambda () (if (eqv? f g) 'both 'f)))
                   (g (lambda () (if (eqv? f g) 'both 'g))))
            (eqv? f g))
                                                 =>  _unspecified_

          (letrec ((f (lambda () (if (eqv? f g) 'f 'both)))
                   (g (lambda () (if (eqv? f g) 'g 'both))))
            (eqv? f g))
                                                 =>  #f
          (eqv? '(a) '(a))                       =>  _unspecified_
          (eqv? "a" "a")                         =>  _unspecified_
          (eqv? '(b) (cdr '(a b)))               =>  _unspecified_
          (let ((x '(a)))
            (eqv? x x))                          =>  #t

 -- library procedure: equal? obj1 obj2
          (equal? 'a 'a)                         =>  #t
          (equal? '(a) '(a))                     =>  #t
          (equal? '(a (b) c)
                  '(a (b) c))                    =>  #t
          (equal? "abc" "abc")                   =>  #t
          (equal? 2 2)                           =>  #t
          (equal? (make-vector 5 'a)
                  (make-vector 5 'a))            =>  #t
          (equal? (lambda (x) x)
                  (lambda (y) y))                =>  _unspecified_

  *Note r5rs.info: (R5RS)Equivalence predicates, for more details.


File: bigloo.info,  Node: Pairs And Lists,  Next: Symbols,  Prev: Equivalence Predicates,  Up: Scheme Library

5.1.3 Pairs and lists
---------------------

The form '()' is _illegal_.

 -- procedure: pair? obj

 -- procedure: cons a d

 -- bigloo procedure: pair-or-null? obj
     Returns '#t' if OBJ is either a pair or the empty list.  Otherwise
     it returns '#f'.

 -- procedure: car pair
 -- procedure: cdr pair
 -- procedure: set-car! pair obj
 -- procedure: set-cdr! pair obj

 -- library procedure: caar pair
 -- library procedure: cadr pair
 -- library procedure: cadar pair
 -- library procedure: caadr pair
 -- library procedure: caaar pair
 -- library procedure: caddr pair
 -- library procedure: cadar pair
 -- library procedure: cdddar pair
 -- library procedure: cddddr pair

 -- library procedure: null? obj
 -- library procedure: list? obj
 -- library procedure: list obj ...
 -- library procedure: length list
 -- library procedure: append list ...
 -- bigloo procedure: append! list ...

     A destructive append.

 -- library procedure: reverse list
 -- bigloo procedure: reverse! list

     A destructive reverse.

 -- library procedure: list-ref list k
 -- library procedure: take list k
 -- library procedure: drop list k
 -- library procedure: list-tail list k
     'list-ref' returns the K element of the list.

     'take' returns a new list made of the first K element of the list.

     'Drop' and 'list-tail' returns the sublist of LIST obtained by
     omitting the first K elements.

 -- bigloo procedure: last-pair list
     Returns the last pair in the nonempty, possibly improper, LIST.

 -- library procedure: memq obj list
 -- library procedure: memv obj list
 -- library procedure: member obj list
 -- library procedure: assq obj alist
 -- library procedure: assv obj alist
 -- library procedure: assoc obj alist
 -- bigloo procedure: remq obj list

     Returns a new list which is a copy of LIST with all items 'eq?' to
     OBJ removed from it.

 -- bigloo procedure: remq! obj list
     Same as 'remq' but in a destructive way.

 -- bigloo procedure: delete obj list [eq equal?]
     Returns a new list which is a copy of LIST with all items 'equal?'
     to OBJ deleted from it.

 -- bigloo procedure: delete! obj list [eq equal?]
     Same as 'delete' but in a destructive way.

 -- bigloo procedure: cons* obj ...
     Returns an object formed by consing all arguments together from
     right to left.  If only one OBJ is supplied, that OBJ is returned.

 -- bigloo procedure: every fun clist1 clist2 ...
     Applies the function FUN across the lists, returning the last
     non-false if the function returns non-false on every application.
     If non-false, the result of 'every' is the last value returned by
     the last application of FUN.

          (every < '(1 2 3) '(2 3 4))            => #t
          (every < '(1 2 3) '(2 3 0))            => #f

 -- bigloo procedure: any fun clist1 clist2 ...
     Applies the function FUN across the lists, returning non-false if
     the function returns non-false for at least one application.  If
     non-false, the result of 'any' is the first non-false value
     returned by FUN.

          (any < '(1 2 3) '(2 3 4))            => #t
          (any < '(1 2 3) '(2 3 0))            => #t

 -- bigloo procedure: find pred clist

     Return the first element of CLIST that satisfies predicate PRED;
     false if no element does.

          (find even? '(3 1 4 1 5 9))          => 4

     Note that 'find' has an ambiguity in its lookup semantics - if find
     returns '#f', you cannot tell (in general) if it found a '#f'
     element that satisfied PRED, or if it did not find any element at
     all.  In many situations, this ambiguity cannot arise - either the
     list being searched is known not to contain any '#f' elements, or
     the list is guaranteed to have an element satisfying pred.
     However, in cases where this ambiguity can arise, you should use
     find-tail instead of find - find-tail has no such ambiguity:

          (cond ((find-tail pred lis) => (lambda (pair) ...)) ; Handle (CAR PAIR)
                (else ...)) ; Search failed.

 -- bigloo procedure: find-tail pred clist

     Return the first pair of CLIST whose car satisfies PRED.  If no
     pair does, return false.

     'find-tail' can be viewed as a general-predicate variant of the
     member function.

     Examples:

          (find-tail even? '(3 1 37 -8 -5 0 0)) => (-8 -5 0 0)
          (find-tail even? '(3 1 37 -5)) => #f

          ;; MEMBER X LIS:
          (find-tail (lambda (elt) (equal? x elt)) lis)

     In the circular-list case, this procedure "rotates" the list.

 -- bigloo procedure: reduce f ridentity list

     If LIST if null returns RIDENTITY, if LIST has one element, returns
     that element.  Otherwise, returns F applied to the first element of
     the LIST and to 'reduce' of the rest of the list.

     Examples:

          (reduce max 0 l) == (apply max l)

 -- bigloo procedure: make-list n [fill]
     Returns an N-element list, whose elements are all the value FILL.
     If the FILL argument is not given, the elements of the list may be
     arbitrary values.

          (make-list 4 'c)                     => (c c c c)

 -- bigloo procedure: list-tabulate n init-proc
     Returns an N-element list.  Element i of the list, where 0 <= i <
     N, is produced by '(init-proc i)'.  No guarantee is made about the
     dynamic order in which INIT-PROC is applied to these indices.

          (list-tabulate 4 values)             => (0 1 2 3)

 -- bigloo procedure: list-split list n [filler]
     Split a LIST into a list of lists of length N.  Last smaller list
     is filled with FILLER.

          (list-split '(1 2 3 4 5 6 7 8) 3 0) => ((1 2 3) (4 5 6) (7 8 0))
          (list-split (iota 10) 3)            => ((0 1 2) (3 4 5) (6 7 8) (9))
          (list-split (iota 10 3) '-1)        => ((0 1 2) (3 4 5) (6 7 8) (9 -1 -1))

 -- bigloo procedure: iota count [start step]

     Returns a list containing the elements

          (start start+step ... start+(count-1)*step)

     The START and STEP parameters default to '0' and '1', respectively.
     This procedure takes its name from the APL primitive.

          (iota 5) => (0 1 2 3 4)
          (iota 5 0 -0.1) => (0 -0.1 -0.2 -0.3 -0.4)

 -- bigloo procedure: list-copy l
 -- bigloo procedure: tree-copy l
     The function 'list-copy' copies the spine of the of the list.  The
     function 'tree-copy' recursively copies its arguments, descending
     only into the list cells.

 -- bigloo procedure: delete-duplicates list [eq equal?]
 -- bigloo procedure: delete-duplicates! list [eq equal?]

     'delete-duplicates' removes duplicate elements from the LIST
     argument.  If there are multiple equal elements in the argument
     list, the result list only contains the first or leftmost of these
     elements in the result.  The order of these surviving elements is
     the same as in the original list - 'delete-duplicates' does not
     disorder the list (hence it is useful for "cleaning up" association
     lists).

     The EQUAL parameter is used to compare the elements of the list; it
     defaults to 'equal?'.  If x comes before y in list, then the
     comparison is performed (= x y).  The comparison procedure will be
     used to compare each pair of elements in list no more than once;
     the order in which it is applied to the various pairs is not
     specified.

     'delete-duplicates' is allowed to share common tails between
     argument and result lists - for example, if the list argument
     contains only unique elements, it may simply return exactly this
     list.

  *Note r5rs.info: (R5RS)Pairs and lists, for more details.


File: bigloo.info,  Node: Symbols,  Next: Keywords,  Prev: Pairs And Lists,  Up: Scheme Library

5.1.4 Symbols
-------------

Symbols are case sensitive and the reader is case sensitive too.  So:
     (eq? 'foo 'FOO) => #f
     (eq? (string->symbol "foo") (string->symbol "FOO")) => #f

  Symbols may contain special characters (such as #\Newline or #\Space).
Such symbols that have to be read must be written: '|[^]+|'.  The
function 'write' uses that notation when it encounters symbols
containing special characters.

     (write 'foo) => foo
     (write 'Foo) =>Foo
     (write '|foo bar|) => |foo bar|

 -- procedure: symbol? obj
 -- procedure: symbol->string symbol
     Returns the name of the symbol as a string.  Modifying the string
     result of 'symbol->string' could yield incoherent programs.  It is
     better to copy the string before any physical update.  For
     instance, don't write:
          (string-downcase! (symbol->string 'foo))

     *Note r5rs.info: (R5RS)Symbols, for more details.

     but prefer:
          (string-downcase (symbol->string 'foo))

 -- procedure: string->symbol string
 -- bigloo procedure: string->symbol-ci string
 -- bigloo procedure: symbol-append symbol ...
     'String->symbol' returns a symbol whose name is STRING.
     'String->symbol' respects the case of STRING.  'String->symbol-ci'
     returns a symbol whose name is '(string-upcase STRING)'.
     'Symbol-append' returns a symbol whose name is the concatenation of
     all the SYMBOL's names.

 -- bigloo procedure: gensym [obj]

     Returns a new fresh symbol.  If OBJ is provided and is a string or
     a symbol, it is used as prefix for the new symbol.

 -- bigloo procedure: genuuid

     Returns a string containing a new fresh _Universal Unique
     Identifier_ (see
     <http://fr.wikipedia.org/wiki/Universal_Unique_Identifier>).

 -- bigloo procedure: symbol-plist symbol-or-keyword
     Returns the property-list associated with SYMBOL-OR-KEYWORD.

 -- bigloo procedure: getprop symbol-or-keyword key

     Returns the value that has the key 'eq?' to KEY from the
     SYMBOL-OR-KEYWORD's property list.  If there is no value associated
     with KEY then '#f' is returned.

 -- bigloo procedure: putprop! symbol-or-keyword key val
     Stores VAL using KEY on SYMBOL-OR-KEYWORD's property list.

 -- bigloo procedure: remprop! symbol-or-keyword key
     Removes the value associated with KEY in the SYMBOL-OR-KEYWORD's
     property list.  The result is unspecified.

  Here is an example of properties handling:

     (getprop 'a-sym 'a-key)       => #f
     (putprop! 'a-sym 'a-key 24)
     (getprop 'a-sym 'a-key)       => 24
     (putprop! 'a-sym 'a-key2 25)
     (getprop 'a-sym 'a-key)       => 24
     (getprop 'a-sym 'a-key2)      => 25
     (symbol-plist 'a-sym)         => (a-key2 25 a-key 24)
     (remprop! 'a-sym 'a-key)
     (symbol-plist 'a-sym)         => (a-key2 25)
     (putprop! 'a-sym 'a-key2 16)
     (symbol-plist 'a-sym)         => (a-key2 16)


File: bigloo.info,  Node: Keywords,  Next: Numbers,  Prev: Symbols,  Up: Scheme Library

5.1.5 Keywords
--------------

Keywords constitute an extension to Scheme required by Dsssl [Dsssl96].
Keywords syntax is either '<ident>:' or ':<ident>'.

  Keywords are autoquote and case sensitive.  So
     (eq? toto: TOTO:) => #f

  The colon character "':'" does not belong to they keyword.  Hence
     (eq? toto: :toto) => #t

 -- bigloo procedure: keyword? obj
 -- bigloo procedure: keyword->string keyword
 -- bigloo procedure: string->keyword string
 -- bigloo procedure: keyword->symbol keyword
 -- bigloo procedure: symbol->keyword symbol


File: bigloo.info,  Node: Numbers,  Next: Characters,  Prev: Keywords,  Up: Scheme Library

5.1.6 Numbers
-------------

Bigloo has only three kinds of numbers: fixnum, long fixnum and flonum.
Operations on complexes and rationals are not implemented but for
compatibility purposes, the functions 'complex?' and 'rational?' exist.
(In fact, 'complex?' is the same as 'number?' and 'rational?' is the
same as 'real?' in Bigloo.)  The accepted prefixes are '#b', '#o', '#d',
'#x', '#e', '#ex', '#l', '#lx', '#z', and '#zx'.  For each generic
arithmetic procedure, Bigloo provides two specialized procedures, one
for fixnums and one for flonums.  The names of these two specialized
procedures is the name of the original one suffixed by 'fx' (fixnum),
'fl' (flonum), 'elong' (exact C long), 'llong' (exact C long long), and
'bx' (big integer).  A fixnum has the size of a C 'long' minus 2 bits.
A flonum has the size of a C 'double'.  An elong has the size of a C
long.  An llong has the size of a C long long.  A big integer has an
unbounded size.

 -- procedure: number? obj
 -- procedure: real? obj
 -- procedure: integer? obj
 -- bigloo procedure: complex? x
 -- bigloo procedure: rational? x

 -- bigloo procedure: fixnum? obj
 -- bigloo procedure: flonum? obj
     These two procedures are type checkers on types 'integer' and
     'real'.

 -- bigloo procedure: elong? obj
 -- bigloo procedure: llong? obj
     The 'elong?' procedures is a type checker for "hardware" integers,
     that is integers that have the very same size has the host platform
     permits (e.g., 32 bits or 64 bits integers).  The 'llong?'
     procedure is a type checker for "hardware" long long integers.
     Exact integers literal are introduced with the special '#e' and
     '#ex' prefixes.  Exact long integers literal are introduced with
     the special '#l' and '#lx' prefixes.

 -- bigloo procedure: bignum? obj
     This type checker tests if its argument is a big integer.

 -- bigloo procedure: make-elong int
 -- bigloo procedure: make-llong int
     Create an exact fixnum integer from the fixnum value INT.

 -- bigloo procedure: minvalfx
 -- bigloo procedure: maxvalfx
 -- bigloo procedure: minvalelong
 -- bigloo procedure: maxvalelong
 -- bigloo procedure: minvalllong
 -- bigloo procedure: maxvalllong
     Returns the minimal value (respectively the maximal value) for fix
     integers.

 -- procedure: exact? z
 -- procedure: inexact? z

 -- library procedure: zero? z
 -- library procedure: positive? z
 -- library procedure: negative? z
 -- library procedure: odd? n
 -- library procedure: even? n
 -- library procedure: zerofx? z
 -- library procedure: positivefx? z
 -- library procedure: negativefx? z
 -- library procedure: oddfx? n
 -- library procedure: evenfx? n
 -- library procedure: zerofl? z
 -- library procedure: positivefl? z
 -- library procedure: negativefl? z
 -- library procedure: oddfl? n
 -- library procedure: evenfl? n
 -- library procedure: zeroelong? z
 -- library procedure: positiveelong? z
 -- library procedure: negativeelong? z
 -- library procedure: oddelong? n
 -- library procedure: evenelong? n
 -- library procedure: zerollong? z
 -- library procedure: positivellong? z
 -- library procedure: negativellong? z
 -- library procedure: oddllong? n
 -- library procedure: evenllong? n
 -- library procedure: zerobx? z
 -- library procedure: positivebx? z
 -- library procedure: negativebx? z
 -- library procedure: oddbx? n
 -- library procedure: evenbx? n

 -- library procedure: min x1 x2 ...
 -- library procedure: max x1 x2 ...
 -- bigloo procedure: minfx x1 x2 ...
 -- bigloo procedure: maxfx x1 x2 ...
 -- bigloo procedure: minfl x1 x2 ...
 -- bigloo procedure: maxfl x1 x2 ...
 -- bigloo procedure: minbx x1 x2 ...
 -- bigloo procedure: maxbx x1 x2 ...

 -- procedure: = z1 z2 z3 ...
 -- bigloo procedure: =fx i1 i2
 -- bigloo procedure: =fl r1 r2
 -- bigloo procedure: =elong r1 r2
 -- bigloo procedure: =llong r1 r2
 -- bigloo procedure: =bx r1 r2
 -- procedure: < z1 z2 z3 ...
 -- bigloo procedure: <fx i1 i2
 -- bigloo procedure: <fl r1 r2
 -- bigloo procedure: <elong r1 r2
 -- bigloo procedure: <lllong r1 r2
 -- bigloo procedure: <bx r1 r2
 -- procedure: > z1 z2 z3 ...
 -- bigloo procedure: >fx i1 i2
 -- bigloo procedure: >fl r1 r2
 -- bigloo procedure: >elong r1 r2
 -- bigloo procedure: >lllong r1 r2
 -- bigloo procedure: >bx r1 r2
 -- procedure: <= z1 z2 z3 ...
 -- bigloo procedure: <=fx i1 i2
 -- bigloo procedure: <=fl r1 r2
 -- bigloo procedure: <=elong r1 r2
 -- bigloo procedure: <=llong r1 r2
 -- bigloo procedure: <=bx r1 r2
 -- procedure: >= z1 z2 z3 ...
 -- bigloo procedure: >=fx i1 i2
 -- bigloo procedure: >=fl r1 r2
 -- bigloo procedure: >=elong r1 r2
 -- bigloo procedure: >=llong r1 r2
 -- bigloo procedure: >=bx r1 r2

 -- procedure: + z ...
 -- bigloo procedure: +fx i1 i2
 -- bigloo procedure: +fl r1 r2
 -- bigloo procedure: +elong r1 r2
 -- bigloo procedure: +llong r1 r2
 -- bigloo procedure: +bx r1 r2
 -- procedure: * z ...
 -- bigloo procedure: *fx i1 i2
 -- bigloo procedure: *fl r1 r2
 -- bigloo procedure: *elong r1 r2
 -- bigloo procedure: *llong r1 r2
 -- bigloo procedure: *bx r1 r2
 -- procedure: - z
 -- procedure: - z1 z2 ...
 -- bigloo procedure: -fx i1 i2
 -- bigloo procedure: -fl r1 r2
 -- bigloo procedure: -elong r1 r2
 -- bigloo procedure: -llong r1 r2
 -- bigloo procedure: -bx r1 r2
 -- bigloo procedure: negfx i
 -- bigloo procedure: negfl r
 -- bigloo procedure: negelong r
 -- bigloo procedure: negllong r
 -- bigloo procedure: negbx r
     These two functions implement the unary function '-'.

 -- procedure: / z1 z2
 -- procedure: / z1 z2 ...
 -- bigloo procedure: /fx i1 i2
 -- bigloo procedure: /fl r1 r2
 -- bigloo procedure: /elong r1 r2
 -- bigloo procedure: /llong r1 r2
 -- bigloo procedure: /bx r1 r2

 -- library procedure: abs z
 -- bigloo procedure: absfl z
 -- procedure: quotient z1 z2
 -- procedure: quotientelong z1 z2
 -- procedure: quotientllong z1 z2
 -- procedure: remainder z1 z2
 -- procedure: remainderelong z1 z2
 -- procedure: remainderllong z1 z2
 -- procedure: remainderfl z1 z2
 -- procedure: modulo z1 z2
 -- procedure: gcd z ...
 -- procedure: lcm z ...
 -- procedure: floor z
 -- procedure: floorfl z
 -- procedure: ceiling z
 -- procedure: ceilingfl z
 -- procedure: truncate z
 -- procedure: truncatefl z
 -- procedure: round z
 -- procedure: roundfl z

 -- bigloo procedure: random z
 -- bigloo procedure: randomfl
 -- bigloo procedure: randombx z
 -- bigloo procedure: seed-random! z
     the 'random' function returns a pseudo-random integer between 0 and
     Z.

     If no seed value is provided, the 'random' function is
     automatically seeded with a value of 1.

     The function 'randomfl' returns a double in the range [0..1].

 -- procedure: exp z
 -- procedure: expfl z
 -- procedure: log z
 -- procedure: logfl z
 -- procedure: sin z
 -- procedure: sinfl z
 -- procedure: cos z
 -- procedure: cosfl z
 -- procedure: tan z
 -- procedure: tanfl z
 -- procedure: asin z
 -- procedure: asinfl z
 -- procedure: acos z
 -- procedure: acosfl z
 -- procedure: atan z1 z2
 -- procedure: atanfl z1 z2
 -- procedure: sqrt z
 -- procedure: sqrtfl z
 -- procedure: expt z1 x2
 -- procedure: exptfl z1 x2

 -- procedure: exact->inexact z
 -- procedure: inexact->exact z
 -- procedure: number->string z
 -- bigloo procedure: integer->string i [radix 10]
 -- bigloo procedure: integer->string/padding i padding [radix 10]
 -- bigloo procedure: elong->string i [radix 10]
 -- bigloo procedure: llong->string i [radix 10]
 -- bigloo procedure: bignum->string i [radix 10]
 -- bigloo procedure: real->string z
 -- bigloo procedure: unsigned->string i [radix 16]

     The function 'integer->string/padding' converts its arguments into
     a string with a left padding filled of characters '0'.

          (integer->string/padding 3 5)       => "00003"

     The function 'unsigned->string' only accepts the following radixes:
     '2', '8', and '16'.  It converts its argument into an _unsigned_
     representation.

          (unsigned->string 123 16)           => "7b"
          (unsigned->string -123 16)          => "ffffff85"

 -- bigloo procedure: nanfl? z
     Returns '#t' if the floating Z is 'not-a-number'.  Returns '#f'
     otherwise.

 -- bigloo procedure: infinitefl? z
 -- bigloo procedure: finitefl? z
     The predicate 'infinitefl?' returns '#t' if the floating Z is
     positive or negative infinite.  Returns '#f' otherwise.

     The predicate 'finitefl?' is true if and only if 'z' is finite.

 -- bigloo procedure: signbitfl z
     Returns '0' is 'z' is positive or null.  Returns a positive integer
     otherwise.

 -- bigloo procedure: bignum->octet-string bignum

     Returns a binary big-endian representation of the given bignum
     BIGNUM.

          (string-hex-extern (bignum->octet-string #zx1234567)) => "01234567"

 -- bigloo procedure: double->ieee-string z
 -- bigloo procedure: float->ieee-string z
     Returns a big-endian representation of the given number.

 -- procedure: string->number string [radix 10]
 -- bigloo procedure: string->elong string radix
 -- bigloo procedure: string->llong string radix
 -- bigloo procedure: string->bignum string radix
     Bigloo implements a restricted version of 'string->number'.  If
     STRING denotes a floating point number then, the only radix '10'
     may be send to 'string->number'.  That is:

          (string->number "1243" 16)          => 4675
          (string->number "1243.0" 16)        -|
          # *** ERROR:bigloo:string->number
          # Only radix `10' is legal for floating point number -- 16
          (string->elong "234456353")         => #e234456353

          (string->number "#x1243")          => #f

 -- bigloo procedure: string->integer string [radix 10] [startpos 0]
 -- bigloo procedure: string->real string
     In addition, 'string->number' does not support radix encoded inside
     STRING.  That is:

     For efficiency, 'string->real' and 'string->integer' do not test
     whether the string can be read as a number.  Therefore the result
     might be wrong if the string cannot be read as a number.

 -- bigloo procedure: octet-string->bignum string

     Counterpart to 'bignum->octet-string'.  Takes the bignum
     representation in big-endian format STRING and returns the
     corresponding bignum.

          (octet-string->bignum (bignum->octet-string #z1234)) => #z1234

 -- bigloo procedure: ieee-string->double string
 -- bigloo procedure: ieee-string->float string
     Convert the big-endian representations to their numeric values.

 -- bigloo procedure: fixnum->flonum i
 -- bigloo procedure: flonum->fixnum r
 -- bigloo procedure: elong->fixnum i
 -- bigloo procedure: fixnum->elong r
 -- bigloo procedure: llong->fixnum i
 -- bigloo procedure: fixnum->llong r
 -- bigloo procedure: elong->flonum i
 -- bigloo procedure: flonum->elong r
 -- bigloo procedure: llong->flonum i
 -- bigloo procedure: flonum->llong r

     These last procedures implement the natural translation from and to
     fixnum, flonum, elong, and llong.

 -- bigloo procedure: double->llong-bits z
 -- bigloo-procedure: float->int-bits z
     Returns the double-bits as a llong.

 -- bigloo procedure: llong-bits->double llong
 -- bigloo procedure: int-bits->float int
     Converts the given llong bits to a double.

  *Note r5rs.info: (R5RS)Numerical operations, for more details.


File: bigloo.info,  Node: Characters,  Next: UCS-2 Characters,  Prev: Numbers,  Up: Scheme Library

5.1.7 Characters
----------------

Bigloo knows named characters '#\alarm', '#\backspace', '#\delete',
'#\escape', '#\tab', '#\return', and '#\null' in addition to the
'#\space' and '#\newline' of R5RS.

  A new alternate syntax exists for characters: '#a<ascii-code>' where
'<ascii-code>' is the three digit decimal ASCII number of the character
to be read.  Thus, for instance, the character '#\space' can be written
'#a032'.  Bigloo also supports the R7Rs syntax '#\x<hex-code>'.

 -- procedure: char? obj

 -- procedure: char=? char1 char2
 -- procedure: char<? char1 char2
 -- procedure: char>? char1 char2
 -- procedure: char<=? char1 char2
 -- procedure: char>=? char1 char2
 -- library procedure: char-ci=? char1 char2
 -- library procedure: char-ci<? char1 char2
 -- library procedure: char-ci>? char1 char2
 -- library procedure: char-ci<=? char1 char2
 -- library procedure: char-ci>=? char1 char2

 -- library procedure: char-alphabetic? char
 -- library procedure: char-numeric? char
 -- library procedure: char-whitespace? char
 -- library procedure: char-upper-case? char
 -- library procedure: char-lower-case? char

 -- procedure: char->integer char
 -- procedure: integer->char i

 -- library procedure: char-upcase char
 -- library procedure: char-downcase char


File: bigloo.info,  Node: UCS-2 Characters,  Next: Strings,  Prev: Characters,  Up: Scheme Library

5.1.8 UCS-2 Characters
----------------------

UCS-2 Characters are two byte encoded characters.  They can be read with
the syntax: '#u<unicode>' where '<unicode>' is the four digit
hexadecimal Unicode value of the character to be read.  Thus, for
instance, the character '#\space' can be written '#u0020'.

 -- bigloo procedure: ucs2? obj

 -- bigloo procedure: ucs2=? ucs2a ucs2b
 -- bigloo procedure: ucs2<? ucs2a ucs2b
 -- bigloo procedure: ucs2>? ucs2a ucs2b
 -- bigloo procedure: ucs2<=? ucs2a ucs2b
 -- bigloo procedure: ucs2>=? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci=? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci<? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci>? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci<=? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci>=? ucs2a ucs2b

 -- bigloo procedure: ucs2-alphabetic? ucs2
 -- bigloo procedure: ucs2-numeric? ucs2
 -- bigloo procedure: ucs2-whitespace? ucs2
 -- bigloo procedure: ucs2-upper-case? ucs2
 -- bigloo procedure: ucs2-lower-case? ucs2

 -- bigloo procedure: ucs2->integer ucs2
 -- bigloo procedure: integer->ucs2 i

 -- bigloo procedure: ucs2->char ucs2
 -- bigloo procedure: char->ucs2 char

 -- bigloo procedure: ucs2-upcase ucs2
 -- bigloo procedure: ucs2-downcase ucs2


File: bigloo.info,  Node: Strings,  Next: Unicode (UCS-2) Strings,  Prev: UCS-2 Characters,  Up: Scheme Library

5.1.9 Strings
-------------

There are three different syntaxes for strings in Bigloo: traditional,
foreign or Unicode.  The traditional syntax for strings may conform to
the Revised Report, see *note r5rs.info: (R5RS)Lexical structure.  With
the foreign syntax, C escape sequences are interpreted as specified by
ISO-C. In addition, Bigloo's reader evaluate '\x??' sequence as an
hexadecimal escape character.  For Unicode syntax, see *note Unicode
(UCS-2) Strings::.  Only the reader distinguishes between these three
appearances of strings; i.e., there is only one type of string at
evaluation-time.  The regular expression describing the syntax for
foreign string is: '#"([^"]|\")*"'.  Escape characters are controlled by
the parameter 'bigloo-strict-r5rs-strings' (see *note Parameters::).

  The library functions for string processing are:
 -- procedure: string? obj

 -- SRFI-13 procedure: string-null? s
     Is S an empty string?

 -- procedure: make-string k
 -- procedure: make-string k char
 -- library procedure: string char ...

 -- procedure: string-length string
 -- procedure: string-ref string k
 -- procedure: string-set! string k char

 -- library procedure: string=? string1 string2
     This function returns '#t' if the STRING1 and STRING2 are made of
     the same characters.  It returns '#f' otherwise.

 -- bigloo procedure: substring=? string1 string2 len
     This function returns '#t' if STRING1 and STRING2 have a common
     prefix of size LEN.

          (substring=? "abcdef" "ab9989898" 2)
             => #t
          (substring=? "abcdef" "ab9989898" 3)
             => #f

 -- bigloo procedure: substring-at? string1 string2 offset [len]
 -- bigloo procedure: substring-ci-at? string1 string2 offset [len]
     This function returns '#t' if STRING2 is at position OFFSET in the
     string 'string1'.  It returns '#f' otherwise.
          (substring-at? "abcdefghij" "def" 3)
             => #t
          (substring-at? "abcdefghij" "def" 2)
             => #f
          (substring-at? "abcdefghij" "defz" 3)
             => #f
          (substring-at? "abcdefghij" "defz" 3 3)
             => #t

 -- library procedure: string-ci=? string1 string2
 -- bigloo procedure: substring-ci=? string1 string2 len
 -- library procedure: string<? string1 string2
 -- library procedure: string>? string1 string2
 -- library procedure: string<=? string1 string2
 -- library procedure: string>=? string1 string2
 -- library procedure: string-ci<? string1 string2
 -- library procedure: string-ci>? string1 string2
 -- library procedure: string-ci<=? string1 string2
 -- library procedure: string-ci>=? string1 string2

 -- bigloo procedure: string-index string charset [start 0] [count -1]
 -- bigloo procedure: string-char-index string char [start 0]
 -- bigloo procedure: string-index-right string charset [start len-1]

     Returns the first occurrence of a character of CHAR-OR-SET in
     STRING.  The argument CHARSET is either a character or a string.
     If no character is found, 'string-index' returns '#f' The argument
     COUNT, if provided, is the number of characters to be scanned in
     the string.

 -- bigloo procedure: string-skip string charset [start 0]
 -- bigloo procedure: string-skip-right string charset [start len-1]

     'string-skip' (resp.  'string-skip-right') searches through the
     STRING from the left (resp.  right), returning the index of the
     first occurrence of a character which

        * is not equal to c (if c is a character);
        * is not in c (if c is a character set);
        * does not satisfy the predicate c (if c is a procedure).

     If no such index exists, the functions return false.

     The start and end parameters specify the beginning and end indices
     of the search; the search includes the start index, but not the end
     index.  Be careful of "fencepost" considerations: when searching
     right-to-left, the first index considered is end-1 whereas when
     searching left-to-right, the first index considered is start.  That
     is, the start/end indices describe a same half-open interval
     [start,end).

 -- bigloo procedure: string-contains string1 string2 [start 0]
 -- bigloo procedure: string-contains-ci string1 string2 [start 0]

     Does string STRING1 contain string STRING2?

     Return the index in STRING1 where STRING2 occurs first as a
     substring, or false.

     'string-contains-ci' is the case-insensitive variant.
     Case-insensitive comparison is done by case-folding characters with
     the operation:

          (char-downcase (char-upcase c))

 -- bigloo procedure: string-compare3 string1 string2
 -- bigloo procedure: string-compare3-ci string1 string2
     This function compares STRING1 and STRING2.  It returns a negative
     integer if STRING1 < STRING2.  It returns zero if the STRING1 equal
     STRING2.  It returns a positive integer if STRING1 > STRING2.

 -- bigloo procedure: string-natural-compare3 string1 string2 [start1 0]
          [start2 0]
 -- bigloo procedure: string-natural-compare3-ci string1 string2 [start1
          0] [start2 0]
     This function compares STRING1 and STRING2 according to a _natural
     string order_.  It returns a negative integer if STRING1 < STRING2.
     It returns zero if the STRING1 equal STRING2.  It returns a
     positive integer if STRING1 > STRING2.

          (string-natural-compare "foo" "foo")
             => 0
          (string-natural-compare "foo0" "foo1")
             => -1
          (string-natural-compare "foo1" "foo0")
             => 1
          (string-natural-compare "rfc822.txt" "rfc1.txt")
             => -1
          (string-natural-compare "rfc1.txt" "rfc2086.txt")
             => -1
          (string-natural-compare "rfc2086.txt" "rfc1.txt")
             => 1
          (string-natural-compare "rfc822.txt" "rfc2086.txt")
             => -1
          (string-natural-compare "a0" "a1")
             => -1
          (string-natural-compare "a1" "a1a")
             => -1
          (string-natural-compare "a1a" "a1b")
             => -1
          (string-natural-compare "a1b" "a2")
             => -1
          (string-natural-compare "a2" "a10")
             => -1
          (string-natural-compare "a10" "a20")
             => -1
          (string-natural-compare "a2" "a20")
             => -1
          (string-natural-compare "x2-g8" "x2-y7")
             => -1
          (string-natural-compare "1.001" "1.002")
             => -1
          (string-natural-compare "1.002" "1.010")
             => -1
          (string-natural-compare "1.010"  "1.02")
             => 1
          (string-natural-compare "1.02" "1.1")
             => -1
          (string-natural-compare "1.1" "1.02")
             => 1
          (string-natural-compare "1.02" "1.3")
             => -1

 -- library procedure: substring string start [end]

     STRING must be a string, and START and END must be exact integers
     satisfying:

            0 <= START <= END <= (string-length STRING)

     The optional argument END defaults to '(string-length STRING)'.

     'substring' returns a newly allocated string formed from the
     characters of STRING beginning with index START (inclusive) and
     ending with index END (exclusive).

          (substring "abcdef" 0 5)
             => "abcde"
          (substring "abcdef" 1 5)
             => "bcde"

 -- library procedure: string-shrink! string end

     STRING must be a string, and END must be an exact integers
     satisfying:

            0 <= END <= (string-length STRING)

     'string-shrink!' returns a new string formed from the characters of
     STRING beginning with index 0 (inclusive) and ending with index END
     (exclusive).  As much as possible 'string-shrink!' changes the
     argument STRING.  That is, as much as possible, and for the
     back-ends that enable it, STRING-SHRINK! operates a side effect on
     its argument.

          (let ((s (string #\a #\b #\c #\d #\e)))
             (set! s (string-shrink! s 3))
             s)
             => "abc"

 -- library procedure: string-append string ...
 -- library procedure: string->list string
 -- library procedure: list->string list
 -- library procedure: string-copy string

 -- bigloo procedure: string-fill! string char
     Stores CHAR in every element of the given STRING and returns an
     unspecified value.

 -- bigloo procedure: string-downcase string
     Returns a newly allocated version of string where each upper case
     letter is replaced by its lower case equivalent.

 -- bigloo procedure: string-upcase string
     Returns a newly allocated version of string where each lower case
     letter is replaced by its upper case equivalent.

 -- bigloo procedure: string-capitalize string
     Builds a newly allocated capitalized string.

 -- bigloo procedure: string-downcase! string
     Physically downcases the STRING argument.

 -- bigloo procedure: string-upcase! string
     Physically upcases the STRING argument.

 -- bigloo procedure: string-capitalize! string
     Physically capitalized the STRING argument.

 -- bigloo procedure: string-for-read string
     Returns a copy of STRING with each special character replaced by an
     escape sequence.

 -- bigloo procedure: blit-string! string1 o1 string2 o2 len
     Fill string STRING2 starting at position O2 with LEN characters
     taken out of string STRING1 from position O1.

          (let ((s (make-string 20 #\-)))
          	(blit-string! "toto" 0 s 16 4)
          	s)
             => "----------------toto"

 -- bigloo procedure: string-replace string char1 char2
 -- bigloo procedure: string-replace! string char1 char2
     Replace all the occurrence of CHAR1 by CHAR2 in STRING.  The
     function 'string-replace' returns a newly allocated string.  The
     function 'string-replace!' modifies its first argument.

 -- bigloo procedure: string-split string
 -- bigloo procedure: string-split string delimiters

     Parses STRING and returns a list of tokens ended by a character of
     the DELIMITERS string.  If DELIMITERS is omitted, it defaults to a
     string containing a space, a tabulation and a newline characters.

          (string-split "/usr/local/bin" "/") => ("usr" "local" "bin")
          (string-split "once   upon a time") => ("once" "upon" "a" "time")

 -- bigloo procedure: string-cut string
 -- bigloo procedure: string-cut string delimiters
     The function 'string-cut' behaves as 'string-split' but it
     introduces empty strings for consecutive occurrences of delimiters.

          (string-cut "/usr//local/bin" "/") => ("usr" "" "local" "bin")
          (string-cut "once   upon a time") => ("once" "" "" "" "upon" "a" "time")

 -- SRFI-13 procedure: string-delete string char/charset/pred s [start
          end]

     Filter the string STRING, retaining only those characters that are
     not equal to CHAR, not present in CHARSET, or not satisfying PRED.
     This function returns a fresh string no larger than END - START.

 -- SRFI-13 procedure: string-prefix-length s1 s2 [start1 end1 start2
          end2]
 -- SRFI-13 procedure: string-suffix-length s1 s2 [start1 end1 start2
          end2]
 -- SRFI-13 procedure: string-prefix-length-ci s1 s2 [start1 end1 start2
          end2]
 -- SRFI-13 procedure: string-suffix-length-ci s1 s2 [start1 end1 start2
          end2]
     Return the length of the longest common prefix/suffix of the two
     strings.  For prefixes, this is equivalent to the "mismatch index"
     for the strings (modulo the starti index offsets).

     The optional start/end indices restrict the comparison to the
     indicated substrings of s1 and s2.

 -- SRFI-13 procedure: string-prefix? s1 s2 [start1 end1 start2 end2]
 -- SRFI-13 procedure: string-suffix? s1 s2 [start1 end1 start2 end2]
 -- SRFI-13 procedure: string-prefix-ci? s1 s2 [start1 end1 start2 end2]
 -- SRFI-13 procedure: string-suffix-ci? s1 s2 [start1 end1 start2 end2]

     Is s1 a prefix/suffix of s2?

     The optional start/end indices restrict the comparison to the
     indicated substrings of s1 and s2.

 -- bigloo procedure: string-hex-intern string
 -- bigloo procedure: string-hex-intern! string
     Converts an hexadecimal STRING of 'n' characters into an actual
     string of 'n/2' characters.

          (string-hex-intern "4a4b4c") => "JKL"

 -- bigloo procedure: string-hex-extern string [start [end]]
     Converts a STRING into a hexadecimal representation.

     STRING must be a string, and START and END must be exact integers
     satisfying:

            0 <= START <= END <= (string-length STRING)

     The optional argument START default to 0.  The optional argument
     END defaults to '(string-length STRING)'.

          (string-hex-extern "JKL") => "4a4b4c"


File: bigloo.info,  Node: Unicode (UCS-2) Strings,  Next: Vectors,  Prev: Strings,  Up: Scheme Library

5.1.10 Unicode (UCS-2) Strings
------------------------------

UCS-2 strings cannot be read by the standard reader but UTF-8 strings
can.  The special syntax for UTF-8 is described by the regular
expression: '#u"([^]|\")*"'.

  The library functions for Unicode string processing are:
 -- bigloo procedure: ucs2-string? obj

 -- bigloo procedure: make-ucs2-string k
 -- bigloo procedure: make-ucs2-string k char
 -- bigloo procedure: ucs2-string k ...

 -- bigloo procedure: ucs2-string-length s-ucs2
 -- bigloo procedure: ucs2-string-ref s-ucs2 k
 -- bigloo procedure: ucs2-string-set! s-ucs2 k char

 -- bigloo procedure: ucs2-string=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string<? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string>? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string<=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string>=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci<? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci>? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci<=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci>=? s-ucs2a s-ucs2b

 -- bigloo procedure: ucs2-substring s-ucs2 start end
 -- bigloo procedure: ucs2-string-append s-ucs2 ...
 -- bigloo procedure: ucs2-string->list s-ucs2
 -- bigloo procedure: list->ucs2-string chars
 -- bigloo procedure: ucs2-string-copy s-ucs2

 -- bigloo procedure: ucs2-string-fill! s-ucs2 char
     Stores CHAR in every element of the given s-ucs2 and returns an
     unspecified value.

 -- bigloo procedure: ucs2-string-downcase s-ucs2
     Builds a newly allocated ucs2-string with lower case letters.

 -- bigloo procedure: ucs2-string-upcase s-ucs2
     Builds a new allocated ucs2-string with upper case letters.

 -- bigloo procedure: ucs2-string-downcase! s-ucs2
     Physically downcases the S-UCS2 argument.

 -- bigloo procedure: ucs2-string-upcase! s-ucs2
     Physically upcases the S-UCS2 argument.

 -- bigloo procedure: ucs2-string->utf8-string s-ucs2
 -- bigloo procedure: utf8-string->ucs2-string STRING
     Convert UCS-2 strings to (or from) UTF-8 encoded ascii strings.

 -- bigloo procedure: utf8-string? string [strict #f]
     Returns '#t' if and only if the argument STRING is a well formed
     UTF-8 string.  Otherwise returns '#f'.

     If the optional argument STRICT is '#t', half utf16-surrogates are
     rejected.  The optional argument STRICT defaults to '#f'.

 -- bigloo procedure: ascii-string? string
     Returns '#t' if and only if the argument STRING is only composed of
     ascii characters.  Otherwise returns '#f'.

 -- bigloo procedure: utf8-string-encode string [strict #f]
     Returns a copy of STRING where all the illegal UTF-8 prefix are
     replaced with the Unicode Replacement Character EF BF BD. The
     result is a well formed UTF-8 string.

 -- bigloo procedure: utf8-string-length string
     Returns the number of characters of an UTF-8 string.  It raises an
     error if the string is not a well formed UTF-8 string (i.e., it
     does satisfies the 'utf8-string?' predicate.

 -- bigloo procedure: utf8-codepoint-length string
     Returns the number of code points of an UTF-8 string.  The code
     points length is the number of 16bits long values needed to encode
     the utf8 strings in utf16.

 -- bigloo procedure: utf8-string-ref string i
     Returns the character (represented as an UTF-8 string) at the
     position I in STRING.

 -- library procedure: utf8-substring string start [end]

     STRING must be a string, and START and END must be exact integers
     satisfying:

            0 <= START <= END <= (string-length STRING)

     The optional argument END defaults to '(utf8-string-length
     STRING)'.

     'utf8-substring' returns a newly allocated string formed from the
     characters of STRING beginning with index START (inclusive) and
     ending with index END (exclusive).

     If the argument STRING is not a well formed UTF-8 string an error
     is raised.  Otherwise, the result is also a well formed UTF-8
     string.

 -- bigloo procedure: iso-latin->utf8 string
 -- bigloo procedure: iso-latin->utf8! string
 -- bigloo procedure: utf8->iso-latin STRING
 -- bigloo procedure: utf8->iso-latin! STRING
 -- bigloo procedure: utf8->iso-latin-15 STRING
 -- bigloo procedure: utf8->iso-latin-15! STRING
     Encode and decode iso-latin strings into utf8.  The functions
     'iso-latin->utf8-string!', 'utf8->iso-latin!' and
     'utf8->iso-latin-15!' may return, as result, the string they
     receive as argument.

 -- bigloo procedure: cp1252->utf8 string
 -- bigloo procedure: cp1252->utf8! string
 -- bigloo procedure: utf8->cp1252 STRING
 -- bigloo procedure: utf8->cp1252! STRING
     Encode and decode cp1252 strings into utf8.  The functions
     'cp1252->utf8-string!' and 'utf8->cp1252!' may return, as result,
     the string they receive as argument.

 -- bigloo procedure: 8bits->utf8 string table
 -- bigloo procedure: 8bits->utf8! string table
 -- bigloo procedure: utf8->8bits string inv-table
 -- bigloo procedure: utf8->8bits! string inv-table
     These are the general conversion routines used internally by
     'iso-latin->utf8' and 'cp1252->utf8'.  They convert any 8 bits
     STRING into its equivalent UTF-8 representation and vice versa.

     The argument TABLE should be either '#f', which means that the
     basic (i.e., iso-latin-1) 8bits -> UTF-8 conversion is used, or it
     must be a vector of at least 127 entries containing strings of
     characters.  This table contains the encodings for the 8 bits
     characters whose code range from 128 to 255.

     The table is not required to be complete.  That is, it is not
     required to give the whole character encoding set.  Only the
     characters that need a non-iso-latin canonical representation must
     be given.  For instance, the CP1252 table can be defined as:

          (define cp1252
             '#("\xe2\x82\xac" ;; 0x80
                ""             ;; 0x81
                "\xe2\x80\x9a" ;; 0x82
                "\xc6\x92"     ;; 0x83
                "\xe2\x80\x9e" ;; 0x84
                "\xe2\x80\xa6" ;; 0x85
                "\xe2\x80\xa0" ;; 0x86
                "\xe2\x80\xa1" ;; 0x87
                "\xcb\x86"     ;; 0x88
                "\xe2\x80\xb0" ;; 0x89
                "\xc5\xa0"     ;; 0x8a
                "\xe2\x80\xb9" ;; 0x8b
                "\xc5\x92"     ;; 0x8c
                ""             ;; 0x8d
                "\xc5\xbd"     ;; 0x8e
                ""             ;; 0x8f
                ""             ;; 0x90
                "\xe2\x80\x98" ;; 0x91
                "\xe2\x80\x99" ;; 0x92
                "\xe2\x80\x9c" ;; 0x93
                "\xe2\x80\x9d" ;; 0x94
                "\xe2\x80\xa2" ;; 0x95
                "\xe2\x80\x93" ;; 0x96
                "\xe2\x80\x94" ;; 0x97
                "\xcb\x9c"     ;; 0x98
                "\xe2\x84\xa2" ;; 0x99
                "\xc5\xa1"     ;; 0x9a
                "\xe2\x80\xba" ;; 0x9b
                "\xc5\x93"     ;; 0x9c
                ""             ;; 0x9d
                "\xc5\xbe"     ;; 0x9e
                "\xc5\xb8"))   ;; 0x9f

     The argument INV-TABLE is an inverse table that can be build from a
     table and using the function 'inverse-utf8-table'.

 -- procedure: inverse-utf8-table vector
     Inverse an UTF-8 table into an object suitable for 'utf8->8bits'
     and 'utf8->8bits!'.


File: bigloo.info,  Node: Vectors,  Next: Homogeneous Vectors (SRFI-4),  Prev: Unicode (UCS-2) Strings,  Up: Scheme Library

5.1.11 Vectors
--------------

Vectors are not autoquoted objects.

 -- procedure: vector? obj

 -- procedure: make-vector k
 -- procedure: make-vector k obj
 -- library procedure: vector obj ...

 -- procedure: vector-length vector
 -- procedure: vector-ref vector k
 -- procedure: vector-set! vector k obj

 -- library procedure: vector->list vector
 -- library procedure: list->vector list

 -- library procedure: vector-fill! vector obj [start [end]]
     Stores OBJ in every element of VECTOR.  For instance:

          (let ((v (make-vector 5 #f)))
             (vector-fill! v #t)
             v)

 -- bigloo procedure: copy-vector vector len
     Allocate a new vector of size LEN and fills it with the first LEN
     element of VECTOR.  The new length LEN may be bigger than the old
     vector length.

 -- bigloo procedure: vector-copy vector start end
     VECTOR must be a vector, and START and END must be exact integers
     satisfying:

            0 <= START <= END <= (vector-length VECTOR)

     'vector-copy' returns a newly allocated vector formed from the
     elements of VECTOR beginning with index START (inclusive) and
     ending with index END (exclusive).

          (vector-copy '#(1 2 3 4) 0 4)
             => '#(1 2 3 4)
          (vector-copy '#(1 2 3 4) 1 3)
             => '#(2 3)

 -- bigloo procedure: vector-copy! target tstart source [sstart [send]]

     Copies a block of elements from SOURCE to TARGET, both of which
     must be vectors, starting in target at TSTART and starting in
     source at SSTART, ending when SEND - SSTART elements have been
     copied.  It is an error for TARGET to have a length less than
     'tstart + (send - sstart)'.  SSTART defaults to '0' and SEND
     defaults to the length of SOURCE.

  *Note r5rs.info: Vectors, for more details.

 -- bigloo procedure: vector-append vector ...

     Returns a newly allocated vector that contains all elements in
     order from the subsequent locations in vector ....

     Examples:

          (vector-append '#(x) '#(y)) => #(x y)
          (vector-append '#(a) '#(b c d)) => #(a b c d)
          (vector-append '#(a #(b)) '#(#(c))) => #(a #(b) #(c))

 -- bigloo procedure: vector-for-each proc vector ...
     Apply PROC to all the elements of the VECTORS.  The arity of PROC
     must be the number of passed vectors.  All vectors must have the
     same length.  The procedure is applied from elements of index '0'
     to '(vector-length vector) - 1'.

 -- bigloo procedure: vector-map proc vector ...
 -- bigloo procedure: vector-map! proc vector ...

     The function 'vector-map' creates a new vector whose size the is
     the size of its argument VECTOR.  Each elements of the new vector
     is the result of apply PROC to the corresponding elements of the
     initial vectors.

     The function 'vector-map!' modifies the elements of the argument
     VECTOR.

 -- bigloo procedure: vector-shrink! vector end

     Shrink a vector.  The argument VECTOR must be a vector, and END
     must be an exact integers satisfying:

            0 <= END <= (vector-length STRING)

     Shrink a vector.  The resulting vector's len is the minimum value
     of '(vector-length vec)' and NLEN.

     'vector-shrink!' returns a new vector formed from the values of
     VECTOR beginning with index 0 (inclusive) and ending with index END
     (exclusive).  As much as possible 'vector-shrink!' changes the
     argument VECTOR.  That is, as much as possible, and for the
     back-ends that enable it, VECTOR-SHRINK! operates a side effect on
     its argument.


File: bigloo.info,  Node: Homogeneous Vectors (SRFI-4),  Next: Control Features,  Prev: Vectors,  Up: Scheme Library

5.1.12 Homogeneous Vectors (SRFI-4)
-----------------------------------

Bigloo fully supports SRFI-4 specification of homogeneous vectors (see
<http://srfi.schemers.org/srfi-4/srfi-4.html>).

  Each homogeneous vector is represented by a Bigloo type.  That is:

   * '::s8vector' signed exact integer in the range -(2^7) to (2^7)-1
   * '::u8vector' unsigned exact integer in the range 0 to (2^8)-1
   * '::s16vector' signed exact integer in the range -(2^15) to (2^15)-1
   * '::u16vector' unsigned exact integer in the range 0 to (2^16)-1
   * '::s32vector' signed exact integer in the range -(2^31) to (2^31)-1
   * '::u32vector' unsigned exact integer in the range 0 to (2^32)-1
   * '::s64vector' signed exact integer in the range -(2^63) to (2^63)-1
   * '::u64vector' unsigned exact integer in the range 0 to (2^64)-1
   * 'f32vector' inexact small real
   * 'f64vector' inexact largest real

  Each homogeneous vector datatype has an external representation which
is supported by the read and write procedures and by the program parser.
Each datatype also has a set of associated predefined procedures
analogous to those available for Scheme's heterogeneous vectors.

  As noted by Marc Feeley's specification, for each value of TAG in {
s8, u8, s16, u16, s32, u32, s64, u64, f32,f64 }, if the datatype
TAGvector is supported, then

   * the external representation of instances of the datatype TAGvector
     is #TAG( ...elements...  ).

     For example, '#u8(0 100 #xff)' is an u8vector of length 3
     containing 0, 100 and 255; '#f64(-1.5)' is an f64vector of length 1
     containing -1.5.

     Note that the syntax for float vectors conflicts with Standard
     Scheme which parses '#f32()' as 3 objects: '#f', '32' and '()'.
     For this reason, conformance to this SRFI implies this minor
     nonconformance to Standard Scheme.

     This external representation is also available in program source
     code.  For example, '(set! x '#u8(1 2 3))' will set x to the object
     '#u8(1 2 3)'.  Literal homogeneous vectors must be quoted just like
     heterogeneous vectors must be.  Homogeneous vectors can appear in
     quasiquotations but must not contain unquote or unquote-splicing
     forms (i.e.  '`(,x #u8(1 2))' is legal but '`#u8(1 ,x 2)' is not).
     This restriction is to accomomdate the many Scheme systems that use
     the read procedure to parse programs.

   * the following predefined procedures are available:

      -- SRFI-4 procedure: TAGvector? obj
      -- SRFI-4 procedure: make-TAGvector n [ TAGvalue ]
      -- SRFI-4 procedure: TAGvector TAGvalue ...
      -- SRFI-4 procedure: TAGvector-length TAGvect
      -- SRFI-4 procedure: TAGvector-ref TAGvect i
      -- SRFI-4 procedure: TAGvector-set! TAGvect i TAGvalue
      -- SRFI-4 procedure: TAGvector->list TAGvect
      -- SRFI-4 procedure: list->TAGvector TAGlist

          where obj is any Scheme object, n is a nonnegative exact
          integer, i is a nonnegative exact integer less than the length
          of the vector, TAGvect is an instance of the TAGvector
          datatype, TAGvalue is a number of the type acceptable for
          elements of the TAGvector datatype, and TAGlist is a proper
          list of numbers of the type acceptable for elements of the
          TAGvector datatype.

          It is an error if TAGvalue is not the same type as the
          elements of the TAGvector datatype (for example if an exact
          integer is passed to f64vector).  If the fill value is not
          specified, the content of the vector is unspecified but
          individual elements of the vector are guaranteed to be in the
          range of values permitted for that type of vector.


File: bigloo.info,  Node: Control Features,  Prev: Homogeneous Vectors (SRFI-4),  Up: Scheme Library

5.1.13 Control features
-----------------------

 -- procedure: procedure? obj

 -- procedure: apply proc arg1 ... args

 -- library procedure: map proc list1 list2 ...
 -- bigloo procedure: map! proc list1 list2 ...
 -- library procedure: for-each proc list1 list2 ...

 -- library procedure: filter pred list ...
 -- library procedure: filter! pred list ...
     Strip out all elements of LIST for which the predicate PRED is not
     true.  The second version 'filter!' is destructive:

          (filter number? '(1 2 #\a "foo" foo 3)) => (1 2 3)
          (let ((l (list 1 2 #\a "foo" 'foo 3)))
             (set! l (filter! number? l))
             l)                                   => (1 2 3)

 -- library procedure: append-map proc list1 list2 ...
 -- library procedure: append-map! proc list1 list2 ...
     The expression
            (append-map f clist1 clist2 ...)

     is equivalent to:

            (apply append (map f clist1 clist2 ...))

     The expression
            (append-map! f clist1 clist2 ...)

     is equivalent to:

            (apply append! (map f clist1 clist2 ...))

 -- bigloo procedure: filter-map pred list ...
     As 'map' but only none '#f' values are accumulated in the resulting
     list.  The Bigloo implementation complies with the SRFI-1
     description.

          (filter-map (lambda (x) (if (number? x) '- #f)) '(1 2 #\a "foo" foo 3)) => (- - -)

 -- bigloo procedure: sort proc obj
 -- bigloo procedure: sort obj proc
     Sorts OBJ according to PROC test.  The argument OBJ can either be a
     vector or a list.  In either case, a copy of the argument is
     returned.  For instance:

          (let ((l '(("foo" 5) ("bar" 6) ("hux" 1) ("gee" 4))))
             (sort (lambda (x y) (string<? (car x) (car y))) l))
             => ((bar 6) (foo 5) (gee 4) (hux 1))

     The second form (which uses OBJ before PROC ensures backward
     compatibility with old Lisp systems, and older Bigloo versions.  It
     is deprecated.

 -- library procedure: force promise

 -- bigloo procedure: call/cc proc
     This function is the same as the 'call-with-current-continuation'
     function of the R5RS, see *note r5rs.info:
     (R5RS)call-with-current-continuation, but it is necessary to
     compile the module with the '-call/cc' option to use it, see
     Section *Note The Bigloo command line: Compiler Description.

     Note: Since 'call/cc' is difficult to compile efficiently, one
     might consider using 'bind-exit' instead.  For this reason, we
     decided to enable 'call/cc' only with a compiler option.

 -- bigloo syntax: bind-exit escape body
     This form provides an escape operator facility.  'bind-exit'
     evaluates the BODY, which may refer to the variable ESCAPE which
     will denote an "escape function" of one argument: when called, this
     escape function will return from the 'bind-exit' form with the
     given argument as the value of the 'bind-exit' form.  The ESCAPE
     can only be used while in the dynamic extent of the form.  Bindings
     introduced by 'bind-exit' are immutable.

          (bind-exit (exit)
           (for-each (lambda (x)
                       (if (negative? x)
                           (exit x)))
                     '(54 0 37 -3 245 19))
           #t)                                  => -3

          (define list-length
            (lambda (obj)
              (bind-exit (return)
               (letrec ((r (lambda (obj)
                              (cond ((null? obj) 0)
                                    ((pair? obj)
                                     (+ (r (cdr obj)) 1))
                                    (else (return #f))))))
                    (r obj)))))

          (list-length '(1 2 3 4))               => 4
          (list-length '(a b . c))               => #f

 -- bigloo syntax: unwind-protect expr protect
     This form provides protections.  Expression EXPR is evaluated.  If
     this evaluation requires the invocation of an escape procedure (a
     procedure bounded by the 'bind-exit' special form), PROTECT is
     evaluated before the control jump to the exit procedure.  If EXPR
     does not raise any exit procedure, 'unwind-protect' has the same
     behaviour as the 'begin' special form except that the value of the
     form is always the value of EXPR.

          (define (my-open f)
             (if (file-exists? f)
                 (let ((port (open-input-file f)))
                    (if (input-port? port)
                        (unwind-protect
                           (bar port)
                           (close-input-port port))))))

 -- procedure: dynamic-wind before thunk after

     Calls THUNK without arguments, returning the result(s) of this
     call.  BEFORE and AFTER are called, also without arguments, as
     required by the following rules (note that in the absence of calls
     to continuations captured using 'call/cc' the three arguments are
     called once each, in order).  BEFORE is called whenever execution
     enters the dynamic extent of the call to THUNK and AFTER is called
     whenever it exits that dynamic extent.  The dynamic extent of a
     procedure call is the period between when the call is initiated and
     when it returns.  In Scheme, because of 'call/cc', the dynamic
     extent of a call may not be a single, connected time period.  It is
     defined as follows:

        * The dynamic extent is entered when execution of the body of
          the called procedure begins.

        * The dynamic extent is also entered when execution is not
          within the dynamic extent and a continuation is invoked that
          was captured (using 'call/cc') during the dynamic extent.

        * It is exited when the called procedure returns.

        * It is also exited when execution is within the dynamic extent
          and a continuation is invoked that was captured while not
          within the dynamic extent.

     If a second call to 'dynamic-wind' occurs within the dynamic extent
     of the call to THUNK and then a continuation is invoked in such a
     way that the AFTERs from these two invocations of 'dynamic-wind'
     are both to be called, then the AFTER associated with the second
     (inner) call to 'dynamic-wind' is called first.

     If a second call to 'dynamic-wind' occurs within the dynamic extent
     of the call to THUNK and then a continuation is invoked in such a
     way that the BEFOREs from these two invocations of 'dynamic-wind'
     are both to be called, then the BEFORE associated with the first
     (outer) call to 'dynamic-wind' is called first.

     If invoking a continuation requires calling the BEFORE from one
     call to 'dynamic-wind' and the AFTER from another, then the AFTER
     is called first.

     The effect of using a captured continuation to enter or exit the
     dynamic extent of a call to BEFORE or AFTER is undefined.

          (let ((path '())
                (c #f))
            (let ((add (lambda (s)
                         (set! path (cons s path)))))
              (dynamic-wind
                (lambda () (add 'connect))
                (lambda ()
                  (add (call/cc
                         (lambda (c0)
                           (set! c c0)
                           'talk1))))
                (lambda () (add 'disconnect)))
              (if (< (length path) 4)
                  (c 'talk2)
                  (reverse path))))

             => (connect talk1 disconnect connect talk2 disconnect)

 -- bigloo procedure: unspecified
     Returns the _unspecified_ (noted as '#unspecified') object with no
     specific property.

 -- bigloo syntax: try exp handler
     This form is documented in Section *note Errors Assertions and
     Traces::.

 -- procedure: values obj ...

     Delivers all of its arguments to its continuation.  Except for
     continuations created by the 'call-with-values' procedure, all
     continuations take exactly one value.  Values might be defined as
     follows:

          (define (values . things)
            (call/cc
              (lambda (cont) (apply cont things))))

 -- procedure: call-with-values producer consumer
     Calls its PRODUCER argument with no values and a continuation that,
     when passed some values, calls the CONSUMER procedure with those
     values as arguments.  The continuation for the call to CONSUMER is
     the continuation of the call to call-with-values.

          (call-with-values (lambda () (values 4 5))
                            (lambda (a b) b))
              => 5
          (call-with-values * -)
              => -1

 -- bigloo syntax: multiple-value-bind (var ...) producer exp ...
 -- bigloo syntax: receive (var ...) producer exp ...
     Evaluates EXP ... in a environment where VAR ... are bound from the
     evaluation of PRODUCER.  The result of PRODUCER must be a call to
     'values' where the number of argument is the number of bound
     variables.
          (define (bar a)
             (values (modulo a 5) (quotient a 5)))

          (define (foo a)
             (multiple-value-bind (x y)
                (bar a)
                (print x " " y)))

          (foo 354)
             -| 4 70


File: bigloo.info,  Node: Input and Output,  Next: Serialization,  Prev: Scheme Library,  Up: Standard Library

5.2 Input and output
====================

This section describes Scheme operation for reading and writing data.
The section *note Files:: describes functions for handling files.

* Menu:

* Library functions::
* Memory mapped area::
* Zip::
* Tar::


File: bigloo.info,  Node: Library functions,  Next: Memory mapped area,  Up: Input and Output

5.2.1 Library functions
-----------------------

 -- library procedure: call-with-input-file string proc
 -- bigloo procedure: call-with-input-string string proc
 -- library procedure: call-with-output-file string proc
 -- library procedure: call-with-append-file string proc
 -- library procedure: call-with-output-string proc
     These two procedures call PROC with one argument, a port obtained
     by opening STRING.  See *note r5rs.info: (R5RS)Ports, for more
     details.

          (call-with-input-file "/etc/passwd"
             (lambda (port)
                (let loop ((line (read-line port)))
                   (if (not (eof-object? line))
                       (begin
                          (print line)
                          (loop (read-line port)))))))

 -- procedure: input-port? obj
 -- procedure: input-string-port? obj
 -- procedure: output-port? obj
 -- procedure: output-string-port? obj
 -- procedure: port? obj

 -- bigloo procedure: input-port-name obj
 -- bigloo procedure: input-port-name-set! obj name
 -- bigloo procedure: output-port-name obj
 -- bigloo procedure: output-port-name-set! obj name
     Returns/sets the file name for which OBJ has been opened.

 -- bigloo (>=3.8d) procedure: input-port-length obj
     Returns the source number of bytes, i.e., the number characters
     contains in the source.  Returns '-1' if that number is unknown
     (typically for a pipe).

 -- bigloo (>=2.8b) procedure: input-port-timeout-set! port time
 -- bigloo (>=2.8b) procedure: output-port-timeout-set! port time
     These two functions limit the time an read or write operation may
     last.  If the TIME limit (expressed in microseconds) exceeded, an
     exception of time '&io-timeout-error' is raised.

     Setting a timeout equal to 0, restore the socket in blocking mode.
     Setting a timeout with a value lesser than 0 is ignored.

     Note: ports created from sockets share their internal file
     descriptor.  Hence it is erroneous to set a timeout for only one of
     the two ports.  Both must be set.

 -- bigloo procedure: output-port-flush-hook port
 -- bigloo procedure: output-port-flush-hook-set! port hook
     Returns (resp.  sets) the _flush hook_ of the output PORT.  The
     flush hook is a procedure of two arguments, the output port and the
     number of characters that are to be actually written out during the
     flush.  It is unspecified when the hook is invoked, however, one
     may expect the C back-end to invoke the hook only when output
     buffers are full.  The other back-ends (JVM and DOTNET) are likely
     to invoke the hook as soon as a character is to be written.

     A flush hook can return two types of values:

        * A string, which is then directly displayed to the system
          stream associated with the output port.

        * An integer, which denotes the number of characters of the
          output port flush buffer (see 'output-port-flush-buffer') that
          have to be displayed on the system stream.

 -- bigloo procedure: output-port-flush-buffer port
 -- bigloo procedure: output-port-flush-buffer-set! port buffer
     These functions gets and sets a buffer that can be used by program
     by the flush hooks.  The runtime system makes no provision for
     automatically allocated these buffers that hence must be manually
     allocated by programs.  The motivation for flush buffer is to allow
     programs to write flush hooks that don't have to allocate a new
     string each time invoked.

 -- bigloo procedure: output-port-close-hook port
 -- bigloo procedure: output-port-close-hook-set! port proc
     Returns (resp.  sets) the _close hook_ of the output PORT.  The
     close hook is a procedure of one argument, the closed port.  The
     hook is invoked _after_ the PORT is closed.

 -- bigloo procedure: input-port-close-hook port
 -- bigloo procedure: input-port-close-hook-set! port proc
     Returns (resp.  sets) the _close hook_ of the input PORT.  The
     close hook is a procedure of one argument, the closed port.

     Example:
          (let ((p (open-input-string "/etc/passwd")))
            (input-port-close-hook-set! p (lambda () (display 'done)))
            ...
            (close-input-port p))

 -- bigloo procedure: input-port-reopen! obj
     Re-open the input port OBJ.  That is, re-start reading from the
     first character of the input port.

 -- procedure: current-input-port
 -- procedure: current-output-port
 -- bigloo procedure: current-error-port

 -- optional procedure: with-input-from-file string thunk
 -- optional procedure: with-input-from-string string thunk
 -- optional procedure: with-input-from-procedure procedure thunk
 -- optional procedure: with-output-to-file string thunk
 -- optional procedure: with-append-to-file string thunk
 -- bigloo procedure: with-error-to-file string thunk
 -- bigloo procedure: with-output-to-string thunk
 -- bigloo procedure: with-output-to-procedure procedure thunk
 -- bigloo procedure: with-error-to-string thunk
 -- bigloo procedure: with-error-to-procedure procedure thunk
     A port is opened from file STRING.  This port is made the current
     input port (resp.  the current output port or the current error
     port) and THUNK is called.  See *note r5rs.info: (R5RS)Ports, for
     more details.

          (with-input-from-file "/etc/passwd"
             (lambda ()
                (let loop ((line (read-line (current-input-port))))
                   (if (not (eof-object? line))
                       (begin
                          (print line)
                          (loop (read-line (current-input-port))))))))

 -- bigloo procedure: with-input-from-port port thunk
 -- bigloo procedure: with-output-to-port port thunk
 -- bigloo procedure: with-error-to-port port thunk

     'with-input-from-port', 'with-output-to-port' and
     'with-error-to-port' all suppose PORT to be a legal port.  They
     call THUNK making PORT the current input (resp.  output or error)
     port.  None of these functions close PORT on the continuation of
     THUNK.

          (with-output-to-port (current-error-port)
             (lambda () (display "hello")))

 -- procedure: open-input-file file-name [buffer #f] [timeout 5000000]

     If FILE-NAME is a regular file name, 'open-input-file' behaves as
     the function defined in the Scheme report.  If FILE-NAME starts
     with special prefixes it behaves differently.  Here are the
     recognized prefixes:

        * '| ' (a string made of the characters '#\|' and '#\space')
          Instead of opening a regular file, Bigloo opens an input pipe.
          The same syntax is used for output file.

               (define pin (open-input-file "| cat /etc/passwd"))
               (define pout (open-output-file "| wc -l"))

               (display (read pin) pout)
               (close-input-port pin)
               (newline pout)
               (close-output-port pout)

        * 'pipe:' Same as '| '.

        * 'file:' Opens a regular file.

        * 'gzip:' Opens a port on a gzipped filed.  This is equivalent
          to 'open-input-gzip-file'.  Example:

               (with-input-from-file "gzip:bigloo.tar.gz"
                  (lambda ()
                     (send-chars (current-input-port) (current-output-port))))

        * 'string:' Opens a port on a string.  This is equivalent to
          'open-input-string'.  Example:

               (with-input-from-file "string:foo bar Gee"
                  (lambda ()
                     (print (read))
                     (print (read))
                     (print (read))))
                  -| foo
                  -| bar
                  -| Gee

        * 'http://server/path'

          Opens an _http_ connection on 'server' and open an input file
          on file 'path'.

        * 'http://server:port-number/path'
        * 'http://user:password@server:port-number/path'

          Opens an _http_ connection on 'server', on port number 'port'
          with an authentication and open an input file on file 'path'.

        * 'ftp://server/path'
        * 'ftp://user:password@server/path'

          Opens an _ftp_ connection on 'server' and open an input file
          on file 'path'.  Log in as anonymous.

        * 'ressource:'

          Opens a JVM _ressource_ file.  Opening a 'ressource:' file in
          non JVM backend always return '#f'.  On the JVM backend it
          returns a input port if the ressource exists.  Otherwise, it
          returns '#f'.

     The optional argument BUFFER can either be:

        * A positive fixnum, this gives the size of the buffer.
        * The boolean '#t', a buffer is allocated.
        * The boolean '#f', the socket is unbufferized.
        * A string, it is used as buffer.

     The optional argument TIMEOUT, an integer represents a microseconds
     timeout for the open operation.

 -- bigloo procedure: open-input-gzip-file file-name [buffer #t]
 -- bigloo procedure: open-input-gzip-port input-port [buffer #t]

     Open respectively a gzipped file for input and a port on a gzipped
     stream.  Note that closing a gzip port opened from a port PI does
     not close the PI port.

          (let ((p (open-input-gzip-file "bigloo.tar.gz")))
             (unwind-protect
                (read-line p1)
                (close-input-port p)))

     This can be decomposed as:

          (let* ((p1 (open-input-file "bigloo.tar.gz"))
                 (p2 (open-input-gzip-port p1)))
             (unwind-protect
                (read-line p2)
                (close-input-port p2)
                (close-input-port p1)))

 -- bigloo procedure: open-input-zlib-file file-name [buffer #t]
 -- bigloo procedure: open-input-zlib-port input-port [buffer #t]

     Open respectively a zlib file for input and a port on a zlib
     stream.  Note that closing a zlib port opened from a port PI does
     not close the PI port.

 -- bigloo procedure: open-input-string string [start 0] [end]
 -- bigloo procedure: open-input-string! string [start 0] [end]

     STRING must be a string, and START and END must be exact integers
     satisfying:

            0 <= START <= END <= (string-length STRING)

     The optional argument END defaults to '(string-length STRING)'.

     Returns an 'input-port' able to deliver characters from STRING.

     The function 'open-input-string!' acts as 'open-input-string' but
     it might modify the string it receives as parameter.

 -- bigloo procedure: open-input-c-string string
     Returns an 'input-port' able to deliver characters from C STRING.
     The buffer used by the input port is the exact same string as the
     argument.  That is, no buffer is allocated.

 -- bigloo procedure: open-input-ftp-file file-name [buffer #t]
     Returns an 'input-port' able to deliver characters from a remote
     file located on a FTP server.

     Example:

          (let ((p (open-input-ftp-file "ftp-sop.inria.fr/ls-lR.gz'')))
            (unwind-protect
               (read-string p)
               (close-input-port p)))

     The file name may contain user authentication such as:

          (let ((p (open-input-ftp-file "anonymous:foo@ftp-sop.inria.fr/ls-lR.gz'')))
            (unwind-protect
               (read-string p)
               (close-input-port p)))

 -- bigloo procedure: open-input-procedure procedure [buffer #t]
     Returns an 'input-port' able to deliver characters from PROCEDURE.
     Each time a character has to be read, the PROCEDURE is called.
     This procedure may returns a string of characters, or the boolean
     '#f'.  This last value stands for the end of file.

     Example:

          (let ((p (open-input-procedure (let ((s #t))
          				  (lambda ()
          				     (if s
          					 (begin
                                                      (set! s #f)
                                                      "foobar")
          					 s))))))
             (read))

 -- bigloo procedure: unread-char! char [input-port]
 -- bigloo procedure: unread-string! string [input-port]
 -- bigloo procedure: unread-substring! string start end [input-port]
     Pushes the given CHAR, STRING or substring into the input-port.
     The next read character(s) will be the pushed ones.  The INPUT-PORT
     must be buffered and not be closed.

     Example:

          (define p (open-input-string "a ymbol c"))
          (read p)                       => a
          (read-char p)                  => #\space
          (unread-char! #\s p)
          (read p)                       => symbol
          (read-char p)                  => #\space
          (read p)                       => c
          (char-ready? p)                => #f
          (unread-string! "sym1 sym2" p)
          (char-ready? p)                => #t
          (read p)                       => sym1
          (read p)                       => sym2

 -- procedure: open-output-file file-name
     The same syntax as 'open-input-file' for file names applies here.
     When a file name starts with '| ', Bigloo opens an output pipe
     instead of a regular file.

 -- bigloo procedure: append-output-file file-name
     If 'file-name' exists, this function returns an 'output-port' on
     it, without removing it.  New output will be appended to FILE-NAME.
     If 'file-name' does not exist, it is created.

 -- bigloo procedure: open-output-string
     This function returns an _output string port_.  This object has
     almost the same purpose as 'output-port'.  It can be used with all
     the printer functions which accept 'output-port'.  An output on a
     _output string port_ memorizes all the characters written.  An
     invocation of 'flush-output-port' or 'close-output-port' on an
     _output string port_ returns a new string which contains all the
     characters accumulated in the port.

 -- bigloo procedure: get-output-string output-port
     Given an output port created by 'open-output-string', returns a
     string consisting of the characters that have been output to the
     port so far.

 -- bigloo procedure: open-output-procedure proc [flush [close]]
     This function returns an _output procedure port_.  This object has
     almost the same purpose as 'output-port'.  It can be used with all
     the printer functions which accept 'output-port'.  An output on a
     _output procedure port_ invokes the PROC procedure each time it is
     used for writing.  That is, PROC is invoked with a string denoting
     the displayed characters.  When the function 'flush-output-port' is
     called on such a port, the optional FLUSH procedure is invoked.
     When the function 'close-output-port' is called on such a port, the
     optional CLOSE procedure is invoked.

 -- procedure: close-input-port input-port
 -- procedure: close-output-port output-port
     According to R5RS, the value returned is unspecified.  However, if
     _output-port_ was created using 'open-output-string', the value
     returned is the string consisting of all characters sent to the
     port.

 -- procedure: closed-input-port? input-port
 -- procedure: closed-output-port? output-port
     Predicates that return '#t' if and if their associated port is
     closed.  Return '#f' otherwise.

 -- bigloo procedure: input-port-name input-port
     Returns the name of the file used to open the INPUT-PORT.

 -- bigloo procedure: input-port-position port
 -- bigloo procedure: output-port-position port
     Returns the current position (a character number), in the PORT.

 -- bigloo procedure: set-input-port-position! port pos
 -- bigloo procedure: set-output-port-position! port pos
     These functions set the file position indicator for PORT.  The new
     position, measured in bytes, is specified by POS.  It is an error
     to seek a port that cannot be changed (for instance, a procedure or
     a console port).  The result of these functions is unspecified.  An
     error is raised if the position cannot be changed.

 -- bigloo procedure: input-port-reopen! input-port
     This function re-opens the input 'input-port'.  That is, it reset
     the position in the INPUT-PORT to the first character.

 -- procedure: read [input-port]
 -- bigloo procedure: read/case case [input-port]
 -- bigloo procedure: read-case-sensitive [input-port]
 -- bigloo procedure: read-case-insensitive [input-port]
     Read a lisp expression.  The case sensitivity of 'read' is
     unspecified.  If have to to enforce a special behavior regarding
     the case, use 'read/case', 'read-case-sensitive' or
     'read-case-insensitive'.  Let us consider the following source
     code: The value of the 'read/case''s CASE argument may either be
     'upcase', 'downcase' or 'sensitive'.  Using any other value is an
     error.

          (define (main argv)
             (let loop ((exp (read-case-sensitive)))
                (if (not (eof-object? exp))
                    (begin
                       (display "exp: ")
                       (write exp)
                       (display " [")
                       (display exp)
                       (display "]")
                       (print " eq?: " (eq? exp 'FOO) " " (eq? exp 'foo))
                       (loop (read-case-sensitive))))))

     Thus:
          > a.out
          foo
            -| exp: foo [foo] eq?: #f #t
          FOO
            -| exp: FOO [FOO] eq?: #t #f

 -- bigloo procedure: read/rp grammar port
 -- bigloo procedure: read/lalrp lalrg rg port [emptyp]
     These functions are fully explained in *note Regular Parsing::, and
     *note Lalr Parsing::.

 -- bigloo procedure: define-reader-ctor symbol procedure

     Note: This feature is experimental and might be removed in feature
     versions.

     The present SRFI-10
     (<http://srfi.schemers.org/srfi-10/srfi-10.html>) proposes an
     extensible external representation of Scheme values, a notational
     convention for future SRFIs.  This SRFI adds '#,(' as a new token
     and extends production rules of the grammar for a Scheme reader.
     The '#,()' form can be used for example to denote values that do
     not have a convenient printed representation, as well for
     conditional code compilation.  It is proposed that future SRFIs
     that contain new read syntax for values use the '#,()' notation
     with an appropriate tag symbol.

     As a particular example and the reference implementation for the
     '#,()' convention, this SRFI describes an interpretation of the
     '#,()' external form as a read-time application.

     Examples:
          (define-reader-ctor 'list list)
          (with-input-from-string "#,(list 1 2 #f \"4 5\")" read) => (1 2 #f "4 5")

          (define-reader-ctor '+ +)
          (with-input-from-string "#,(+ 1 2)" read) => 3

 -- bigloo procedure: set-read-syntax! char procedure

     Note: This feature is experimental and might be removed in feature
     versions.

     Registers a function PROCEDURE to be invoked with one argument, an
     input-port, that is invoked when the reader hits an unparsed
     character.

     Example:

          (set-read-syntax! #\{
             (lambda (port)
                (let loop ((c (peek-char port)) (exps '()))
          	 (cond ((eof-object? c)
          		(error "{" "EOF encountered while parsing { ... } clause" port))
          	       ((char=? c #\})
          		(read-char port)   ; discard
          		`(begin ,@(reverse exps)))
          	       ((char-whitespace? c)
          		(read-char port)   ; discard whitespace
          		(loop (peek-char port) exps))
          	       (else
          		(let ((exp (read port)))
          		   (loop (peek-char port)
                                (cons exp exps))))))))

 -- procedure: read-char [port]
 -- procedure: read-byte [port]
 -- procedure: peek-char [port]
 -- procedure: peek-byte [port]
 -- procedure: eof-object? obj

 -- procedure: char-ready? [port]
     As specified in the R5Rs, *note r5rs.info: (R5RS)Ports,
     'char-ready?' returns #t if a character is ready on the input PORT
     and returns #f otherwise.  If 'char-ready' returns #t then the next
     'read-char' operation on the given PORT is guaranteed not to hang.
     If the PORT is at end of file then 'char-ready?' returns #t.  PORT
     may be omitted, in which case it defaults to the value returned by
     'current-input-port'.

     When using 'char-ready?' consider the latency that may exists
     before characters are available.  For instance, executing the
     following source code:

          (let* ((proc (run-process "/bin/ls" "-l" "/bin" output: pipe:))
                 (port (process-output-port proc)))
             (let loop ((line (read-line port)))
                (print "char ready " (char-ready? port))
                (if (eof-object? line)
                    (close-input-port port)
                    (begin
                       (print line)
                       (loop (read-line port))))))

     Produces outputs such as:

          char ready #f
          total 7168
          char ready #f
          -rwxr-xr-x    1 root     root         2896 Sep  6  2001 arch
          char ready #f
          -rwxr-xr-x    1 root     root        66428 Aug 25  2001 ash
          char ready #t
          ...

     For a discussion of Bigloo processes, see *note Process::.

     _Note:_ Thanks to Todd Dukes for the example and the suggestion of
     including it this documentation.

 -- bigloo procedure: read-line [input-port]
 -- bigloo procedure: read-line-newline [input-port]
     Reads characters from INPUT-PORT until a '#\Newline', a '#\Return'
     or an 'end of file' condition is encountered.  'read-line' returns
     a newly allocated string composed of the characters read.

     The strings returned by 'read-line' do not contain the newline
     delimiters.  The strings returned by 'read-line-newline' do contain
     them.

 -- bigloo procedure: read-lines [input-port]
     Accumulates all the line of an INPUT-PORT into a list.

 -- bigloo procedure: read-of-strings [input-port]
     Reads a sequence of non-space characters on INPUT-PORT, makes a
     string of them and returns the string.

 -- bigloo procedure: read-string [input-port]
     Reads all the characters of INPUT-PORT into a string.

 -- bigloo procedure: read-chars size [input-port]
 -- bigloo procedure: read-chars! buf size [input-port]

     The function 'read-chars' returns a newly allocated strings made of
     SIZE characters read from INPUT-PORT (or from
     '(current-input-port)' if INPUT-PORT is not provided).  If less
     than SIZE characters are available on the input port, the returned
     string is smaller than SIZE.  Its size is the number of available
     characters.

     The function 'read-chars!' fills the buffer BUF with at most SIZE
     characters.

 -- bigloo procedure: read-fill-string! s o len [input-port]
     Fills the string S starting at offset O with at most LEN characters
     read from the input port INPUT-PORT (or from '(current-input-port)'
     if INPUT-PORT is not provided).  This function returns the number
     of read characters (which may be smaller than LEN if less
     characters are available) or the end of file object.  The argument
     'len' is a small integer.

     The function 'read-fill-string!' is similar to 'read-chars!' except
     that it returns the _end-of-file_ object on termination while
     'read-chars!' returns 0.

     Example:
          (let ((s (make-string 10 #\-)))
             (with-input-from-string "abcdefghijlkmnops"
                (lambda ()
                   (read-fill-string! s 3 5)
                   s)))
             => ---abcde--

 -- bigloo procedure: port->string-list input-port
     Returns a list of strings composed of the elements of INPUT-PORT.

 -- bigloo procedure: port->list input-port reader
 -- bigloo procedure: port->sexp-list input-port
     'Port->list' applies reader to port repeatedly until it returns
     EOF, then returns a list of results.  'Port->list-sexp' is
     equivalent to '(port->list read port)'.

 -- bigloo procedure: file->string path
     This function builds a new string out of all the characters of the
     file PATH.  If the file cannot be open or read, an 'IO_EXCEPTION'
     is raised.

 -- bigloo procedure: send-chars input-port output-port [len] [offset]
 -- bigloo procedure: send-file filename output-port [len] [offset]
     Transfer the characters from INPUT-PORT to OUTPUT-PORT.  This
     procedure is sometimes mapped to a system call (such as 'sendfile'
     under Linux) and might thus be more efficient than copying the
     ports by hand.  The optional argument OFFSET specifies an offset
     from which characters of INPUT-PORT are sent.  The function
     'send-chars' returns the number of characters sent.

     The function 'send-file' opens the file FILENAME in order to get
     its input port.  On some backends, 'send-file' might be more
     efficient than 'send-chars' because it may avoid creating a
     full-fledged Bigloo 'input-port'.

     Note that the type of LEN and OFFSET is 'elong' (i.e., exact long),
     which is also returned by 'file-size'.

 -- library procedure: write obj [output-port]
 -- library procedure: display obj [output-port]
 -- bigloo procedure: print obj ...
     This procedure allows several objects to be displayed.  When all
     these objects have been printed, 'print' adds a newline.

 -- bigloo procedure: display* obj ...
     This function is similar to 'print' but does not add a newline.

 -- bigloo procedure: fprint output-port obj ...
     This function is the same as 'print' except that a port is
     provided.

 -- procedure: write-char char [output-port]
 -- procedure: write-byte byte [output-port]
     These procedures write a char (respec.  a byte, i.e., in integer in
     the range 0..255) to the OUTPUT-PORT.

 -- procedure: newline [output-port]
 -- bigloo procedure: flush-output-port output-port
     This procedure flushes the output port OUTPUT-PORT.  This function
     _does not_ reset characters accumulated in string port.  For this
     uses, 'reset-output-port'.

 -- procedure: newline [output-port]
 -- bigloo procedure: reset-output-port output-port
     This function is equivalent to 'flush-output-port' but in addition,
     for string ports, it reset the internal buffer that accumulates the
     displayed characters.

 -- bigloo procedure: format format-string [objs]

     _Note_: Many thanks to Scott G. Miller who is the author of
     SRFI-28.  Most of the documentation of this function is copied from
     the SRFI documentation.

     Accepts a message template (a Scheme String), and processes it,
     replacing any escape sequences in order with one or more
     characters, the characters themselves dependent on the semantics of
     the escape sequence encountered.

     An escape sequence is a two character sequence in the string where
     the first character is a tilde '~'.  Each escape code's meaning is
     as follows:

        * '~a' The corresponding value is inserted into the string as if
          printed with display.
        * '~s' The corresponding value is inserted into the string as if
          printed with write.
        * '~%' or '~n' A newline is inserted A newline is inserted.
        * '~~' A tilde '~' is inserted.
        * '~r' A return ('#\Return') is inserted.
        * '~v' The corresponding value is inserted into the string as if
          printed with display followed by a newline.  This tag is hence
          equivalent to the sequence '~a~n'.
        * '~c' The corresponding value must be a character and is
          inserted into the string as if printed with write-char.
        * '~d', '~x', '~o', '~b' The corresponding value must must be a
          number and is printed with radix 16, 8 or 2.
        * '~l' If the corresponding value is a proper list, its items
          are inserted into the string, separated by whitespaces,
          without the surrounding parenthesis.  If the corresponding
          value is not a list, it behaves as '~s'.
        * '~(<sep>)' If the corresponding value is a proper list, its
          items are inserted into the string, separated from each other
          by SEP, without the surrounding parenthesis.  If the
          corresponding value is not a list, it behaves as '~s'.
        * '~Ndxob' Print a number in N columns with space padding.
        * '~N,<padding>dxob' Print a number in NUM columns with PADDING
          padding.

     '~a' and '~s', when encountered, require a corresponding Scheme
     value to be present after the format string.  The values provided
     as operands are used by the escape sequences in order.  It is an
     error if fewer values are provided than escape sequences that
     require them.

     '~%' and '~~' require no corresponding value.

          (format "Hello, ~a" "World!")
             -| Hello, World!
          (format "Error, list is too short: ~s~%" '(one "two" 3))
             -| Error, list is too short: (one "two" 3)
          (format "a ~l: ~l" "list" '(1 2 3))
             -| a list: 1 2 3
          (format "a ~l: ~(, )" "list" '(1 2 3))
             -| a list: 1, 2, 3
          (format "~3d" 4)
             -|   4
          (format "~3,-d" 4)
             -| --4
          (format "~3x" 16)
             -|  10
          (format "~3,0d" 5)
             -| 005

 -- bigloo procedure: printf format-string [objs]
 -- bigloo procedure: fprintf port format-string [objs]
     Formats OBJS to the current output port or to the specified PORT.

 -- bigloo procedure: pp obj [output-port]
     Pretty print OBJ on OUTPUT-PORT.

 -- bigloo variable: *pp-case*
     Sets the variable to 'respect', 'lower' or 'upper' to change the
     case for pretty-printing.

 -- bigloo variable: *pp-width*
     The width of the pretty-print.

 -- bigloo procedure: write-circle obj [output-port]
     Display recursive object OBJ on OUTPUT-PORT.  Each component of the
     object is displayed using the 'write' library function.

 -- bigloo procedure: display-circle obj [output-port]
     Display recursive object OBJ on OUTPUT-PORT.  Each component of the
     object is displayed using the 'display' library function.

     For instance:
          (define l (list 1 2 3))
          (set-car! (cdr l) l)
          (set-car! (cddr l) l)
          (display-circle l)  -| #0=(1 #0# #0#)

 -- bigloo procedure: display-string string output-port
 -- bigloo procedure: display-substring string start end output-port

     STRING must be a string, and START and END must be exact integers
     satisfying '0 <= start <= end <= (string-length string)'.

     'Display-substring' displays a string formed from the characters of
     string beginning with index START (inclusive) and ending with index
     END (exclusive).

 -- bigloo procedure: password [prompt]
     Reads a password from the current input port.  The reading stops
     when the user hits the ,(code "Enter") key.

 -- bigloo procedure: open-pipes [name]
     Opens a bi-directional pipes.  Returns two values, an 'input-port'
     and an 'output-port'.  The optional argument NAME is only used for
     debugging.

     Example:
          (multiple-value-bind (in out)
            (open-pipes "my pipe")
            (write-char #\z out)
            (flush-output-port out))

 -- bigloo procedure: select [:timeout 0] [:read '()] [:write '()]
          [:except '()]
     A wrapper of the Posix 'select' function.  Returns three values,
     the three lists of objects that are ready for reading, respectively
     writing, or that are in error.

     Example:
          (define *inpipe* #f)
          (define *outpipe* #f)
          (define *watch-mutex* (make-mutex "watch"))
          (define *sockets* '())

          (define (watch socket onclose)
             (synchronize *watch-mutex*
                (set! *sockets* (cons socket *sockets*))
                (if *outpipe*
          	  (begin
          	     (write-char *outpipe*)
          	     (flush-output-port *outpipe*))
          	  (thread-start!
          	     (instantiate::hopthread
          		(body (watch-thread onclose)))))))

          (define (watch-thread onclose)
             (let loop ()
                (synchronize *watch-mutex*
          	 (unless *inpipe*
          	    (multiple-value-bind (in out)
          	       (open-pipes)
          	       (set! *inpipe* in)
          	       (set! *outpipe* out))))
                (multiple-value-bind (readfs _ _)
          	 (select :read (cons *inpipe* *sockets*))
          	 (let ((socks (filter socket? readfs)))
          	    (for-each onclose socks)
          	    (synchronize *watch-mutex*
          	       (for-each (lambda (s)
          			    (set! *sockets* (remq! s *sockets*)))
          		  socks)
          	       (unless (pair? *sockets*)
          		  (close-input-port *inpipe*)
          		  (close-output-port *outpipe*)
          		  (set! *inpipe* #f)
          		  (set! *outpipe* #f)))
          	    (when *outpipe*
          	       (loop))))))

 -- bigloo procedure: lockf output-port command [len 0]
     Lock a file descriptor or an output port.  It is an error to call
     'lockf' with an port not open on a plain file (i.e., a port open
     with 'open-output-file', or its variants).

     The COMMAND argument is one of:

        * 'lock': locks the file, raises an error on failure.
        * 'ulock': unlocks the file, raises an error on failure.
        * 'test': tests whether a file is locked or not.
        * 'tlock': tries to lock a file, return '#t' upon success and
          '#f' otherwise.

     The argument LEN is the portion of the file to be locked.


File: bigloo.info,  Node: Memory mapped area,  Next: Zip,  Prev: Library functions,  Up: Input and Output

5.2.2 mmap
----------

The 'mmap' function asks to map a file into memory.  This memory area
can be randomly accessed as a string.  In general using 'mmap' improves
performance in comparison with equivalent code using regular ports.

 -- bigloo procedure: mmap? obj
     Returns '#t' if and only if OBJ has been produced by 'open-mmap'.
     Otherwise, it returns '#f'.

 -- bigloo procedure: open-mmap path [mode]
     Maps a file PATH into memory.  The optional argument MODE specifies
     how the file is open.  The argument can be:

        * 'read: #t' The memory can be read
        * 'read: #f' The memory cannot be read
        * 'write: #t' The memory can be written
        * 'write: #f' The memory is read-only.

 -- bigloo procedure: string->mmap string [mode]
     Wrap a Bigloo string into a mmap object.

 -- bigloo procedure: mmap-name mm
     Returns the file name of the memory map MM.

 -- bigloo procedure: close-mmap mm
     Closes the memory mapped.  Returns '#t' on success, '#f' otherwise.

 -- bigloo procedure: mmap-length mm
     Returns the length, an exact integer, of the memory mapped.

 -- bigloo procedure: mmap-read-position mm
 -- bigloo procedure: mmap-read-position-set! mm offset
 -- bigloo procedure: mmap-write-position mm
 -- bigloo procedure: mmap-write-position-set! mm offset
     Returns and sets the read and write position of a memory mapped
     memory.  The result and the argument are exact integers.

 -- bigloo procedure: mmap-ref mm offset
     Reads the character in MM at OFFSET, an exact long (::elong).  This
     function sets the read position to 'offset + 1'.

 -- bigloo procedure: mmap-set! mm offset char
     Writes the character CHAR in MM at OFFSET, an exact long (::elong).
     This function sets the write position to 'offset + 1'.

 -- bigloo procedure: mmap-substring mm start end
     Returns a newly allocated string made of the characters read from
     MM starting at position START and ending at position END - 1.  If
     the values 'start' and 'end' are not ranged in '[0...(mmap-length
     mm)]', an error is signaled.  The function 'mmap-substring' sets
     the read position to 'end'.

 -- bigloo procedure: mmap-substring-set! mm start str
     Writes the string STR to MM at position START.  If the values
     'start' and 'start + (string-length str)' are not ranged in
     '[0...(mmap-length mm)[', an error is signaled.  The function
     'mmap-substring' sets the write position to 'start + (string-length
     str)'.

 -- bigloo procedure: mmap-get-char mm
 -- bigloo procedure: mmap-put-char! mm c
 -- bigloo procedure: mmap-get-string mm len
 -- bigloo procedure: mmap-put-string! mm str
     These functions get (resp.  put) character and strings into a
     memory mapped area.  They increment the read (resp.  write)
     position.  An error is signaled if the characters read (resp.
     writen) outbound the length of the memory mapped.


File: bigloo.info,  Node: Zip,  Next: Tar,  Prev: Memory mapped area,  Up: Input and Output

5.2.3 zip
---------

 -- bigloo procedure: port->gzip-port input-port [buffer #t]
 -- bigloo procedure: port->zlib-port input-port [buffer #t]
 -- bigloo procedure: port->inflate-port input-port [buffer #t]
     These functions take a regular port as input (INPUT-PORT).  They
     construct a new port that automatically _unzip_ the read
     characters.  The 'inflate' version does not parse a gunzip-header
     before inflating the content.

 -- bigloo procedure: open-input-inflate-file path [buffer #t]
     These function open a gzipped file for input.  The file is
     automatically unzipped when the characters are read.  It is
     equivalent to:

          (let ((p (open-input-port path)))
            (port->gzip-port p))

     The function 'open-input-inflate-file' is similar to
     'open-input-gzip-file' but it does not parse a gunzip-header before
     inflating the content.

 -- bigloo procedure: gunzip-sendchars input-port output-port
 -- bigloo procedure: inflate-sendchars input-port output-port
     Transmit all the characters from the gzipped INPUT-PORT to the
     OUTPUT-PORT.

     Note that the function 'send-chars' can also be used on gzipped
     input-ports.

 -- bigloo procedure: gunzip-parse-header input-port
     Parse the header of INPUT-PORT.  Returns '#f' if and only if the
     port is not gzipped.


File: bigloo.info,  Node: Tar,  Prev: Zip,  Up: Input and Output

5.2.4 tar
---------

 -- bigloo procedure: tar-read-header [input-port]
     Reads a tar header from INPUT-PORT.  If the input-port does not
     conform the tar format, an IO exception is raised.  On success a
     _tar-header_ descriptor is returned.

 -- bigloo procedure: tar-read-block tar-header [input-port]
     Reads the content of the TAR-HEADER block.

 -- bigloo procedure: tar-round-up-to-record-size int
     Rounds up tar-block sizes.

 -- bigloo procedure: tar-header-name tar-header
 -- bigloo procedure: tar-header-mode tar-header
 -- bigloo procedure: tar-header-uid tar-header
 -- bigloo procedure: tar-header-gid tar-header
 -- bigloo procedure: tar-header-size tar-header
 -- bigloo procedure: tar-header-mtim tar-header
 -- bigloo procedure: tar-header-checksum tar-header
 -- bigloo procedure: tar-header-type tar-header
 -- bigloo procedure: tar-header-linkname tar-header
 -- bigloo procedure: tar-header-uname tar-header
 -- bigloo procedure: tar-header-gname tar-header
 -- bigloo procedure: tar-header-devmajor tar-header
 -- bigloo procedure: tar-header-devminir tar-header
     Return various information about TAR-HEADER.

  The following example simulates the Unix command 'tar xvfz':

     (define (untar path)
        (let ((pz (open-input-gzip-port path)))
           (unwind-protect
     	 (let loop ((lst '()))
     	    (let ((h (tar-read-header pz)))
     	       (if (not h)
     		   lst
     		   (case (tar-header-type h)
     		      ((dir)
     		       (let ((path (tar-header-name h)))
     			  (if (make-directory path)
     			      (loop lst)
     			      (error 'untar
     				     "Cannot create directory"
     				     path))))
     		      ((normal)
     		       (let* ((path (tar-header-name h))
     			      (dir (dirname path)))
     			  (when (and (file-exists? dir) (not (directory? dir)))
     			     (delete-file dir))
     			  (unless (file-exists? dir)
     			     (make-directory dir))
     			  (with-output-to-file path
     			     (lambda ()
     				(display (tar-read-block h pz))))
     			  (loop (cons path lst))))
     		      (else
     		       (error 'untar
     			      (format "Illegal file type `~a'"
     				      (tar-header-type h))
     			      (tar-header-name h)))))))
     	 (close-input-port pz))))

 -- bigloo procedure: untar input-port [:directory (pwd)] [:file #f]
     Untars the archive whose content is provided by the input port
     INPUT-PORT.

        * If :FILE is provided, 'untar' extract the content of the file
          named :FILE and returns a string.  The file name must exactly
          matches the files of the archive files names.  If the file
          does not exist, 'untar' returns '#f'.

        * If :FILE is not provided, it _untars_ the whole content, in
          the directory denoted by :DIRECTORY, which defaults to
          '(pwd)'.  The function 'untar', returns the whole list of
          created directories and files.


File: bigloo.info,  Node: Serialization,  Next: Bit Manipulation,  Prev: Input and Output,  Up: Standard Library

5.3 Serialization
=================

 -- bigloo procedure: string->obj string #!optional extension
     This function converts a STRING which has been produced by
     'obj->string' into a Bigloo object.

     New in Bigloo 4.2a: The EXTENSION parameter is used to decode
     _extension_ sequences.  Theses sequences of characters are
     introduced by the 'X' character.  To decode an extension, the
     unserializer starts decoding the item following the 'X' as a
     regular serialized item.  Then, if the EXTENSION parameter is bound
     to a function, the unserializer calls that function and use the
     returned value as the unserialized object.  If the EXTENSION
     argument is not a function, the unserializer return the ream item.

 -- bigloo procedure: obj->string object
     This function converts into a string _any_ Bigloo OBJECT which does
     not contain a procedure.

  The implementation of the last two functions ensures that for every
Bigloo object 'obj' (containing no procedure), the expression:

     (equal? obj (string->obj (obj->string obj)))
        => #t

 -- bigloo procedure: binary-port? obj
 -- bigloo procedure: open-output-binary-file file-name
 -- bigloo procedure: append-output-binary-file file-name
 -- bigloo procedure: open-input-binary-file file-name
 -- bigloo procedure: close-binary-port binary-port
 -- bigloo procedure: flush-binary-port binary-port
 -- bigloo procedure: input-obj binary-port
 -- bigloo procedure: output-obj binary-port obj
     Bigloo allows Scheme objects to be dumped into, and restored from,
     files.  These operations are performed by the previous functions.
     The dump and the restore use the two functions 'obj->string' and
     'string->obj'.

     It is also possible to use a binary file as a flat character file.
     This can be done by the means of 'output-char', 'input-char',
     'output-string', and 'input-string' functions.

 -- bigloo procedure: input-char binary-port
 -- bigloo procedure: output-char binary-port char
 -- bigloo procedure: output-byte binary-port byte
     The function 'input-char' reads a single character from a
     BINARY-PORT.  It returns the read character or the 'end-of-file'
     object.  The function 'output-char' and 'output-byte' writes a
     character, respectively a byte, into a BINARY-PORT.

 -- bigloo procedure: input-string binary-port len
 -- bigloo procedure: output-string binary-port
     The function 'input-string' reads a string from a BINARY-PORT of
     maximum length LEN.  It returns a newly allocated string whose
     length is possibly smaller than LEN.  The function 'output-string'
     writes a string into a BINARY-PORT.

 -- bigloo procedure: input-fill-string! binary-port string
     Fills a string with characters read from BINARY-PORT with at most
     the length of STRING.  The function returns the number of filled
     characters.

 -- bigloo procedure: register-procedure-serialization! serializer
          unserializer
 -- bigloo procedure: register-custom-serialization! ident serializer
          unserializer
 -- bigloo procedure: register-process-serialization! serializer
          unserializer
 -- bigloo procedure: register-opaque-serialization! serializer
          unserializer
     There is no existing portable method to dump and restore a
     procedure.  Thus, if 'obj->string' is passed a procedure, it will
     emit an error message.  Sometime, using strict restrictions, it may
     be convenient to use an ad-hoc framework to serialize and
     unserialize procedures.  User may specify there own procedure
     serializer and unserializer.  This is the role of
     'register-procedure-serialization!'.  The argument SERIALIZER is a
     procedure of one argument, converting a procedure into a characters
     strings.  The argument UNSERIALIZER is a procedure of one argument,
     converting a characters string into a procedure.  It belongs to the
     user to provide correct serializer and unserializer.

     Here is an example of procedure serializer and unserializer that
     may be correct under some Unix platform:

          (module foo
             (extern (macro %sprintf::int (::string ::string ::procedure) "sprintf")))

          (define (string->procedure str)
             (pragma "(obj_t)(strtoul(BSTRING_TO_STRING($1), 0, 16))" str))

          (define (procedure->string proc)
             (let ((item (make-string 10)))
                (%sprintf item "#p%lx" proc)
                item))

          (register-procedure-serialization! procedure->string string->procedure)

          (let ((x 4))
             (let ((obj (cons "toto" (lambda (y) (+ x y)))))
                (let ((nobj (string->obj (obj->string obj))))
          	 (print ((cdr nobj) 5)))))

 -- bigloo procedure: register-class-serialization! class serializer
          unserializer
     Register a serializer/unserializer for a class.  Subclasses of
     CLASS inherit this serializer.

          (module class-serialization-example
             (static (class point::object (x (default 10)) (y (default 20)))))

          (register-class-serialization! point
          			       (lambda (o)
          				  (with-access::point o (x y)
          				     (cons x y)))
          			       (lambda (l)
          				  (instantiate::point
          				     (x (car l))
          				     (y (cdr l)))))

          (let ((o (instantiate::point)))
             (let ((s (obj->string (list o o))))
                (print (string-for-read s))
                (let ((l (string->obj s)))
          	 (print l)
          	 (eq? (car l) (cadr l))))) => #t

 -- bigloo procedure: get-procedure-serialization
 -- bigloo procedure: get-custom-serialization ident
 -- bigloo procedure: get-process-serialization
 -- bigloo procedure: get-opaque-serialization
 -- bigloo procedure: get-class-serialization class
     Returns the a multiple-values whose first element is the current
     procedure serializer and whose second element is the current
     procedure unserializer.  If no serializer/unserializer is defined,
     these procedures return the values '#f #f'.


File: bigloo.info,  Node: Bit Manipulation,  Next: Weak Pointers,  Prev: Serialization,  Up: Standard Library

5.4 Bit manipulation
====================

These procedures allow the manipulation of fixnums as bit-fields.
 -- bigloo procedure: bit-or i1 i2
 -- bigloo procedure: bit-orbx z1 z2
 -- bigloo procedure: bit-orelong i1 i2
 -- bigloo procedure: bit-orllong i1 i2
 -- bigloo procedure: bit-xor i1 i2
 -- bigloo procedure: bit-xorbx z1 z2
 -- bigloo procedure: bit-xorelong i1 i2
 -- bigloo procedure: bit-xorllong i1 i2
 -- bigloo procedure: bit-and i1 i2
 -- bigloo procedure: bit-andbx z1 z2
 -- bigloo procedure: bit-andelong i1 i2
 -- bigloo procedure: bit-andllong i1 i2
 -- bigloo procedure: bit-not i
 -- bigloo procedure: bit-notbx z
 -- bigloo procedure: bit-notelong i
 -- bigloo procedure: bit-notllong i
 -- bigloo procedure: bit-lsh i1 i2
 -- bigloo procedure: bit-lshbx z1 i2
 -- bigloo procedure: bit-lshelong i1 i2
 -- bigloo procedure: bit-lshllong i1 i2
 -- bigloo procedure: bit-rsh i1 i2
 -- bigloo procedure: bit-rshbx z1 i2
 -- bigloo procedure: bit-ursh i1 i2
 -- bigloo procedure: bit-rshelong i1 i2
 -- bigloo procedure: bit-rshllong i1 i2
 -- bigloo procedure: bit-urshelong i1 i2
 -- bigloo procedure: bit-urshllong i1 i2

          (bit-or 5 3)                           => 7
          (bit-orelong #e5 #e3)                  => #e7
          (bit-xor 5 3)                          => 6
          (bit-xorbx #z5 #z3)                    => #z6
          (bit-andllong #l5 #l3)                 => #l1
          (bit-not 5)                            => -6
          (bit-lsh 5 3)                          => 40
          (bit-rsh 5 1)                          => 2
          (bit-rsh #z5 1)                        => #z2


File: bigloo.info,  Node: Weak Pointers,  Next: Hash Tables,  Prev: Bit Manipulation,  Up: Standard Library

5.5 Weak Pointers
=================

Bigloo may support weak pointers.  In order to activate this support,
Bigloo must be configured with the 'finalization' enabled.  That is, the
'configure' script must be invoked with the option '--finalization=yes'.
When the finalization and weak pointers support is enabled, Bigloo
defines the 'cond-expand' properties 'bigloo-finalizer' and
'bigloo-weakptr'.  Then a program may test the support with expressions
such as:

     (cond-expand
       (bigloo-weakptr <something>)
       (else <something-else>))

  Weak pointers are pointers to objects which can be collected by the
garbage collector if they are weakly pointed to.  An object is weakly
pointed to if the only pointers to it are weak pointers.  Weakly pointed
objects can be collected by the garbage collector, and all the weak
pointers to such objects will cease to point to it and point to
'#unspecified' instead.

 -- bigloo procedure: make-weakptr data
 -- bigloo procedure: make-weakptr data ref
     Creates a weak pointer to DATA and REF.

 -- bigloo procedure: weakptr? obj
     Returns '#t' if OBJ is a weak pointer, constructed by
     'make-weakptr'.

 -- bigloo procedure: weakptr-data ptr
     Returns the DATA object pointed to by PTR.  If the object has been
     collected, it returns '#unspecified'.

 -- bigloo procedure: weakptr-data-set! ptr data
     Set a new DATA to the weak pointer.

 -- bigloo procedure: weakptr-ref ptr
     Returns the REF object pointed to by PTR.  If the object has been
     collected, it returns '#unspecified'.

 -- bigloo procedure: weakptr-ref-set! ptr ref
     Set a new REF to the weak pointer.


File: bigloo.info,  Node: Hash Tables,  Next: System Programming,  Prev: Weak Pointers,  Up: Standard Library

5.6 Hash Tables
===============

Bigloo offers hash tables with support for weak pointers.  Here are
described functions which define and use them.

 -- bigloo procedure: make-hashtable [bucket-len] [max-bucket-len]
          [eqtest] [hash] [weak-keys] [weak-data]
 -- bigloo procedure: create-hashtable [:size] [:max-bucket-len]
          [:eqtest] [:hash] [:weak] [:max-length] [:bucket-expansion]
          [:persistent #f]
     Defines an hash table for which the number of buckets is SIZE.  The
     variable MAX-BUCKET-LEN specify when the table should be resized.
     If provided, these two values have to be exact integers greater or
     equal to 1.  Normally you could ignore SIZE and MAX-BUCKET-LEN
     arguments and call 'make-hashtable' with no argument at all.  The
     argument EQTEST enables the specification of a comparison function.
     The first argument of this function is the keys contained in the
     table.  The second argument is the searched key.  By default hash
     tables rely on 'hashtable-equal?', which is defined as:

     Persistent hashtables are serializable.  Non persisent hashtables
     are not.

          (define (hashtable-equal? obj1 obj2)
             (or (eq? obj1 obj2)
                 (and (string? obj1)
                      (string? obj2)
                      (string=? obj1 obj2))))

     The argument HASH specifies an hashing function.  It defaults to
     GET-HASHNUMBER.  The arguments WEAK-KEYS, WEAK-DATA, and WEAK-BOTH
     specify respectively whether the hash table should use weak
     pointers to store the keys and/or the data.  By default a hash
     table uses strong pointers for both keys and data.  Each optional
     arguments SIZE, MAX-BUCKET-LEN, EQTEST, HASH, WEAK-KEYS, and
     WEAK-DATA can be bound to the Bigloo value '#unspecified' which
     forces its default.

     The argument MAX-LENGTH specifies a maximum length (in number of
     buckets) for this hashtable.  It defaults to '16384'.  If during
     the execution, the hashtable tries to expand itself more than
     MAX-LENGTH, an exception is raised.  This feature helps debugging
     incorrect hashtable uses because excessive expansion is generally
     the signs of an incorrect behavior.  Excessive expansions, cause
     the garbage collector to crash at some point.  This debugging
     feature can be disabled by specifying a negative max length, in
     which case, no check is performed at runtime.

     The argument BUCKET-EXPANSION controls how MAX-BUCKET-LEN is
     expanded each time the table grows.  This is a floating point
     number that is a multiplicative coefficient.  It defaults to '1.2'.

     The function 'create-hashtable' is equivalent to 'make-hashtable'
     but it uses a keyword interface.  The keyword argument 'weak' can
     either be 'none', 'data', or 'keys'.

 -- bigloo procedure: hashtable? obj
     Returns '#t' if OBJ is an hash table, constructed by
     'make-hashtable'.

 -- bigloo procedure: hashtable-weak-keys? table
     Returns '#t' if TABLE is a hash table with weakly pointed keys.

 -- bigloo procedure: hashtable-weak-data? table
     Returns '#t' if TABLE is a hash table with weakly pointed data.

 -- bigloo procedure: hashtable-size table
     Returns the number of entries contained in TABLE.  Note that for a
     weak hash table the size does not guarantee the real size, since
     keys and/or data can dissapear before the next call to the hash
     table.

 -- bigloo procedure: hashtable-contains? table key
     Returns the boolean '#t' if it exists at least one entry whose key
     is KEY in TABLE.  If not entry is found '#f' is returned.  Note
     that for a weak hash table, the fact this procedure returns '#t'
     does not guarantee that the key (or its associated data) will not
     dissapear before the next call to the hash table.

 -- bigloo procedure: hashtable-get table key
     Returns the entry whose key is KEY in TABLE.  If no entry is found,
     or if the key and/or value is weakly pointed to and has dissapeard,
     '#f' is returned.

 -- bigloo procedure: hashtable-put! table key obj
     Puts OBJ in TABLE under the key KEY.  This function returns the
     object bound in the table.  If there was an object OBJ-OLD already
     in the table with the same key as OBJ, this function returns
     OBJ-OLD; otherwise it returns OBJ.

 -- bigloo procedure: hashtable-remove! table key
     Removes the object associated to KEY from TABLE, returning '#t' if
     such object was bound in table and '#f' otherwise.

 -- bigloo procedure: hashtable-add! table key update-fun obj init-value
     If key is already in table, the new value is calculated by
     '(update-fun obj current-value)'.  Otherwise the TABLE is extended
     by an entry linking key and '(update-fun obj init-value)'.

 -- deprecated bigloo procedure: hashtable-update! table key update-fun
          init-value
     If key is already in table, the new value is calculated by
     '(update-fun current-value)'.  Otherwise the TABLE is extended by
     an entry linking key and 'init-value'.

 -- bigloo procedure: hashtable->vector table
 -- bigloo procedure: hashtable->list table
     Returns the hash table TABLE's data as a vector (respectively a
     list).  If the hash table is weak, the result will consist only of
     the data which haven't dissapeared yet and whose keys haven't
     dissapeared either.

 -- bigloo procedure: hashtable-key-list table
     Returns the list of keys used in the TABLE.  If the hash table is
     weak, the result will consist only of the keys which haven't
     dissapeared yet and whose data haven't dissapeared either.

 -- bigloo procedure: hashtable-map table fun
     Returns a list whose elements are the result of applying FUN to
     each of the keys and elements of TABLE (no order is specified).  In
     consequence, FUN must be a procedure of two arguments.  The first
     one is a key and the second one, an associated object.  If the hash
     table is weak, FUN will only be mapped on sets of key/datum which
     haven't dissapeared yet.

 -- bigloo procedure: hashtable-for-each table fun
     Applies FUN to each of the keys and elements of TABLE (no order is
     specified).  In consequence, FUN must be a procedure of two
     arguments.  The first one is a key and the second one, an
     associated object.  If the hash table is weak, FUN will only be
     called on sets of key/datum which haven't dissapeared yet.

 -- bigloo procedure: hashtable-filter! table fun
     Filter out elements from TABLE according to predicate FUN.  If the
     hash table is weak, FUN will only be called on sets of key/datum
     which haven't dissapeared yet.

 -- bigloo procedure: hashtable-clear! table
     Remove all the elements from TABLE.

  Here is an example of hash table.

     (define *table* (make-hashtable))

     (hashtable-put! *table* "toto" "tutu")
     (hashtable-put! *table* "tata" "titi")
     (hashtable-put! *table* "titi" 5)
     (hashtable-put! *table* "tutu" 'tutu)
     (hashtable-put! *table* 'foo 'foo)

     (print (hashtable-get *table* "toto"))
        -| "tutu"
     (print (hashtable-get *table* 'foo))
        -| 'foo
     (print (hashtable-get *table* 'bar))
        -| #f

     (hashtable-for-each *table* (lambda (key obj) (print (cons key obj))))
        -| ("toto" . "tutu")
           ("tata" . "titi")
           ("titi" . 5)
           ("tutu" . TUTU)
           (foo . foo)

 -- bigloo procedure: get-hashnumber obj
 -- bigloo procedure: get-hashnumber-persistent obj

     Computes a hash number of the value OBJ, which can be of any type.
     The function 'get-hashnumber-persistent' returns a hash number that
     is persistent accross program executions and execution platforms.

 -- bigloo generic: object-hashnumber object
     This generic function computes a hash number of the instance
     OBJECT.

     Example:
          (define-method (object-hashnumber pt::point)
             (with-access::point pt (x y)
                (+fx (*fx x 10) y)))

 -- bigloo procedure: string-hash string [start 0] [len (string-length
          string)]
     Compute a hash value for STRING, starting at index START, ending at
     length LEN.


File: bigloo.info,  Node: System Programming,  Next: Date,  Prev: Hash Tables,  Up: Standard Library

5.7 System programming
======================

* Menu:

* Operating System Interface::
* Files::
* Process::
* Socket::
* SSL::


File: bigloo.info,  Node: Operating System Interface,  Next: Files,  Up: System Programming

5.7.1 Operating System interface
--------------------------------

 -- bigloo procedure: bigloo-config
 -- bigloo procedure: bigloo-config key
     The function 'bigloo-config' returns an alist representing the
     configuration of the running Bigloo system.  When used with one
     parameter, the function 'bigloo-config' returns the value
     associated with the key.

     Examples:

          (bigloo-config) => ((release-number . 3.4b) ... (endianess . little-endian))
          (bigloo-config 'endianess) => little-endian
          (bigloo-config 'int-size) => 61

 -- bigloo procedure: register-exit-function! proc
 -- bigloo procedure: unregister-exit-function! proc
     Register PROC as an exit functions.  PROC is a procedure accepting
     of one argument.  This argument is the numerical value which is the
     status of the exit call.  The registered functions are called when
     the execution ends.

 -- bigloo procedure: exit int
     Apply all the registered exit functions then stops an execution,
     returning the integer INT.

 -- bigloo procedure: signal n proc
     Provides a signal handler for the operating system dependent signal
     N.  PROC is a procedure of one argument.

 -- bigloo procedure: get-signal-handler n
     Returns the current handler associated with signal N or '#f' if no
     handler is installed.

 -- bigloo procedure: system . strings
     Append all the arguments STRINGS and invoke the native host
     'system' command on that new string which returns an integer.

 -- bigloo procedure: system->string . strings
     Append all the arguments STRINGS and invoke the native host
     'system' command on that new string.  If the command completes,
     'system->string' returns a string made of the output of the
     command.

 -- bigloo procedure: getenv [name]
     Returns the string value of the Unix shell's NAME variable.  If no
     such variable is bound, 'getenv' returns '#f'.  If NAME is not
     provided, 'getenv' returns an alist composed of all the environment
     variables.

 -- bigloo procedure: putenv string val
     Adds or modifies the global environment variable STRING so that it
     is bound to VAL after the call.  This facility is not supported by
     all back-end.  In particular, the JVM back-end does not support it.

 -- bigloo procedure: date
     Returns the current date in a 'string'.  See also *note Date::.

 -- bigloo procedure: sleep micros
     Sleeps for a delay during at least MICROS microseconds.

 -- bigloo procedure: command-line
     Returns a list of strings which are the Unix command line
     arguments.

 -- bigloo procedure: executable-name
     Returns the name of the running executable.

 -- bigloo procedure: os-class
     Gives the OS class (e.g.  'unix').

 -- bigloo procedure: os-name
     Gives the OS name (e.g.  'Linux').

 -- bigloo procedure: os-arch
     Gives the host architecture (e.g.  'i386').

 -- bigloo procedure: os-version
     Gives the operating system version (e.g.  'RedHat 2.0.27').

 -- bigloo procedure: os-tmp
     Gives the regular temporary directory (e.g.  '/tmp').

 -- bigloo procedure: os-charset
     Gives the charset used for encoding names of the file system (e.g.
     'UTF-8').

 -- bigloo procedure: file-separator
     Gives the operating system file separator (e.g.  '#\/').

 -- bigloo procedure: path-separator
     Gives the operating system file path separator (e.g.'#\:').

  For additional functions (such as 'directory->list') see *note Input
and Output::.

 -- bigloo procedure: unix-path->list
     Converts a Unix path to a Bigloo list of strings.

          (unix-path->list ".")           => (".")
          (unix-path->list ".:/usr/bin")  => ("." "/usr/bin")

 -- bigloo procedure: hostname
     Returns the fully qualified name of the current host.

 -- bigloo procedure: time thunk
     Evaluates the THUNK and returns four values: the result of calling
     THUNK, the actual execution time, the system time, and the user
     time in millisecond.

          (multiple-value-bind (res rtime stime utime)
            (time (lambda () (fib 35)))
            (print "real: " rtime " sys: " stime " user: " utime))

 -- bigloo procedure: getuid
 -- bigloo procedure: getgid
 -- bigloo procedure: setuid uid
 -- bigloo procedure: setgid uid
     The procedure 'getuid' (resp.  'getgid') returns the UID (resp.
     GID) of the user the current process is executed on behalf of.

     The procedure 'setuid' (resp.  'setgid') set the UID (resp.  GID)
     of the current process.  In case of failure, this procedure raises
     an error.

 -- bigloo procedure: getpid
     Get the current process identifier.

 -- bigloo procedure: getppid
     Get the parent process identifier.

 -- bigloo procedure: getgroups
     Maps the Posix 'getgroups' function, which returns the
     supplementary group IDs of the calling process.  The result is a
     vector of IDs.  On error, an IO exception is raised.

 -- bigloo procedure: getpwnam name
 -- bigloo procedure: getpwuid uid
     These two procedures returns information about a user.  The
     procedure 'getpwname' accepts a string denoting the user name as
     argument.  The procedure 'getpwuid' accepts an UID as returned by
     the procedure 'getuid'.

     If the user is found, these two procedures returns a list of seven
     elements:

        * the user name,
        * his encrypted password,
        * his uid,
        * his group id,
        * his real name,
        * his home directory,
        * his preferred shell.

     When no user is found, these procedures returns '#f'.

 -- bigloo procedure: openlog name option facility
 -- bigloo procedure: syslog level . obj
 -- bigloo procedure: closelog
 -- bigloo procedure: syslog-option
 -- bigloo procedure: syslog-level
 -- bigloo procedure: syslog-facility

     Wrapper to Unix syslog facilities.  See the 'syslog' man page for
     detail.  Example.

          (syslog (syslog-level 'LOG_INFO) "this is a log message")
          (closelog)


File: bigloo.info,  Node: Files,  Next: Process,  Prev: Operating System Interface,  Up: System Programming

5.7.2 Files
-----------

See *note Input and Output:: for file and directory handling.  This
section only deals with _name_ handling.  Four procedures exist to
manipulate Unix filenames.

 -- bigloo procedure: basename string
     Returns a copy of STRING where the longest prefix ending in '/' is
     deleted if any existed.

 -- bigloo procedure: prefix string
     Returns a copy of STRING where the suffix starting by the char
     '#\.' is deleted.  If no prefix is found, the result of 'prefix' is
     a copy of 'string'.  For instance:

          (prefix "foo.scm")
             => "foo"
          (prefix "./foo.scm")
             => "./foo"
          (prefix "foo.tar.gz")
             => "foo.tar"

 -- bigloo procedure: suffix string
     Returns a new string which is the suffix of STRING.  If no suffix
     is found, this function returns an empty string.  For instance,

          (suffix "foo.scm")
             => "scm"
          (suffix "./foo.scm")
             => "scm"
          (suffix "foo.tar.gz")
             => "gz"

 -- bigloo procedure: dirname string
     Returns a new string which is the directory component of STRING.
     For instance:

          (dirname "abc/def/ghi")
             => "abc/def"
          (dirname "abc")
             =>  "."
          (dirname "abc/")
             => "abc"
          (dirname "/abc")
             => "/"

 -- bigloo procedure: pwd
     Returns the current working directory.

 -- bigloo procedure: chdir dir-name
     Changes the current directory to DIR-NAME.  On success, 'chdir'
     returns '#t'.  On failure it returns '#f'.

 -- bigloo procedure: make-file-name dir-name name
     Make an absolute file-name from a directory name DIR-NAME and a
     relative name NAME.

 -- bigloo procedure: make-file-path dir-name name . names
     Make an absolute file-name from a directory name DIR-NAME and a
     relative name NAMEs.

 -- bigloo procedure: file-name->list name
     Explodes a file name into a list.

             => '("" "etc" "passwd")
          (file-name->list "etc/passwd")
             => '("etc" "passwd")

 -- bigloo procedure: file-name-canonicalize name
 -- bigloo procedure: file-name-canonicalize! name
 -- bigloo procedure: file-name-unix-canonicalize name
 -- bigloo procedure: file-name-unix-canonicalize! name
     Canonicalizes a file name.  If the file name is malformed this
     function raises an '&io-malformed-url-error' exception.

     The function 'file-name-canonicalize!' may returns its argument if
     no changes in the string is needed.  Otherwise, as
     'file-name-canonicalize' is returns a new string.

     In addition to handling '..' directory name, the function
     'file-name-unix-canonicalize' also handles the '~' character.

             => "/etc/passwd"
          (file-name-canonicalize "/etc/../tmp/passwd")
             => "/tmp/passwd"
          (file-name-canonicalize "~/passwd")
             => "~/passwd"
          (file-name-unix-canonicalize "~/passwd")
             => "/home/a-user/passwd"
          (file-name-unix-canonicalize "~foo/passwd")
             => "/home/foo/passwd"

 -- bigloo procedure: relative-file-name name base
     Builds a file name relative to BASE.

             => "passwd"

 -- bigloo procedure: find-file/path name path
     Search, in sequence, in the directory list PATH for the file NAME.
     If NAME is an absolute name, then PATH is not used to find the
     file.  If NAME is a relative name, the function 'make-file-name' is
     used to build absolute name from NAME and the directories in PATH.
     The current path is not included automatically in the list of PATH.
     In consequence, to check the current directory one may add '"."' to
     the PATH list.  On success, the absolute file name is returned.  On
     failure, '#f' is returned.  Example:

             => "/etc/passwd"
          (find-file/path "passwd" '("/toto" "/etc"))
             => "/etc/passwd"
          (find-file/path "pass-wd" '("." "/etc"))
             => #f

 -- bigloo procedure: make-static-library-name name
     Make a static library name from NAME by adding the static library
     regular suffix.

 -- bigloo procedure: make-shared-library-name name
     Make a shared library name from NAME by adding the shared library
     regular suffix.

 -- bigloo procedure: file-exists? string
     This procedure returns '#t' if the file (respectively directory,
     and link) STRING exists.  Otherwise it returns '#f'.

 -- bigloo procedure: file-gzip? string
     This procedure returns '#t' if and only if the file STRING exists
     and can be unzip by Bigloo.  Otherwise it returns '#f'.

 -- bigloo procedure: delete-file string
     Deletes the file named STRING.  The result of this procedure is
     '#t' is the operation succeeded.  The result is '#f' otherwise.

 -- bigloo procedure: rename-file string1 string2
     Renames the file STRING1 as STRING2.  The two files have to be
     located on the same file system.  If the renaming succeeds, the
     result is '#t', otherwise it is '#f'.

 -- bigloo procedure: truncate-file path size
     Truncates shall cause the regular file named by path to have a size
     which shall be equal to length bytes.

     Returns '#t' on success.  Returns '#f' otherwise.

 -- bigloo procedure: copy-file string1 string2
     Copies the file STRING1 into STRING2.  If the copy succeeds, the
     result is '#t', otherwise it is '#f'.

 -- bigloo procedure: make-symlink target linkpath
     Creates a symbolic link named LINKPATH which contains the string
     TARGET.

 -- bigloo procedure: directory? string
     This procedure returns '#t' if the file STRING exists and is a
     directory.  Otherwise it returns '#f'.

 -- bigloo procedure: make-directory string
     Creates a new directory named STRING.  It returns '#t' if the
     directory was created.  It returns '#f' otherwise.

 -- bigloo procedure: make-directories string
     Creates a new directory named STRING, including any necessary but
     nonexistent parent directories.  It returns '#t' if the directory
     was created.  It returns '#f' otherwise.  Note that if this
     operation fails it may have succeeded in creating some of the
     necessary parent directories.

 -- bigloo procedure: delete-directory string
     Deletes the directory named STRING.  The directory must be empty in
     order to be deleted.  The result of this procedure is unspecified.

 -- bigloo procedure: directory->list string
 -- bigloo procedure: directory->path-list string
     If file STRING exists and is a directory, the function
     'directory->list' returns the list of files in STRING.  The
     function 'directory->path-list' returns a list of files whose
     dirname is STRING.

 -- bigloo procedure: file-modification-time string
 -- bigloo procedure: file-change-time string
 -- bigloo procedure: file-access-time string
 -- bigloo procedure: file-times-set! string atime mtime
     The date (in second) of the last modification (respec.  access) for
     file STRING.  The number of seconds is represented by a value that
     may be converted into a date by the means of 'seconds->date' (see
     *note Date::).

 -- bigloo procedure: file-size string
     Returns the size (in bytes) for file STRING.  The return type is
     'long'.  If an full-sized integer is needed, one may write:

          (let ((sz::llong (file-size <PATH>)))
           ...)

          On error, -1 is returned.

 -- bigloo procedure: file-uid string
 -- bigloo procedure: file-gid string
     The functions return the user id (an integer) and group id (an
     integer) for file STRING.  On error, '-1' is returned.

 -- bigloo procedure: file-mode string
     Returns the file access mode (an integer).  On error '-1' is
     returned.

 -- bigloo procedure: file-type string
     Returns the file type (a symbol).  The possible returned values
     are:

        * 'regular'
        * 'directory'
        * 'link'
        * 'block'
        * 'fifo'
        * 'character'
        * 'socket'
        * 'resource'
        * 'unknown'
        * 'does-not-exist'

 -- bigloo procedure: chmod string [option]
     Change the access mode of the file named STRING.  The OPTION must
     be either a list of the following symbols 'read', 'write' and
     'execute' or an integer.  If the operation succeeds, 'chmod'
     returns '#t'.  It returns '#f' otherwise.  The argument OPTION can
     also be an integer that represents the native file permission.
     Example:

          (chmod (make-file-name (getenv "HOME") ".bigloorc") 'read 'write)
          (chmod (make-file-name (getenv "HOME") ".bigloorc") #o777)


File: bigloo.info,  Node: Process,  Next: Socket,  Prev: Files,  Up: System Programming

5.7.3 Process support
---------------------

Bigloo provides access to Unix-like processes as first class objects.
The implementation and this documentation are to a great extent copies
of the STk [Gallesio95] process support.  Basically, a process contains
four informations: the standard Unix process identification (aka PID)
and the three standard files of the process.

 -- bigloo procedure: run-process command arg...

     'run-process' creates a new process and run the executable
     specified in COMMAND.  The ARG correspond to the command line
     arguments.  When is process completes its execution, non pipe
     associated ports are automatically closed.  Pipe associated ports
     have to be explicitly closed by the program.  The following values
     of P have a special meaning:

        * 'input:' permits to redirect the standard input file of the
          process.  Redirection can come from a file or from a pipe.  To
          redirect the standard input from a file, the name of this file
          must be specified after 'input:'.  Use the special keyword
          'pipe:' to redirect the standard input from a pipe.

        * 'output:' permits to redirect the standard output file of the
          process.  Redirection can go to a file or to a pipe.  To
          redirect the standard output to a file, the name of this file
          must be specified after 'output:'.  Use the special keyword
          'pipe:' to redirect the standard output to a pipe.

        * 'error:' permits to redirect the standard error file of the
          process.  Redirection can go to a file or to a pipe.  To
          redirect the standard error to a file, the name of this file
          must be specified after 'error:'.  Use the special keyword
          'pipe:' to redirect the standard error to a pipe.

        * 'wait:' must be followed by a boolean value.  This value
          specifies if the process must be ran asynchronously or not.
          By default, the process is run asynchronously (i.e.  'wait:'
          if '#f').

        * 'host:' must be followed by a string.  This string represents
          the name of the machine on which the COMMAND must be executed.
          This option uses the external command 'rsh'.  The shell
          variable 'PATH' must be correctly set for accessing it without
          specifying its absolute path.

        * 'fork:' must be followed by a boolean value.  This value
          specifies if the process must substitute the current
          execution.  That is, if the value is '#t' a new process is
          spawned otherwise, the current execution is stopped and
          replaced by the execution of 'command'.  It defaults to '#t'.

        * 'env:' must be followed by a string of the form 'VAR=VAL'.
          This will bound an environment variable in the spawned
          process.  A 'run-process' command may contain several 'env:'
          arguments.  The current variables of the current process are
          also passed to the new process.

     The following example launches a process which execute the Unix
     command 'ls' with the arguments '-l' and '/bin'.  The lines printed
     by this command are stored in the file 'tmp/X'.

          (run-process "ls" "-l" "/bin" output: "/tmp/X")

     The same example with a pipe for output:

          (let* ((proc (run-process "ls" "-l" "/bin" output: pipe:))
                 (port (process-output-port proc)))
             (let loop ((line (read-line port)))
                (if (eof-object? line)
                    (close-input-port port)
                    (begin
                       (print line)
                       (loop (read-line port))))))

     One should note that the same program can be written with explicit
     process handling but making use of the '|' notation for
     'open-input-file'.

          (let ((port (open-input-file "| ls -l /bin")))
             (let loop ((line (read-line port)))
                (if (eof-object? line)
                    (close-input-port port)
                    (begin
                       (print line)
                       (loop (read-line port))))))

     Both input and output ports can be piped:

          (let* ((proc (run-process "/usr/bin/dc" output: pipe: input: pipe:))
                 (inport (process-input-port proc))
                 (port (process-output-port proc)))
             (fprint inport "16 o")
             (fprint inport "16 i")
             (fprint inport "10")
             (fprint inport "10")
             (fprint inport "+ p")
             (flush-output-port inport)
             (let loop ((line (read-line port)))
                (if (eof-object? line)
          	  (close-input-port port)
          	  (begin
          	     (print line)
          	     (loop (read-line port))))))   -| 20

     _Note:_ The call to 'flush-output-port' is mandatory in order to
     get the 'dc' process to get its input characters.

     _Note:_ Thanks to Todd Dukes for the example and the suggestion of
     including it this documentation.

 -- bigloo procedure: process? obj
     Returns '#t' if OBJ is a process, otherwise returns '#f'.

 -- bigloo procedure: process-alive? process
     Returns '#t' if PROCESS is currently running, otherwise returns
     '#f'.

 -- bigloo procedure: close-process-ports command arg...
     Close the three ports associated with a process.  In general the
     ports should not be closed before the process is terminated.

 -- bigloo procedure: process-pid process
     Returns an integer value which represents the Unix identification
     (PID) of the PROCESS.

 -- bigloo procedure: process-input-port process
 -- bigloo procedure: process-output-port process
 -- bigloo procedure: process-error-port process
     Return the file port associated to the standard input, output and
     error of PROCESS otherwise returns '#f'.  Note that the returned
     port is opened for reading when calling 'process-output-port' or
     'process-error-port'.  It is opened for writing when calling
     'process-input-port'.

 -- bigloo procedure: process-wait process
     This function stops the current process until PROCESS completion.
     This function returns '#f' when PROCESS is already terminated.  It
     returns '#t' otherwise.

 -- bigloo procedure: process-exit-status process
     This function returns the exit status of PROCESS if it is has
     finished its execution.  It returns '#f' otherwise.

 -- bigloo procedure: process-send-signal process s
     Sends the signal whose integer value is S to PROCESS.  Value of S
     is system dependent.  The result of 'process-send-signal' is
     undefined.

 -- bigloo procedure: process-kill process
     This function brutally kills PROCESS.  The result of 'process-kill'
     is undefined.

 -- bigloo procedure: process-stop process
 -- bigloo procedure: process-continue process
     Those procedures are only available on systems that support job
     control.  The function 'process-stop' stops the execution of
     PROCESS and 'process-continue' resumes its execution.

 -- bigloo procedure: process-list
     This function returns the list of processes which are currently
     running (i.e.  alive).


File: bigloo.info,  Node: Socket,  Next: SSL,  Prev: Process,  Up: System Programming

5.7.4 Socket support
--------------------

Bigloo defines sockets, on systems that support them, as first class
objects.  Sockets permits processes to communicate even if they are on
different machines.  Sockets are useful for creating client-server
applications.  The implementation and this documentation are, to a great
extent copies of the STk [Gallesio95] socket support.

  Bigloo supports both "stream-oriented" sockets and "datagram" sockets
(*note socket communication styles: (libc)Communication Styles.).
Stream-oriented sockets are created and manipulated with the following
procedures.

 -- bigloo procedure: make-client-socket hostname port-number #!key
          (timeout 0) (inbuf #t) (outbuf #t) (domain 'inet)

     'make-client-socket' returns a new socket object.  This socket
     establishes a link between the running application listening on
     port PORT-NUMBER of HOSTNAME.  If keyword arguments INBUF and
     OUTBUF describe the buffer to be used.  Each can either be:

        * A positive fixnum, this gives the size of the buffer.
        * The boolean '#t', a buffer is allocated by the Bigloo runtime
          system with a default size.
        * The boolean '#f', the socket is unbufferized.
        * A string, it is used as buffer.

     Unbuffered sockets are useful for socket clients connected to
     servers that do not emit #\Newline character after emissions.  If
     the optional argument TIMEOUT is missing or is '0', the execution
     blocks until the connection is established.  If the TIMEOUT is
     provided, the execution unblocks after TIMEOUT microseconds unless
     the connection is established.

     The DOMAIN argument specifies the protocol used by the socket.  The
     supported domains are:

        * 'inet': IPv4 Internet protocols.
        * 'unix': Unix sockets for local inter-process communications.
        * 'local': Same as 'unix'.

     If the connection cannot be established, an '&io-error' is raised
     (see *note Errors Assertions and Traces::).

     When a socket is used in unbufferized mode the characters available
     on the input port _must_ be read exclusively with 'read-char' or
     'read-line'.  It is forbidden to use 'read' or any regular grammar.
     This limitation is imposed by Rgc (see *note Regular Parsing::)
     that intrinsicly associates buffers with regular grammars.  If the
     current Rgc implementation is improved on the coming version this
     restriction will be eliminated.

     Example:
          ;; open a client socket on port 80:
          (make-client-socket "www.inria.fr" 80)
          ;; open an unbufferized connection
          (make-client-socket "www.inria.fr" 80 :inbuf #f :outbuf #f)

 -- bigloo procedure: socket? obj
 -- bigloo procedure: socket-server? obj
 -- bigloo procedure: socket-client? obj
     Returns '#t' if OBJ is a socket, a socket server a socket client.
     Otherwise returns '#f'.  Socket servers and socket clients are
     sockets.

 -- bigloo procedure: socket-hostname socket
     Returns a string which contains the name of the distant host
     attached to SOCKET.  If SOCKET has been created with
     'make-client-socket' this procedure returns the official name of
     the distant machine used for connection.  If SOCKET has been
     created with 'make-server-socket', this function returns the
     official name of the client connected to the socket.  If no client
     has used yet the socket, this function returns '#f'.

 -- bigloo procedure: socket-host-address socket
     Returns a string which contains the IP number of the distant host
     attached to SOCKET.  If SOCKET has been created with
     'make-client-socket' this procedure returns the IP number of the
     distant machine used for connection.  If SOCKET has been created
     with 'make-server-socket', this function returns the address of the
     client connected to the socket.  If no client has used yet the
     socket, this function returns '#f'.

 -- bigloo procedure: socket-local-address socket
     Returns a string which contains the IP number of the local host
     attached to SOCKET.

 -- bigloo procedure: socket-port-number socket
     Returns the integer number of the port used for SOCKET.

 -- bigloo procedure: socket-input socket
 -- bigloo procedure: socket-output socket

     Returns the file port associated for reading or writing with the
     program connected with SOCKET.  If no connection has already been
     established, these functions return '#f'.

     The following example shows how to make a client socket.  Here we
     create a socket on port 13 of the machine "'kaolin.unice.fr'"(1)
     (*note Socket-Footnote-1::):
          (let ((s (make-client-socket "kaolin.unice.fr" 13)))
            (print "Time is: " (read-line (socket-input s)))
            (socket-shutdown  s))

 -- bigloo procedure: make-server-socket #!optional (port 0) #!key (name
          #f) (backlog 5)
     'make-server-socket' returns a new socket object.  The socket will
     be listening on the network interface NAME, either on the specified
     PORT, or on a port chosen by the system (usually the first port
     available on the network interface).  The NAME can be an IP number
     as a string, or a host name, whose first IP address will be used
     (as returned by the name server lookup).

     The BACKLOG argument specifies the size of the wait-queue used for
     accepting connections.

 -- bigloo procedure: socket-accept socket #!key (errp #t) (inbuf #t)
          (outbuf #t)
     'socket-accept' waits for a client connection on the given SOCKET.
     It returns a 'client-socket'.  If no client is already waiting for
     a connection, this procedure blocks its caller; otherwise, the
     first connection request on the queue of pending connections is
     connected to SOCKET.  This procedure must be called on a server
     socket created with 'make-server-socket'.

     The arguments INBUF and OUTBUF are similar to the ones used by
     'make-client-socket'.  That is, each can either be:

        * A positive fixnum, this gives the size of the buffer.
        * The boolean '#t', a buffer is allocated.
        * The boolean '#f', the socket is unbufferized.
        * A string, it is used as buffer.

     The keyword argument ERRP is a boolean.  The value '#t' means that
     if an error is raised it is signaled.  Otherwise, it is omitted.

     _Note:_ When a socket is used in unbufferized mode the characters
     available on the input port _must_ be read exclusively with
     'read-char' or 'read-line'.  It is forbidden to use 'read' or any
     regular grammar.  This limitation is imposed by Rgc (see *note
     Regular Parsing::) that intrinsicly associate buffers with regular
     grammars.  If the current Rgc implementation is improved on the
     coming version this restriction will be suppressed.

     The following exemple is a simple server which waits for a
     connection on the port 1234(2) (*note Socket-Footnote-2::).  Once
     the connection with the distant program is established, we read a
     line on the input port associated to the socket and we write the
     length of this line on its output port.
          (let* ((s (make-server-socket 1234))
                 (s2 (socket-accept s)))
            (let ((l (read-line (socket-input s2))))
              (fprint (socket-output s2) "Length is: " (string-length l))
              (flush-output-port (socket-output s2)))
            (socket-close s2)
            (socket-shutdown s))

 -- bigloo procedure: socket-close socket
     The function 'socket-close' closes the connection established with
     a 'socket-client'.

 -- bigloo procedure: socket-shutdown socket #!optional (how #t)
     'Socket-shutdown' shutdowns the connection associated to SOCKET.

     CLOSE is either a boolean or one of the symbols 'RDWR', 'RD', or
     'WR'.  The meaning of the optional how (which defaults to '#t') is
     as follows:

        * '#t', the socket is shutdown for reading and writing _and_ the
          socket is closed.
        * '#f', the socket is shutdown for reading and writing.
        * 'RDWR', the socket is shutdown for reading and writing.
        * 'RD', the socket is shutdown for reading.
        * 'WD', the socket is shutdown for writing.

     The function 'socket-shutdown' returns an integer which is '0' is
     the operation has succeeded and a positive integer otherwise.

 -- bigloo procedure: socket-down? socket
     Returns '#t' if SOCKET has been previously closed with
     'socket-shutdown'.  It returns '#f' otherwise.

  Here is another example of making use of stream sockets:

     (define s1 (make-server-socket))
     (define s2 #unspecified)

     (dynamic-wind
        ;; Init: Launch an xterm with telnet running
        ;; on the s listening port and connect
        (lambda ()
           (run-process "/usr/X11R6/bin/xterm" "-display" ":0" "-e" "telnet" "localhost"
     		   (number->string (socket-port-number s1)))
           (set! s2 (socket-accept s1))
           (display #"\nWelcome on the socket REPL.\n\n> " (socket-output s2))
           (flush-output-port (socket-output s2)))

        ;; Action: A toplevel like loop
        (lambda ()
           (let loop ()
     	 (let ((obj (eval (read (socket-input s2)))))
     	    (fprint (socket-output s2) "; Result: " obj)
     	    (display "> " (socket-output s2))
     	    (flush-output-port (socket-output s2))
     	    (loop))))

        ;; Termination: We go here when
        ;;     -a: an error occurs
        ;;     -b: connection is closed
        (lambda ()
           (print #"Shutdown ......\n")
           (socket-close s2)
           (socket-shutdown s1)))

  Here is a second example that uses sockets.  It implements a
client-server architecture and it uses unbufferized (see
'socket-accept') input ports.

  First, here is the code of the client:

     (module client)

     (let* ((s (make-client-socket "localhost" 8080 :outbuf #f))
            (p (socket-output s)))
        (display "string" p)
        (newline p)
        (display "abc" p)
        (flush-output-port p)
        (let loop ()
           (loop)))

  Then, here is the code of the server:

     (module server)

     (let* ((s (make-server-socket 8080))
            (s2 (socket-accept s :inbuf #f)))
        (let ((pin (socket-input s2)))
           (let loop ()
              (display (read-char pin))
              (flush-output-port (current-output-port))
              (loop))))

  At, to conclude here the source code for a server waiting for multiple
consecutive connections:

     (define (main argv)
        (let ((n (if (pair? (cdr argv))
                     (string->integer (cadr argv))
                     10))
     	 (s (make-server-socket)))
           (print "s: " s)
           (let loop ((i 0))
              (if (<fx i n)
                  (let ((s2 (socket-accept s)))
     		(print "i: " i " " s2)
     		(print (read-line (socket-input s2)))
     		(socket-close s2)
                     (loop (+fx i 1)))
     	     (socket-shutdown s)))))

  Bigloo also provides primitives dealing with "datagram" sockets, for
use with transports such as UDP. These are shown below:

 -- bigloo procedure: make-datagram-server-socket PORT
     Return a datagram server socket bound to the loopback address on
     PORT, and whose address family and protocol family are those
     normally used for services on PORT.

 -- bigloo procedure: make-datagram-unbound-socket [(domain 'inet)]
     Return an unbound datagram socket.  It may then be used in
     conjunction with 'datagram-socket-send' and
     'datagram-socket-receive', for instance send to and receive from a
     UDP multicast address.

 -- bigloo procedure: datagram-socket-receive sock size
     Receive up to SIZE bytes from datagram socket SOCK, and return them
     as a string.

 -- bigloo procedure: datagram-socket-send sock message host port
     Send string MESSAGE over datagram socket SOCK to HOST and PORT.
     HOST must be a string denoting an IPv4 or IPv6 address.  On
     success, return the number of bytes actually sent.

 -- bigloo procedure: host hostname
 -- bigloo procedure: hostinfo hostname

     Returns the IP number of HOSTNAME.  When HOSTNAME is not found, the
     'io-unknown-host-error' exception is raided (see *note Errors
     Assertions and Traces::).

     The function 'hostinfo' possibly returns more information about the
     host.  It returns an association list made out the information
     about the host.  This list might contain a 'name' entry, an
     'addresses' entry, and a 'aliases' entry.

     Some back-ends (e.g., the C back-end) implements DNS caching.  This
     may dramatically improve the performance of intensive networking
     applications.  DNS caching can be control by the means of two
     parameters: 'bigloo-dns-enable-cache' and
     'bigloo-dns-cache-validity-timeout' (see *note Parameters::).

 -- bigloo procedure: get-interfaces
     Returns the list of configured interfaces, their associated IP
     addresses, their protocol, and, if supported by the system, the
     hardware address (the mac address).

 -- bigloo procedure: get-protocols
     Reads all the entries from the protocols database and returns a
     list of protocol entries.  Each entries consists in a list of three
     elements:

        * a string denoting the protocol name,
        * an integer denoting the protocol number,
        * a list of strings denoting the protocol aliases.

 -- bigloo procedure: get-protocol number-or-name
     Returns the protocol entry found in the protocols database.  The
     argument NUMBER-OF-NAME is either an integer or a string.

 -- bigloo procedure: socket-option socket option-name
 -- bigloo procedure: socket-option-set! socket option-name val
     These two functions _get_ and _set_ socket option.  The argument
     OPTION-NAME must be a keyword.  If the OPTION-NAME is not supported
     by the Bigloo runtime system, the function 'socket-option' returns
     the value '#unspecified' otherwise, it returns the option value.
     If the OPTION-NAME is not supported, the function
     'socket-option-set!' returns 'false'.  Otherwise it returns a non
     false value.

     Here is a list of possibly supported option-name values:

        * ':SO_KEEPALIVE'
        * ':SO_OOBINLINE'
        * ':SO_RCVBUF'
        * ':SO_SNDBUF'
        * ':SO_REUSEADDR'
        * ':SO_TIMEOUT'
        * ':SO_SNDTIMEO'
        * ':SO_RCVTIMEO'
        * ':TCP_CORK'
        * ':TCP_QUICKACK'
        * ':TCP_NODELAY'

     The ':SO_KEEPALIVE' option can be use to implement automatic
     notification of client disconnection.  It requires system tuning
     for enabling TCP keeplive support.  On Linux additional information
     may be found on the "TCP Keepalive HOWTO" (see
     <http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/>).


File: bigloo.info,  Node: Socket-Footnotes,  Up: Socket

   (1) Port 13 is generally used for testing: making a connection to it
permits to know the distant system's idea of the time of day.

   (2) Under Unix, you can simply connect to listening socket with the
'telnet' command.  With the given example, this can be achived by typing
the following command in a window shell: '$ telnet localhost 1234'


File: bigloo.info,  Node: SSL,  Prev: Socket,  Up: System Programming

5.7.5 SSL
---------

* Menu:

* SSL Sockets::
* Certificates::
* Private Keys::

Bigloo allows access to SSL sockets, certificates and private keys, in
order to build secure encrypted and/or signed communications.

 -- SSL library procedure: ssl-version
     Returns a string representing the SSL library version number.


File: bigloo.info,  Node: SSL Sockets,  Next: Certificates,  Up: SSL

5.7.5.1 SSL Sockets
...................

Bigloo defines SSL sockets, on systems that support them, as first class
objects.  SSL Sockets permits processes to communicate even if they are
on different machines securely via encrypted connections.  SSL Sockets
are useful for creating secure client-server applications.

 -- SSL library procedure: ssl-socket? obj
     Returns '#t' if an only if obj is a SSL socket (either client or
     server).  Returns '#f' otherwise.

 -- SSL library procedure: make-ssl-client-socket hostname port-number
          #!key (buffer #t) (timeout 0) (protocol 'sslv23) (cert #f)
          (pkey #f) (CAs '()) (accepted-certs #f)

     'make-ssl-client-socket' returns a new client socket object.  This
     object satisfies the 'socket?' predicate (see *note Socket::) can
     be used in any context where a socket created by
     'make-client-socket' can be used.

     A SSL client socket establishes a link between the running
     application (client) and a remote application (server) listening on
     port PORT-NUMBER of HOSTNAME.  If optional argument BUFSIZ is
     lesser or equal to '1' then the input port associated with the
     socket is unbuffered.  This is useful for socket clients connected
     to servers that do not emit #\Newline character after emissions.
     The optional argument BUFFER can either be:

        * A positive fixnum, this gives the size of the buffer.
        * The boolean '#t', a buffer is allocated.
        * The boolean '#f', the socket is unbufferized.
        * A string, it is used as buffer.

     If the optional argument TIMEOUT is '0', the execution blocks until
     the connection is established.  If the TIMEOUT is provided, the
     execution unblocks after TIMEOUT microseconds unless the connection
     is established.  If the PROTOCOL option argument is given, it
     specifies the encryption protocol.  Accepted values are ''sslv2',
     ''sslv3', ''sslv23' (alias ''ssl'), ''tlsv1' (alias ''tls'),
     ''tlsv1_1', ''tlsv1_2', ''tlsv1_3', or ''dtlsv1' (alias ''dtls').
     The default value is ''sslv23'.

     The SSL socket will sign the connection using the optional
     arguments CERT (for the certificate) and PKEY (for the private
     key).  The certificate CERT must be of type 'certificate', and the
     private key PKEY must be of type 'private-key'.  If any of those
     two arguments is given, they must both be given.  If those optional
     arguments are missing the connection will be encrypted but not
     signed from the client side.

     The CAS optional argument specifies the list of certificates to
     trust as CA (Certificate Authority) for the connection.  It must be
     a list of values of type 'certificate'.  If the list is empty, the
     default list of trusted CA is used (set by the system).  Note that
     giving a list of trusted certificates turns on the peer (server)
     certificate validation: an '&io-error' will be raised if the peer
     (server) certificate is not signed directly or indirectly by one of
     the certificates in CAS.

     The ACCEPTED-CERTS optional argument gives a list of certificate
     objects (of type 'certificate') which are accepted as peer (server)
     certificate.  If ACCEPTED-CERTS is '#f' then every peer (server)
     certificate is accepted (aside from eventual certificate
     validation).  If ACCEPTED-CERTS is a list, the peer (server)
     certificate must match one of the given certificates.  Otherwise,
     an '&io-error' will be raised.

     If the connection cannot be established, an '&io-error' is raised
     (see *note Errors Assertions and Traces::).

     When a socket is used in unbufferized mode the characters available
     on the input port _must_ be read exclusively with 'read-char' or
     'read-line'.  It is forbidden to use 'read' or any regular grammar.
     This limitation is imposed by Rgc (see *note Regular Parsing::)
     that intrinsicly associates buffers with regular grammars.  If the
     current Rgc implementation is improved on the coming version this
     restriction will be eliminated.

     The function 'make-ssl-client-socket' is defined in the SSL
     library.  A module that needs this facility must then use a
     'library' clause (see *note Modules::).  The SSL library can also
     be loaded from the interpreter using the 'library-load' function
     (see *note Bigloo Libraries::).

          (module imap
             (library ssl)
             (main main))

          (let* ((s (make-ssl-client-socket "localhost" 993))
                 (p (socket-output s)))
             (display "string" p)
             (newline p)
             (display "abc" p)
             (flush-output-port p)
             (let loop ()
                (loop)))

 -- SSL library procedure: client-socket-use-ssl! socket #!key (protocol
          'sslv23) (cert #f) (pkey #f) (CAs '()) (accepted-certs #f)
     Returns an SSL socket built from a socket obtained by
     'make-client-socket' (see *note Socket::).  Depending on the
     implementation and back-end the returned socket may or may not be
     'eq?' to SOCKET.

 -- SSL library procedure: make-ssl-server-socket #!key (port 0) (name
          #f) (protocol 'sslv23) (cert #f) (pkey #f) (CAs '())
          (accepted-certs #f)

     'make-ssl-server-socket' returns a new server socket object which
     satisfies the 'socket?' predicate and which can be used in any
     context where a socket created by 'make-server-socket' can be used
     (see *note Socket::).

     A SSL server socket opens the port PORT on the current host NAME
     (the server), and allows remote applications (clients) to connect
     to it.  listening on port PORT-NUMBER of HOSTNAME.  If the optional
     argument PORT is not given or is '0', the server socket will use
     the first availailable port number.  If the optional argument NAME
     is given, the server socket will be bound to the network interface
     representing the given host name.  If it is '#f' (the default) the
     socket will be bound on every local network interface.  If the
     PROTOCOL option argument is given, it specifies the encryption
     protocol.  Accepted values are ''sslv2', ''sslv3', ''sslv23' (alias
     ''ssl'), ''tlsv1' (alias ''tls'), ''tlsv1_1', ''tlsv1_2'
     ''tlsv1_3', or ''dtlsv1' (alias ''dtls').  The default value is
     ''sslv23'.

     The SSL socket will sign the connection using the optional
     arguments CERT (for the certificate) and PKEY (for the private
     key).  The certificate CERT must be of type 'certificate', and the
     private key PKEY must be of type 'private-key'.  If any of those
     two arguments is given, they must both be given.  If those optional
     arguments are missing the connection will be encrypted but not
     signed from the server side, which means the peer (client) will
     have to provide a certificate/private key pair to encrypt the
     connection, and that seldom happens.  Typical SSL servers provide
     their certificate and private key.

     Note that since the peer (client) certificate is only known when we
     are accepting a client socket (with 'socket-accept') the CAS and
     ACCEPTED-CERTS optional arguments are only checked during the
     accept operation of a server socket.

     The CAS optional argument specifies the list of certificates to
     trust as CA (Certificate Authority) for the connection.  It must be
     a list of values of type 'certificate'.  If the list is empty, the
     default list of trusted CA is used (set by the system).  Note that
     giving a list of trusted certificates turns on the peer (client)
     certificate validation: an '&io-error' will be raised if the peer
     (client) certificate is not signed directly or indirectly by one of
     the certificates in CAS when accepting the client socket.

     The ACCEPTED-CERTS optional argument gives a list of certificate
     objects (of type 'certificate') which are accepted as peer (client)
     certificate.  If ACCEPTED-CERTS is '#f' then every peer (client)
     certificate is accepted (aside from eventual certificate
     validation).  If ACCEPTED-CERTS is a list, the peer (client)
     certificate must match one of the given certificates.  Otherwise,
     an '&io-error' will be raised when accepting the client socket.

     If the connection cannot be established, an '&io-error' is raised
     (see *note Errors Assertions and Traces::).

     The function 'make-ssl-server-socket' is defined in the SSL
     library.  A module that needs this facility must then use a
     'library' clause (see *note Modules::).  The SSL library can also
     be loaded from the interpreter using the 'library-load' function
     (see *note Bigloo Libraries::).

          (module secure-echo
             (library ssl))

          (let* ((cert (read-certificate "/etc/ssl/my_cert.crt"))
                 (pkey (read-private-key "/etc/ssl/my_key.pkey"))
                 (cas (read-pem-file "/etc/ssl/ca.cert"))
                 (s (make-ssl-server-socket 1055 :CAs cas :cert cert :pkey pkey))
                 (cs (socket-accept s))
                 (ip (socket-input cs))
                 (op (socket-output cs)))
             (let loop ((e (read ip)))
                (when (not (eof-object? e))
                   (write e op)
                   (loop (read ip))))
             (socket-close s))


File: bigloo.info,  Node: Certificates,  Next: Private Keys,  Prev: SSL Sockets,  Up: SSL

5.7.5.2 Certificates
....................

Certificates are instances of the 'certificate' class.  There type can
be checked with '(isa? expr certificate)'.

 -- SSL library procedure: read-certificate file
     Reads an X509 certificate stored in PEM format in the given FILE
     name.  If the file cannot be read, it raises an '&io-error'
     condition.  Otherwise the certificate is returned.

 -- SSL library procedure: read-pem-file file
     Reads a list of X509 certificate stored in PEM format in the given
     FILE name.  If the file cannot be read, it raises an '&io-error'
     condition.  Otherwise the list of certificate contained in the file
     is returned.

 -- SSL library procedure: certificate-subject cert
     Returns the CommonName (CN) part of the subject of the given
     certificate.

 -- SSL library procedure: certificate-issuer cert
     Returns the CommonName (CN) part of the issuer of the given
     certificate.


File: bigloo.info,  Node: Private Keys,  Prev: Certificates,  Up: SSL

5.7.5.3 Private Keys
....................

Private keys are instances of the 'private-key' class.  There type can
be checked with '(isa? expr private-key)'.

 -- SSL library procedure: read-private-key file
     Reads a private key stored in PEM format in the given FILE name.
     If the file cannot be read, it raises an '&io-error' condition.
     Otherwise the private key is returned.


File: bigloo.info,  Node: Date,  Next: Digest,  Prev: System Programming,  Up: Standard Library

5.8 Date
========

 -- bigloo procedure: date? obj
     Returns '#t' if and only if OBJ is a _date_ as returned by
     'make-date', 'current-date', 'seconds->date', or
     'seconds->gmtdate'.  It returns '#f' otherwise.

 -- bigloo procedure: make-date #!key (nsec 0) (sec 0) (min 0) (hour 0)
          (day 1) (month 1) (year 1970) timezone (dst -1)
     Creates a 'date' object from the integer values passed as argument.

     The argument TIMEZONE, if provided, is expressed in minute.

     Example:
          (write (make-date :sec 0 :min 22 :hour 17 :day 5 :month 2 :year 2003 :dst 0))
            -| #<date:Wed Feb  5 17:22:00 2003>

     The argument DST is either '-1' when the information is not
     available, '0' when daylight saving is disabled, '1' when daylight
     saving is enabled.

 -- bigloo procedure: date-copy date #!key sec min hour day month year
          timezone isdst
 -- bigloo procedure: date-update! date #!key sec min hour day month
          year
     Creates a new date or update an existing from the argument DATE.

     Example:
          (date-copy (current-date) :sec 32 :min 24 :day 5)

 -- bigloo procedure: date->gmtdate! date
     Update the date to switch to an UTC representation.  Returns the
     modified date object.

 -- bigloo procedure: current-date
     Returns a 'date' object representing the current date.

 -- bigloo procedure: current-seconds
 -- bigloo procedure: current-microseconds
 -- bigloo procedure: current-milliseconds
 -- bigloo procedure: current-nanoseconds
     Returns an 'elong' integer representing the current epoch (i.e.,
     the date since 0:00:00 UTC on the morning of 1 January 1970,
     expressed in seconds (resp.  in micro seconds).

 -- bigloo procedure: date->seconds
 -- bigloo procedure: date->nanoseconds
 -- bigloo procedure: date->milliseconds
 -- bigloo procedure: seconds->date
 -- bigloo procedure - 4.3h: seconds->gmtdate
 -- bigloo procedure - 4.3i: milliseconds->gmtdate
 -- bigloo procedure: nanoeconds->date
 -- bigloo procedure: milliseconds->date
     Convert from 'date' and 'elong'.

 -- bigloo procedure: date->string date
 -- bigloo procedure: date->utc-string date
 -- bigloo procedure: seconds->string elong
 -- bigloo procedure: seconds->utc-string elong
     Construct a textual representation of the date passed in argument

 -- bigloo procedure: date-second date
     Returns the number of seconds of a date, in the range '0...59'.

 -- bigloo procedure: date-nanosecond date
 -- bigloo procedure: date-millisecond date
     Returns the number of nano/milli seconds of a date (to be added to
     'date-second').

 -- bigloo procedure: date-minute date
     Returns the minute of a date, in the range '0...59'.

 -- bigloo procedure: date-hour date
     Returns the hour of a date, in the range '0...23'.

 -- bigloo procedure: date-day date
     Returns the day of a date, in the range '1...31'.

 -- bigloo procedure: date-wday date
 -- bigloo procedure: date-week-day date
     Returns the week day of a date, in the range '1...7'.

 -- bigloo procedure: date-yday date
 -- bigloo procedure: date-year-day date
     Returns the year day of a date, in the range '1...366'.

 -- bigloo procedure: date-month date
     Returns the month of a date, in the range '1...12'.

 -- bigloo procedure: date-year date
     Returns the year of a date.

 -- bigloo procedure: date-timezone date
     Returns the timezone (in seconds) of a date.

 -- bigloo procedure: date-is-dst date
     Returns '-1' if the information is not available, '0' is the date
     does not contain daylight saving adjustment, '1' if it contains a
     daylight saving adjustment.

 -- bigloo procedure: integer->second
     Converts a Bigloo fixnum integer into a second number.

 -- bigloo procedure: day-seconds
     Returns the number of seconds contained in one day.

 -- bigloo procedure: day-name int
 -- bigloo procedure: day-aname int
     Return the name and the abbreviated name of a week day.

 -- bigloo procedure: month-name int
 -- bigloo procedure: month-aname int
     Return the name and the abbreviated name of a month.

 -- bigloo procedure: date-month-length date
     Return the length of the month of DATE.

 -- bigloo procedure: leap-year? int
     Returns '#t' if and only if the year INT is a leap year.  Returns
     '#f' otherwise.

 -- bigloo procedure: rfc2822-date->date string
 -- bigloo procedure: rfc2822-parse-date input-port
     Parses RFC2822 string representing a date.  These functions produce
     a Bigloo date object.

 -- bigloo procedure: date->rfc2822-date date
     Converts a Bigloo date into a string representation compliant with
     the RFC2822 format.

 -- bigloo procedure: iso8601-date->date string
 -- bigloo procedure: iso8601-parse-date input-port
     Parses ISO8601 string representing a date.  These functions produce
     a Bigloo date object.

 -- bigloo procedure: date->iso8601-date date
     Converts a Bigloo date into a string representation compliant with
     the iso8601 format.


File: bigloo.info,  Node: Digest,  Next: CRC,  Prev: Date,  Up: Standard Library

5.9 Digest
==========

 -- bigloo procedure: base64-encode string [padding 64]
 -- bigloo procedure: base64-decode string [no-eof-padding]
     Encodes (respec.  decodes) a string into a base64 representation.

     When decoding, if the optional parameter NO-EOF-PADDING is '#t',
     the decoding success even if the input stream is not padded with
     '=' characters.

 -- bigloo procedure: base64-encode-port input-port output-port [padding
          64]
 -- bigloo procedure: base64-decode-port input-port output-port
          [no-eof-padding]
     Encodes (respec.  decodes) an input port into a base64
     representation.

     When decode succeeds, BASE64-DECODE-PORT returns '#t', it returns
     '#f' otherwise.

     When decoding, if the optional parameter NO-EOF-PADDING is '#t',
     the decoding success even if the input stream is not padded with
     '=' characters.

 -- bigloo procedure: pem-read-file file-name
 -- bigloo procedure: pem-decode-port input-port output-port
     Reads a PEM (Privacy Enhanced Mail) base64 encoded file.

 -- bigloo procedure: md5sum obj
 -- bigloo procedure: md5sum-string string
 -- bigloo procedure: md5sum-mmap mmap
 -- bigloo procedure: md5sum-file string
 -- bigloo procedure: md5sum-port input-port
     Computes MD5 message digest.

     The function 'md5sum' dispatches over its argument and invokes the
     ad-hoc function.  That is, it invokes 'md5sum-string' if its
     argument is a string, 'md5sum-mmap' if it is a mmap, 'md5sum-port'
     if its argument is an input port.

 -- bigloo procedure: hmac-md5sum-string key string
     Computes the Hmac MD5 authentication:

          (hmac-md5sum-string (make-string 16 #a011) "Hi There")
            => "9294727a3638bb1c13f48ef8158bfc9d"

 -- bigloo procedure: cram-md5sum-string user key string
     Challenge-Response Authentication Mechanism as specified in RFC
     2195.

     The function 'cram-md5sum-string' assumes that data is base64
     encoded.  The result is also base64 encoded.

 -- bigloo procedure: sha1sum obj
 -- bigloo procedure: sha1sum-string string
 -- bigloo procedure: sha1sum-mmap mmap
 -- bigloo procedure: sha1sum-file string
 -- bigloo procedure: sha1sum-port input-port
     Computes SHA1 message digest.

     The function 'sha1sum' dispatches over its argument and invokes the
     ad-hoc function.  That is, it invokes 'sha1sum-string' if its
     argument is a string, 'sha1sum-mmap' if it is a mmap,
     'sha1sum-port' if its argument is an input port.

 -- bigloo procedure: hmac-sha1sum-string key string
     Computes the Hmac SHA1 authentication:

 -- bigloo procedure: sha256sum obj
 -- bigloo procedure: sha256sum-string string
 -- bigloo procedure: sha256sum-mmap mmap
 -- bigloo procedure: sha256sum-file string
 -- bigloo procedure: sha256sum-port input-port
 -- bigloo procedure: sha512sum obj
 -- bigloo procedure: sha512sum-string string
 -- bigloo procedure: sha512sum-mmap mmap
 -- bigloo procedure: sha512sum-file string
 -- bigloo procedure: sha512sum-port input-port
     Computes SHA256 and SHA512 message digest.

     The function 'sha256sum' (respec.  'sha512sum') dispatches over its
     argument and invokes the ad-hoc function.  That is, it invokes
     'sha256sum-string' if its argument is a string, 'sha256sum-mmap' if
     it is a mmap, 'sha256sum-port' if its argument is an input port.

 -- bigloo procedure: hmac-sha256sum-string key string
 -- bigloo procedure: hmac-sha512sum-string key string
     Computes the Hmac SHA256 and SHA512 authentication.


File: bigloo.info,  Node: CRC,  Next: Internet,  Prev: Digest,  Up: Standard Library

5.10 Cyclic Redundancy Check (CRC)
==================================

Bigloo provides several known cyclic redundancy checks as well as means
to create custom checks.

  Usually CRCs are executed starting with the leftmost bit inside a byte
(big endian).  However, especially for serial-port transmissions, a
scheme where the least-significant bit is processed first is desirable.
Bigloo's CRC procedures accept a key-parameter (':big-endian') (by
default '#t') which allows to change this behavior.

  The following CRCs (given with the associated polynomial) are
provided:
   * 'itu-4': 0x3
   * 'epc-5': 0x9
   * 'itu-5': 0x15
   * 'usb-5': 0x5
   * 'itu-6': 0x3
   * '7': 0x9
   * 'atm-8': 0x7
   * 'ccitt-8': 0x8d
   * 'dallas/maxim-8': 0x31
   * '8': 0xd5
   * 'sae-j1850-8': 0x1d
   * '10': 0x233
   * '11': 0x385
   * '12': 0x80f
   * 'can-15': 0x4599
   * 'ccitt-16': 0x1021
   * 'dnp-16': 0x3d65
   * 'ibm-16': 0x8005
   * '24': 0x5d6dcb
   * 'radix-64-24': 0x864cfb
   * '30': 0x2030b9cf
   * 'ieee-32': 0x4c11db7
   * 'c-32': 0x1edc6f41
   * 'k-32': 0x741b8cd7
   * 'q-32': 0x814141ab
   * 'iso-64': 0x1b
   * 'ecma-182-64': 0x42f0e1eba9ea3693

 -- bigloo procedure: crc-names
     Returns a list of all provided CRCs ('itu-4', 'epc-5', etc.).

 -- bigloo procedure: crc-polynomial name
 -- bigloo procedure: crc-polynomial-le name
     Returns the polynomial for the given name.  The '-le' variant
     returns the little endian polynomial.

          (crc-polynomial 'ieee-32)
              -| #e79764439 ;; == #ex4c11bd7
          (crc-polynomial 24)
              -| 6122955    ;; == #x5d6dcb

 -- bigloo procedure: crc-length name
     Returns the length of the specified CRC.

 -- bigloo procedure: crc name obj [:init 0] [:final-xor 0]
          [:big-endian? #t]
 -- bigloo procedure: crc-string name str::bstring [:init 0] [:final-xor
          0] [:big-endian? #t]
 -- bigloo procedure: crc-port name p::input-port [:init 0] [:final-xor
          0] [:big-endian? #t]
 -- bigloo procedure: crc-mmap name m::mmap [init 0] [:final-xor 0]
          [big-endian? #t]
 -- bigloo procedure: crc-file name f::bstring [init 0] [:final-xor 0]
          [big-endian? #t]
     Computes the CRC of the given object.  NAME must be one of the
     provided CRC-algorithms.  The optional parameter INIT can be used
     to initialize the CRC. The result of the CRC will be XORed with
     FINAL-XOR.  The result will however be of the CRC's length.  That
     is, even if FINAL-XOR is bigger then the CRC's length only the
     relevant bits will be used to perform the final XOR.

     The result will be a number.  Depending on the CRC this number can
     be a fixnum, an elong, or an llong.

     The following example mimicks the UNIX 'cksum' command:
          (module cksum (main main))
          (define (main args)
            (let loop ((sum (crc-file 'ieee-32 (cadr args)))
                       (size (elong->fixnum (file-size (cadr args)))))
              (if (=fx size 0)
                  (printf "~a ~a ~a\n"
                          (bit-andllong #lxFFFFFFFF (elong->llong (bit-notelong sum)))
                          (file-size (cadr args))
                          (cadr args))
                  (loop (crc-string 'ieee-32
                                    (string (integer->char-ur (bit-and size #xFF)))
                                    :init sum)
          	      (bit-rsh size 8)))))

     In the following example we implement OpenPGP's CRC-24:
          (define (openpgp-crc-24 str)
            (crc-string 'radix-64-24 str :init #xB704CE))

     Be aware that many common CRCs use -1 as init value and invert the
     result.  For compatibility with other implementations you might
     want to try one of the following alternatives:
          (define (alt1 name obj) (crc name obj :init -1))
          (define (alt2 name obj) (crc name obj :final-xor -1))
          (define (alt3 name obj) (crc name obj :init -1 :final-xor -1))

  Bigloo provides means to create additional CRCs: one can either simply
provide a new polynomial or use Bigloo's low level functions.

 -- bigloo procedure: register-crc! name poly len
     Adds the given CRC to Bigloo's list.  Name can be of any type
     ('crc' will use 'assoc' to find it in its list).  The polynomial
     can be either a fixnum, an elong or an llong.  LEN should give the
     CRCs size.  The type of the polynomial and the given LEN must be
     consistent.  On a 32 bit machine the following CRC registration
     would be invalid and yield undefined results:

          (register-crc! 'invalid 1337 55)

     As 55 is bigger than the fixnum's bit-size calling 'crc' with this
     CRC will yield undefinde results.

 -- bigloo procedure: crc-long::long c::char crc::long poly::long
          len::long
 -- bigloo procedure: crc-elong::elong c::char crc::elong poly::elong
          len::long
 -- bigloo procedure: crc-llong::llong c::char crc::llong poly::llong
          len::long
 -- bigloo procedure: crc-long-le::long c::char crc::long poly::long
          len::long
 -- bigloo procedure: crc-elong-le::elong c::char crc::elong poly::elong
          len::long
 -- bigloo procedure: crc-llong-le::llong c::char crc::llong poly::llong
          len::long
     These function perform a CRC operation on one byte.  The previously
     described functions are based on these low level functions.  The
     result of all the low level functions will return values that are
     not cut to the correct length.  Usually a crc is done in a loop,
     and one needs to 'bit-and' only when returning the result.
     Polynomials can be given with or without the high-order bit.

     For instance we could implement 'openpgp-crc24' as follows:
          (define *openpgp-init* #xB704CE)
          (define *radix-64-24-poly* #x864CFB)
          (define (openpgp-crc-24 str)
            (let loop ((i 0)
                       (crc *openpgp-init*))
              (if (=fx i (string-length str))
                  (bit-and crc #xFFFFFF) ;; cut to correct length (24 bits)
                  (loop (+fx i 1)
                        (crc-long (string-ref str i) crc *radix-64-24-poly* 24)))))

 -- bigloo procedure: crc-polynomial-be->le len polynomial
     Returns the little endian variant of a given polynomial.


File: bigloo.info,  Node: Internet,  Prev: CRC,  Up: Standard Library

5.11 Internet
=============

This section presents the Bigloo function aimed at helping internet
programming.

* Menu:

* URLs::
* HTTP::


File: bigloo.info,  Node: URLs,  Next: HTTP,  Up: Internet

5.12 URLs
=========

 -- bigloo procedure: url-parse url
     The argument URL can either be a string or an input-port.  The
     function 'url-parse' parses the url and returns four values:

        * the protocol,
        * the optional user info,
        * the host name,
        * the port number,
        * the absolute path

     Example
          (multiple-value-bind (protocol uinfo host port abspath)
             (url-parse "http://www.inria.fr/sophia/teams/indes/index.html")
             (list protocol uinfo host port abspath))
                => ("http" #f "www.inria.fr" 80 "/sophia/teams/indes/index.html'')
          (multiple-value-bind (protocol uinfo host port abspath)
             (url-parse "https://foo:bar@www.inria.fr/sophia/teams/indes/index.html")
             (list protocol uinfo))
                => ("https" "foo@bar")

 -- bigloo procedure: url-sans-protocol-parse url protocol

     The argument URL can either be a string or an input-port.

     This function behaves as 'url-parse' except it assumes that the
     protocol part of the url has already been extracted from the URI.
     It is explicitly provided using the PROTOCOL argument.

 -- bigloo procedure: http-url-parse url
     The argument URL can either be a string or an input-port.  As
     'url-parse', it returns four values.

     This function parses URL found in HTTP GET responses.

 -- bigloo procedure: url-path-encode path
     Encode a path that can be used in valid URL.

          (url-path-encode "/tmp/foo") => "/tmp/foo"
          (url-path-encode "/tmp/foo&bar") => "/tmp/foo%26bar"
          (url-path-encode "http:///tmp/foo") => "http%3A//tmp/foo"

 -- bigloo procedure: url-encode url
 -- bigloo procedure: uri-encode url
 -- bigloo procedure: uri-encode-component url
     Encode a URL by removing any illegal character.

          (url-encode "http:///tmp/foo") => "http://tmp:80/foo"
          (url-encode "http:///tmp/foo&bar") => "http://tmp:80/foo%26"

 -- bigloo procedure: url-decode url
 -- bigloo procedure: url-decode! url
 -- bigloo procedure: uri-decode url
 -- bigloo procedure: uri-decode! url
 -- bigloo procedure: uri-decode-component url
 -- bigloo procedure: uri-decode-component! url
     Decode a URL. The function 'url-decode!' may return its argument
     unmodified if no decoding is for the URL.

     The variants '-component' treat do not escape URI reserved
     characters (i.e., #, /, ?, :, @, &, =, +, and $).


File: bigloo.info,  Node: HTTP,  Prev: URLs,  Up: Internet

5.13 HTTP
=========

 -- bigloo procedure: http [:in #f] [:out #f] [:socket #f]
     [:protocol 'http] [:method 'get] [:timeout 0] [:proxy #f] [:host
     "localhost"] [:port 80] [:path "/"] [:login #f] [:authorization #f]
     [:username #f] [:password #f] [:http-version "HTTP/1.1"]
     [:content-type #f] [:connection "close"] [:header '((user-agent:
     "Mozilla/5.0"))] [:args '()] [:body #f]

     Opens an HTTP connection.  Returns a socket.

     It is an error to specify a header twice.  In particular, it is
     illegal to re-define keyword-ed arguments in the :HEADER list.  For
     instance, it is illegal to include in the ':header' actual list
     value a value for the 'Connection' HTTP connection.

          (define (wget url)

             (define (parser ip status-code header clen tenc)
                (if (not (and (>=fx status-code 200) (<=fx status-code 299)))
          	  (case status-code
          	     ((401)
          	      (raise (instantiate::&io-port-error
          			(proc 'open-input-file)
          			(msg "Cannot open URL, authentication required")
          			(obj url))))
          	     ((404)
          	      (raise (instantiate::&io-file-not-found-error
          			(proc 'open-input-file)
          			(msg "Cannot open URL")
          			(obj url))))
          	     (else
          	      (raise (instantiate::&io-port-error
          			(proc 'open-input-file)
          			(msg (format "Cannot open URL (~a)" status-code))
          			(obj url)))))
          	  (cond
          	     ((not (input-port? ip))
          	      (open-input-string ""))
          	     (clen
          	      (input-port-fill-barrier-set! ip (elong->fixnum clen))
          	      ip)
          	     (else
          	      ip))))

             (multiple-value-bind (protocol login host port abspath)
                (url-parse url)
                (let* ((sock (http :host host :port port :login login :path abspath))
          	     (ip (socket-input sock))
          	     (op (socket-output sock)))
          	 (with-handler
          	    (lambda (e)
          	       (if (isa? e &http-redirection)
                             (with-access::&http-redirection e (url)
          		      (wget url))
          		   (raise e)))
          	    (read-string (http-parse-response ip op parser))))))

     The optional argument 'args' is used for 'post' method.  The actual
     value should be a list of lists.  Each of these sublists must have
     two values:

        * the argument name
        * the argument actual value

     The argument name can be either a string which is the name of the
     argument or a list of two elements.  In that case, the first
     element of these list is the argument name.  The second element
     should be a string that denotes additional parameter.

     Example:

          (http :host "localhost" :port 8080 :method 'post
             :header '((enctype: "multipart/form-data"))
             :args `(("x" "foo") (("foo.scm" "filename=\"foo.scm\"\nContent-type: application/octet-stream" ,(with-input-from-file "foo.scm" read-string))))
             ...)

     An http connection blocks until the connection is established.  If
     the optional argument 'timeout' is provided, the connection must be
     established before the specified time interval elapses.  The
     timeout is expressed in microseconds.

 -- bigloo procedure: http-read-line input-port
 -- bigloo procedure: http-read-crlf input-port
     Reads a line or an end-of-line of an HTTP response.

 -- bigloo procedure: http-parse-status-line input-port
     Parses the status-line of an HTTP response.  This returns a three
     values:

        * The http version
        * The status code
        * the explanation phrase

 -- bigloo procedure: http-parse-header input-port output-port
     Parses the whole header of an HTTP response.  It returns multiple
     values which are:

        * the whole header as an alist.
        * the host given in the 'host' header.
        * the port given 'host' field.
        * the optional CONTENT-LENGTH header field.
        * the optional TRANSFER-ENCODING header field.
        * the optional AUTHORIZATION header field.
        * the optional PROXY-AUTHORIZATION header field.
        * the optional CONNECTION header field.

 -- bigloo procedure: http-parse-response input-port output-port
          procedure
     Parses the whole response of an HTTP request.  The argument
     PROCEDURE is invoked with five arguments:

        * the input port to read the characters of the response,
        * the status code,
        * the header of the response,
        * the content length,
        * the type encoding.

 -- bigloo procedure: http-response-body->port input-port output-port
     Parses an HTTP response and build an output port that delivers the
     characters of the content.

 -- bigloo procedure: http-chunks->procedure input-port

 -- bigloo procedure: http-chunks->port input-port

 -- bigloo procedure: http-send-chunks input-port output-port


File: bigloo.info,  Node: Pattern Matching,  Next: Fast search,  Prev: Standard Library,  Up: Top

6 Pattern Matching
******************

Pattern matching is a key feature of most modern functional programming
languages since it allows clean and secure code to be written.
Internally, "pattern-matching forms" should be translated (compiled)
into cascades of "elementary tests" where code is made as efficient as
possible, avoiding redundant tests; Bigloo's "pattern matching compiler"
provides this.  The technique used is described in details in
[QueinnecGeffroy92], and the code generated can be considered optimal
(1) (*note Pattern Matching-Footnote-1::) due to the way this "pattern
compiler" was obtained.

  The "pattern language" allows the expression of a wide variety of
patterns, including:

   * Non-linear patterns: pattern variables can appear more than once,
     allowing comparison of subparts of the datum (through 'eq?')

   * Recursive patterns on lists: for example, checking that the datum
     is a list of zero or more 'a's followed by zero or more 'b's.

   * Pattern matching on lists as well as on vectors and structures, and
     record types.

* Menu:

* Bigloo Pattern Matching Facilities::
* The Pattern Language::


File: bigloo.info,  Node: Pattern Matching-Footnotes,  Up: Pattern Matching

   (1) In the cases of pattern matching in lists and vectors, not in
structures for the moment.


File: bigloo.info,  Node: Bigloo Pattern Matching Facilities,  Next: The Pattern Language,  Up: Pattern Matching

6.1 Bigloo pattern matching facilities
======================================

Only two special forms are provided for this in Bigloo: 'match-case' and
'match-lambda'.

 -- bigloo syntax: match-case key clause...
     The argument KEY may be any expression and each CLAUSE has the form

          (PATTERN S-EXPRESSION...)

     _Semantics: _ A 'match-case' expression is evaluated as follows.
     KEY is evaluated and the result is compared with each successive
     pattern.  If the pattern in some CLAUSE yields a match, then the
     expressions in that CLAUSE are evaluated from left to right in an
     environment where the pattern variables are bound to the
     corresponding subparts of the datum, and the result of the last
     expression in that CLAUSE is returned as the result of the
     'match-case' expression.  If no PATTERN in any CLAUSE matches the
     datum, then, if there is an 'else' clause, its expressions are
     evaluated and the result of the last is the result of the whole
     'match-case' expression; otherwise the result of the 'match-case'
     expression is unspecified.

     The equality predicate used is 'eq?'.

          (match-case '(a b a)
             ((?x ?x) 'foo)
             ((?x ?- ?x) 'bar))
             => bar

  The following syntax is also available:

 -- bigloo syntax: match-lambda clause...

     It expands into a lambda-expression expecting an argument which,
     once applied to an expression, behaves exactly like a 'match-case'
     expression.

          ((match-lambda
             ((?x ?x) 'foo)
             ((?x ?- ?x) 'bar))
           '(a b a))
             => bar


File: bigloo.info,  Node: The Pattern Language,  Prev: Bigloo Pattern Matching Facilities,  Up: Pattern Matching

6.2 The pattern language
========================

The syntax for <pattern> is:

     <pattern> ==>                _Matches:_

       <atom>                    the <atom>.
     | (kwote <atom>)            any expression 'eq?' to '<atom>'.
     | (and <pat1> ... <patn>)   if all of '<patI>' match.
     | (or <pat1> ... ...<patn>) if any of '<pat1>' through '<patn>' matches.
     | (not <pat>)               if '<pat>' doesn't match.
     | (? <predicate>)           if '<predicate>' is true.
     | (<pat1> ... <patn>)       a list of n elements. Here, '...' is a
                                 meta-character denoting a finite repetition
                                 of patterns.
     | <pat> ...                 a (possibly empty) repetition
                                 of '<pat>' in a list.
     | #(<pat> ... <patn>)       a vector of N elements.
     | #{<struct> <pat> ... }    a structure.
     | ?<id>                     anything, and binds 'id' as a variable.
     | ?-                        anything.
     | ??-                       any (possibly empty) repetition of anything
                                 in a list.
     | ???-                      any end of list.

_Remark: _ 'and, or, not, check' and 'kwote' must be quoted in order to
be treated as literals.  This is the only justification for having the
'kwote' pattern since, by convention, any atom which is not a keyword is
quoted.

   * '?-' matches any s-expr

   * 'a' matches the atom ''a'.

   * '?a' matches any expression, and binds the variable 'a' to this
     expression.

   * '(? integer?)' matches any integer

   * '(a (a b))' matches the only list ''(a (a b))'.

   * '???-' can only appear at the end of a list, and always succeeds.
     For instance, '(a ???-)' is equivalent to '(a . ?-)'.

   * when occurring in a list, '??-' matches any sequence of anything:
     '(a ??- b)' matches any list whose 'car' is 'a' and last 'car' is
     'b'.

   * '(a ...)' matches any list of 'a''s, possibly empty.

   * '(?x ?x)' matches any list of length 2 whose 'car' is _eq_ to its
     'cadr'

   * '((and (not a) ?x) ?x)' matches any list of length 2 whose 'car' is
     not _eq_ to ''a' but is _eq_ to its 'cadr'

   * '#(?- ?- ???-)' matches any vector whose length is at least 2.

   * '#{foo (?- . ?-) (? integer?)}' matches any structure or record
     'foo' whose first and second fields are respectively a pair and an
     integer.  You can provide only the fields you want to test.  The
     order is not relevant.

  _Remark: _ '??-' and '...' patterns can not appear inside a vector,
where you should use '???-': For example, '#(a ??- b)' or '#(a...)' are
invalid patterns, whereas '#(a ???-)' is valid and matches any vector
whose first element is the atom 'a'.


File: bigloo.info,  Node: Fast search,  Next: Structures and Records,  Prev: Pattern Matching,  Up: Top

7 Fast search
*************

This chapters details the Bigloo's API for fast string search
algorithms.

* Menu:

* Knuth - Morris - Pratt::
* Boyer - Moore::
* Boyer - Moore - Horspool::


File: bigloo.info,  Node: Knuth - Morris - Pratt,  Next: Boyer - Moore,  Up: Fast search

7.1 Knuth, Morris, and Pratt
============================

Bigloo supports an implementation of the _Knuth, Morris, and Pratt_
algorithm on strings and memory mapped area, *Note Memory mapped area::.

 -- bigloo procedure: kmp-table pattern
     This function creates a _kmp_-table used for fast search.

 -- bigloo procedure: kmp-mmap kmp-table mmap offset
 -- bigloo procedure: kmp-string kmp-table string offset
     This function searches the PATTERN described by KMP-TABLE in the
     memory mapped area MMAP (respec.  in the STRING).  The search
     starts at OFFSET.  If an occurrence is found, its position in the
     MMAP is returned.  Otherwise '-1' is returned.

     For the sake of the example, here is a prototypal implementation of
     the Usenix command 'grep':

          (define (main args)
             (cond
                ((null? (cdr args))
                 (fprintf (current-error-port) "Usage: grep STRING [FILE]...")
                 (exit 0))
                (else
                 (let ((t (kmp-table (cadr args))))
          	  (for-each (lambda (f) (grep-file t f)) (cddr args))))))

          (define (grep-file t file)
             (let* ((mm (open-mmap file read: #t write: #f))
          	  (ls (mmap-length mm)))
                (let loop ((o 0))
          	 (unless (>=fx o ls)
          	    (let ((n (kmp-mmap t mm o)))
          	       (when (>fx n 0)
          		  (print file ":" (mmap-line mm ls n))
          		  (loop (+fx n 1))))))
                (close-mmap mm)))

          (define (mmap-line mm ls n)
             (let ((b 0)
          	 (e (elong->fixnum ls)))
                ;; beginning
                (let loop ((i n))
          	 (when (>fx i 0)
          	    (if (char=? (mmap-ref mm i) #\Newline)
          		(set! b (+fx i 1))
          		(loop (-fx i 1)))))
                ;; end
                (let loop ((i n))
          	 (when (<fx i ls)
          	    (if (char=? (mmap-ref mm i) #\Newline)
          		(set! e i)
          		(loop (+fx i 1)))))
                (mmap-substring mm b (- e b))))


File: bigloo.info,  Node: Boyer - Moore,  Next: Boyer - Moore - Horspool,  Prev: Knuth - Morris - Pratt,  Up: Fast search

7.2 Boyer - Moore
=================

Bigloo supports an implementation of the _Boyer, Moore_ algorithm on
strings and memory mapped area, *Note Memory mapped area::.

 -- bigloo procedure: bm-table pattern
     This function creates a _bm_-table used for fast search.

 -- bigloo procedure: bm-mmap bm-table mmap offset
 -- bigloo procedure: bm-string bm-table string offset
     This function searches the PATTERN described by BM-TABLE in the
     memory mapped area MMAP (respec.  in the STRING).  The search
     starts at OFFSET.  If an occurrence is found, its position in the
     MMAP is returned.  Otherwise '-1' is returned.

     For the sake of the example, here is a prototypal implementation of
     the Usenix command 'grep':

          (define (main args)
             (cond
                ((null? (cdr args))
                 (fprintf (current-error-port) "Usage: grep STRING [FILE]...")
                 (exit 0))
                (else
                 (let ((t (bm-table (cadr args))))
          	  (for-each (lambda (f) (grep-file t f)) (cddr args))))))

          (define (grep-file t file)
             (let* ((mm (open-mmap file read: #t write: #f))
          	  (ls (mmap-length mm)))
                (let loop ((o 0))
          	 (unless (>=fx o ls)
          	    (let ((n (bm-mmap t mm o)))
          	       (when (>fx n 0)
          		  (print file ":" (mmap-line mm ls n))
          		  (loop (+fx n 1))))))
                (close-mmap mm)))

          (define (mmap-line mm ls n)
             (let ((b 0)
          	 (e (elong->fixnum ls)))
                ;; beginning
                (let loop ((i n))
          	 (when (>fx i 0)
          	    (if (char=? (mmap-ref mm i) #\Newline)
          		(set! b (+fx i 1))
          		(loop (-fx i 1)))))
                ;; end
                (let loop ((i n))
          	 (when (<fx i ls)
          	    (if (char=? (mmap-ref mm i) #\Newline)
          		(set! e i)
          		(loop (+fx i 1)))))
                (mmap-substring mm b (- e b))))


File: bigloo.info,  Node: Boyer - Moore - Horspool,  Prev: Knuth - Morris - Pratt,  Up: Fast search

7.3 Boyer - Moore - Horspool
============================

Bigloo supports an implementation of the _Boyer, Moore, Horspool_
algorithm on strings and memory mapped area, *Note Memory mapped area::.

 -- bigloo procedure: bmh-table pattern
     This function creates a _bmh_-table used for fast search.

 -- bigloo procedure: bmh-mmap bm-table mmap offset
 -- bigloo procedure: bmh-string bm-table string offset
     This function searches the PATTERN described by BMH-TABLE in the
     memory mapped area MMAP (respec.  in the STRING).  The search
     starts at OFFSET.  If an occurrence is found, its position in the
     MMAP is returned.  Otherwise '-1' is returned.


File: bigloo.info,  Node: Structures and Records,  Next: Object System,  Prev: Fast search,  Up: Top

8 Structures and Records
************************

Bigloo supports two kinds of enumerated types: the _structures_ and the
_records_.  They offer similar facilities.  Structures were pre-existing
to records and they are maintained mainly for backward compatiblity.
Recors are compliant with the Scheme request for implementation 9.

* Menu:

* Structures::
* Records (SRFI-9)::


File: bigloo.info,  Node: Structures,  Next: Records (SRFI-9),  Up: Structures and Records

8.1 Structures
==============

There is, in Bigloo, a new class of objects: structures, which are
equivalent to C 'struct'.

 -- bigloo syntax: define-struct name field...

     This form defines a structure with name NAME, which is a symbol,
     having fields FIELD... which are symbols or lists, each list being
     composed of a symbol and a default value.  This form creates
     several functions: creator, predicate, accessor and assigner
     functions.  The name of each function is built in the following
     way:
        * Creator: 'make-NAME'
        * Predicate: 'NAME?'
        * Accessor: 'NAME-FIELD'
        * Assigner: 'NAME-FIELD-set!'

     Function 'make-NAME' accepts optional arguments.  If a single
     argument is provided, all the slots of the created structures are
     filled with it.  If more than one argument is passed, the various
     values are used to initialize the corresponding structure slots.
     The creator named 'name' accepts as many arguments as the number of
     slots of the structure.  This function allocates a structure and
     fills each of its slots with its corresponding argument.

     If a structure is created using 'make-NAME' and no initialization
     value is provided, the slot default values (when provided) are used
     to initialize the new structure.  For instance, the execution of
     the program:

          (define-struct pt1 a b)
          (define-struct pt2 (h 4) (g 6))

          (make-pt1)
             => #{PT1 () ()}
          (make-pt1 5)
             => #{PT1 5 5}
          (make-pt2)
             => #{PT2 4 6}
          (make-pt2 5)
             => #{PT2 5 5}

 -- bigloo procedure: struct? obj
     Returns '#t' if and only if OBJ is a structure.


File: bigloo.info,  Node: Records (SRFI-9),  Prev: Structures,  Up: Structures and Records

8.2 Records (SRFI-9)
====================

Bigloo supports records has specified by SRFI-9.  This section is a copy
of the SRFI-9 specification by Richard Kelsey.  This SRFI describes
syntax for creating new data types, called record types.  A predicate,
constructor, and field accessors and modifiers are defined for each
record type.  Each new record type is distinct from all existing types,
including other record types and Scheme's predefined types.

 -- syntax: define-record-type expression...

     The syntax of a record-type definition is:

          <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>
          <accessor-name>          ==> <identifier>
          <predicate-name>         ==> <identifier>
          <modifier-name>          ==> <identifier>
          <type-name>              ==> <identifier>

     'Define-record-type' is generative: each use creates a new record
     type that is distinct from all existing types, including other
     record types and Scheme's predefined types.  Record-type
     definitions may only occur at top-level (there are two possible
     semantics for 'internal' record-type definitions, generative and
     nongenerative, and no consensus as to which is better).

     an instance of 'define-record-type' is equivalent to the following
     definitions:

        * '<type-name>' is bound to a representation of the record type
          itself.  Operations on record types, such as defining print
          methods, reflection, etc.  are left to other SRFIs.

        * '<constructor-name>' is bound to a procedure that takes as
          many arguments as the re are '<field-tag>'s in the
          '(<constructor-name> ...)' subform and returns a new
          '<type-name>' record.  Fields whose tags are listed with
          '<constructor-name>' have the corresponding argument as their
          initial value.  The initial values of all other fields are
          unspecified.

        * '<predicate-name>' is a predicate that returns '#t' when given
          a value returned by '<constructor-name>' and '#f' for
          everything else.

        * Each '<accessor-name>' is a procedure that takes a record of
          type '<type-name>' and returns the current value of the
          corresponding field.  It is an error to pass an accessor a
          value which is not a record of the appropriate type.

        * Each '<modifier-name>' is a procedure that takes a record of
          type '<type-name>' and a value which becomes the new value of
          the corresponding field; an unspecified value is returned.  It
          is an error to pass a modifier a first argument which is not a
          record of the appropriate type.

     Records are disjoint from the types listed in Section 4.2 of R5RS.

     Seting the value of any of these identifiers has no effect on the
     behavior of any of their original values.

     The following

          (define-record-type pare
              (kons x y)
              pare?
              (x kar set-kar!)
              (y kdr))

     defines 'kons' to be a constructor, 'kar' and 'kdr' to be
     accessors, 'set-kar!' to be a modifier, and 'pare?' to be a
     predicate for 'pare's.

            (pare? (kons 1 2))        => #t
            (pare? (cons 1 2))        => #f
            (kar (kons 1 2))          => 1
            (kdr (kons 1 2))          => 2
            (let ((k (kons 1 2)))
              (set-kar! k 3)
              (kar k))                => 3


File: bigloo.info,  Node: Object System,  Next: Regular Parsing,  Prev: Structures and Records,  Up: Top

9 Object System
***************

Bigloo's object system is designed to be as simple as possible and
belongs to the CLOS [Bobrow et al.  88] object system family in that it
uses _classes_, _generic functions_ and _methods_.  Its design has been
strongly influenced by C. Queinnec's MEROON [Queinnec93] It does not
include any meta object protocol.

* Menu:

* Class declaration::
* Creating and accessing objects::
* Generic functions::
* Widening and shrinking::
* Object library::
* Object serialization::
* Equality::
* Introspection::


File: bigloo.info,  Node: Class declaration,  Next: Creating and accessing objects,  Up: Object System

9.1 Class declaration
=====================

Classes are defined in a module declaration.  A class declaration can
take place in a compiled or interpreted module.  If a class declaration
takes place in a static module clause (see Section *note Module
Declaration::) its scope is limited to the current module but if it
takes place in an export module clause, its scope is extended to all
modules that import the current module.  The syntax of a class
declaration is:

 -- bigloo module clause: class ident field ...

          <class> ==> (class <ident> <constructor>? <field>+)
               | (final-class <ident> <constructor>? <field>+)
               | (wide-class <ident> <constructor>? <field>+)
               | (abstract-class <ident> <constructor>? <field>+)
          <constructor> ==> ( <expr> )
          <field> ==> <ident>
               | (<ident> <field-prop>)
          <field-prop> ==> read-only
               | (get <bigloo-exp>)
               | (set <bigloo-exp>)
               | (default <bigloo-exp>)
               | (info <bigloo-exp>)

     A class is a Bigloo type (see Section *note Atomic types::) and the
     class identifier is extracted from the <ident> of the class
     definition.  If <ident> is also a <typed-ident>, the type part of
     this identifier denote the super-class of the class.  If <ident> is
     a <IEEE-ident>, the super-class of the class is the root of the
     inheritance tree, the 'object' class.  This 'object' class is the
     only pre-existing class.

     _Final classes_ can only be sub-classed by _wide classes_.  _Wide
     classes_ (only for compiled modules) can only inherit from _final
     classes_.  _abstract classes_ can't be instantiated.

     Wide-classes cannot be defined within the interpreter.

     The optional constructor is an expression that must evaluate to a
     one argument function.  This function is automatically invoked each
     time a new class instance is created.  The constructor is passed
     the fresh instance.  If a class has not defined a constructor the
     super class' constructors are searched.  The first constructor
     found is invoked.  A constructor may be a generic function with a
     method specified for one or more classes.

     A class field may be a _typed class field_ which is achieved by
     using a <typed-ident> instead of a <IEEE-ident> for the <ident>
     value.

     Field marked with 'read-only' declaration are immutables.

     'Default' declarations allow default field values.

     For the means of an example, the traditional points and colored
     points can be defined as:
          (module example
             (static (abstract-class pt)
                     (class point::pt
                        x::double
                        y::double)
                     (class point-C::point
                        (color::string read-only))))

     We illustrate final and wide classes by the example:
          (module example
             (export (final-class person
                         (name::string (default "Jones"))
                         (sex read-only)
                         children::pair-nil)
                     (wide-class married-person::person
                         mate::person)))

     Fields may be virtual.  A field is virtual as soon as its
     declaration contain a 'get' attribute.  Virtual fields have no
     physical implementation within the instance.  When defining a
     virtual field, the class declaration implements a _getter_ and a
     _setter_ if that field is not a read only field.  Access to the
     virtual field will rely on invocation of the user _getter_ and user
     _setter_.  For instance:

          (module example
             (static (class complex
                        mag::double
                        angle::double
                        (real::double (get (lambda (p)
                                              (with-access::complex p (mag angle)
                                                 (* mag (cos angle)))))
                                      read-only)
                        (imag::double (get (lambda (p)
                                              (with-access::complex p (mag angle)
                                                 (* mag (sin angle)))))
                                      read-only))))

          (let ((p (instantiate::complex (mag 1.0) (angle 2.18))))
             (with-access::complex p (real imag)
                (print "real: " real)
                (print "imag: " imag)))

     Virtual fields cannot be associated default values.  If a virtual
     field is not provided with a setter it must be annotated as read
     only.

     'Info' declarations allow arbitrary user information field values.
     This value can be retrieved by introspection, by the means of the
     'class-field-info' introspection function.

     For the means of an example, with add to information to the slot of
     the point class.
          (module example
             (static (class point
                        (x::double (info '(range 0.0 10.0)))
                        (y::double (info '(range -1.0 1.0)))))


File: bigloo.info,  Node: Creating and accessing objects,  Next: Generic functions,  Prev: Class declaration,  Up: Object System

9.2 Creating and accessing objects
==================================

Objects and classes are created and manipulated via library functions
and forms created automatically by Bigloo when a new class is defined.

 -- bigloo procedure: isa? obj class

     This function returns '#t' if OBJ is an instance of CLASS or an
     instance of a sub-class of CLASS, otherwise, it returns '#f'.

 -- bigloo syntax: instantiate::CLASS (ident value)...
     This forms allocates object of class CLASS and fills the fields
     with values found in the list of parameters (note that field are
     explicitly named and that there is no ordering for field naming).
     Field values which are not provided in the parameter list must have
     been declared with a 'default' value which is used to initialize
     the corresponding field.

     For instance:
          (module example
             (export
                (class point (x (default 0)))
                (class point2d::point y)))

          (instantiate::point (x 0) (y 0))
          (instantiate::point (y 0))
          (instantiate::point (x 0))
            => Error because Y has no default value

 -- bigloo procedure: class-nil class

     This function returns the NIL pre-existing class instance.  This
     instance plays the role of 'void *' in C or 'null' in Java.  The
     value of each field is unspecified but correct with respect to the
     Bigloo type system.  Each call to 'CLASS-nil' returns the same
     object (in the sense of 'eq?').

          (module example
             (export
                (class point x)
                (class point2d::point y)))

          (eq? (class-nil point) (class-nil point))
            => #t
          (eq? (class-nil point) (class-nil point2d))
            => #f

 -- bigloo syntax: with-access::CLASS obj (binding...) body

     A reference to any of the variables defined in as a BINDING is
     replaced by the appropriate field access form.  This is true for
     both reference and assignment.  A BINDING is either a symbol or a
     list of two symbols.  In the first place, it denotes a field.  In
     the second case, it denotes an aliases field.

     For instance:
          (with-access::point p (x (y1 y))
             (with-access::point p2 (y)
                (set! x (- x))
                (set! y1 (- y1 y))))

 -- bigloo syntax: -> VAR FIELD
     Class instances can be accesses using the '->' special form.  The
     the first argument must be the identifier of a local typed
     variable, otherwise an error is raised.  The form '->' can be used
     to get or set value of an instance field.  For instance:

          (define (example p1::point p2::point)
             (set! (-> p1 x) (- (-> p1 x)))
             (set! (-> p1 y) (- (-> p1 y) (-> p2 y))))

     This is equivalent to:
          (define (example p1::point p2::point)
             (with-access::point p1 (x (y1 y))
                (with-access::point p2 (y)
                   (set! x (- x))
                   (set! y1 (- y1 y)))))

 -- bigloo syntax: co-instantiate ((VAR VALUE) ...) body

     This form is only available from compiled modules.  In other words,
     it is not available from the interpreter.  It permits the creation
     of recursive instances.  It is specially useful for creating
     instances for which class declarations contain cyclic type
     references (for instance a class 'c1' for a which a field is
     declared of class 'c2' and a class 'c2' for which a class is
     declared of type 'c1').  The syntax of a 'co-instantiate' form is
     similar to a 'let' form.  However the only legal VALUES are
     'instantiate' forms.  The variables introduced in the binding of a
     'co-instantiate' form are bound in BODY.  In addition, they are
     _partially_ bound in the VALUES expressions.  In a VALUE position,
     a variable VAR can only be used to set the value of a field of an
     instantiated class.  It cannot be used in any calculus.  Example:

          (module obj-example
             (export (class c1 a b o2::c2)
                     (class c2 x y o1::c1)))

          (co-instantiate ((o1 (instantiate::c1
                                  (a 10)
                                  (b 20)
                                  (o2 o2)))
                           (o2 (instantiate::c2
                                  (x 10)
                                  (y 20)
                                  (o1 o1))))
             (with-access::c1 o1 (o2)
                (with-access::c2 o2 (x y)
                   (+ x y))))
             => 30

 -- bigloo syntax: duplicate::CLASS obj (ident value)...
     This forms allocates an instance of class CLASS.  The field values
     of the new object are picked up from the field values of the OLD
     object unless they are explicitly given in the parameter list.

     For instance:
          (with-access::point old (x)
             (instantiate::point
                (x x)
                (y 10)))
     is equivalent to:
          (duplicate::point old (y 10))

     The duplicated instance might be a subclass of duplicated instance.
     Example:

          (module foo
             (export (class point x y)
          	   (class point3::point z)
          	   (class point4::point3 t))
             (main main))

          (define (main x)
             (let ((p (instantiate::point (x 1) (y 2))))
                (print (duplicate::point4 p (z 6) (t 55)))))


File: bigloo.info,  Node: Generic functions,  Next: Widening and shrinking,  Prev: Creating and accessing objects,  Up: Object System

9.3 Generic functions
=====================

A generic function is a bag of specific functions known as methods.
When invoked on a Bigloo object, a generic function determines the class
of the discriminating variable (corresponding to the first argument of
the generic function) and invokes the appropriate method.  Generic
functions implement single inheritance and each is defined using the
'define-generic' Bigloo syntax.

 -- bigloo syntax: define-generic (name arg...) default-body

     A generic function can be defined with a default body which will be
     evaluated if no method can be found for the discriminating
     variable.  The default default-body signals an error.

  As an example, here is a possible definition of the 'object-display'
generic function:

     (define-generic (object-display obj::object . op)
        (let ((port (if (pair? op)
                        (car op)
                        (current-output-port))))
           (display "#\|" port)
           (display (class-name (object-class obj)) port)
           (display "\|" port)))

  Methods can be defined to specialize a generic function and such
methods must have a compatible variable list.  That is, the first
argument of the method must be a sub-type (i.e.  belong to a sub-class)
of the first argument of the generic function.  Other formal parameters
must be of same types.  Moreover, the result type of the method must be
a sub-type of the result of the generic function.

 -- bigloo syntax: define-method (name arg...) body
 -- bigloo syntax: call-next-method
     If there is no appropriate method, an error is signaled.

     Methods can use the form '(call-next-method)' to invoke the method
     that would have been called if not present.  The
     '(call-next-method)' cannot be used out of method definition.
     example:
          (define-method (object-display p::person . op)
             (let ((port (if (pair? op)
                             (car op)
                             (current-output-port))))
                (fprint port "firstname : " (-> p fname))
                (fprint port "name      : " (-> p name))
                (fprint port "sex       : " (-> p sex))
                p))


File: bigloo.info,  Node: Widening and shrinking,  Next: Object library,  Prev: Generic functions,  Up: Object System

9.4 Widening and shrinking
==========================

Bigloo introduces a new kind of inheritance: _widening_.  This allows an
object to be temporarily _widened_ (that is transformed into an object
of another class, a _wide-class_) and then _shrink-ed_ (that is reshaped
to its original class).  This mechanism is very useful for implementing
short-term data storage.  For instance, Bigloo compilation passes are
implemented using the _widening/shrinking_ mechanism.  On entry to a
pass, objects are widened with the specific pass fields and, on exit
from a pass, objects are shrunk in order to forget the information
related to this pass.

  Only instances of _final classes_ can be widened and objects can only
be widened in order to become instances of _wide classes_.  Widening is
performed by the 'widen!' syntax:

 -- bigloo syntax: widen!::WIDE-CLASS obj (id value) ...

     The object OBJ is widened to be instance of the wide class
     WIDE-CLASS.  Fields values are either picked up from the parameter
     list of the 'widen!' form or from the default values in the
     declaration of the wide class.

  Objects are shrunk using the 'shrink!' syntax:

 -- bigloo syntax: shrink! obj

  Here is a first example:
     (module example
        (static (final-class point
                   (x (default 0))
                   (y (default 0)))
                (wide-class named-point::point name)))

     (define *point* (instantiate::point))

  Two classes have been declared and an instance '*point*' of 'point'
has been allocated.  For now, '*point*' is an instance of 'point' but
not an instance of 'named-point' and this can be checked by:
     (print (isa? *point* named))           ==> #t
     (print (isa? *point* named-point))     ==> #f

  Now, we _widen_ '*point*'...
     (let ((n-point (widen!::named-point *point*
                       (name "orig"))))

  And we check that now, 'n-point' is an instance of 'named-point'.
Since 'named-point' is a subclass of 'point', 'n-point' still is an
instance of 'point'.

     (print (isa? n-point named-point))  ==> #t
     (print (isa? n-point named))        ==> #t

  Widening affects the objects themselves.  It does not operate any copy
operation.  Hence, '*point*' and 'n-point' are 'eq?'.

     (print (eq? n-point *point*))   ==> #t

  To end this example, we _shrink_ 'n-point' and check its class.
     (shrink! n-point)
     (print (isa? *point* named-point))) ==> #f

  Here is a more complex example:

  We illustrate widening and shrinking using our "wedding simulator".
First let us define three classes, 'person' (for man and woman),
'married-woman' and 'married-man':
     (module wedding
        (static (final-class person
                    name::string
                    fname::string
                    (sex::symbol read-only))
                (wide-class married-man::person
                    mate::person)
                (wide-class married-woman::person
                    maiden-name::string
                    mate::person)))
  As we can see people are allowed to change their name but not their
sex.

  The identity of a person can be printed as
     (define-method (object-display p::person . op)
        (with-access::person p (name fname sex)
           (print "firstname : " fname)
           (print "name      : " name)
           (print "sex       : " sex)
           p))

  A married woman's identity is printed by (we suppose an equivalent
method definition for married-man)
     (define-method (object-display p::married-woman . op)
        (with-access::married-woman p (name fname sex mate)
           (call-next-method)
           (print "married to: " mate)
           p))

  We create a person with the 'birth' function:
     (define (birth name::string fname::string sex)
        [assert (sex) (memq sex '(male female))]
        (instantiate::person
           (name name)
           (fname fname)
           (sex sex)))

  We celebrate a wedding using the 'get-married!' function:
     (define (get-married! woman::person man::person)
        (if (not (and (eq? (-> woman sex) 'female)
                      (eq? (-> man sex) 'male)))
            (error "get-married"
                   "Illegal wedding"
                   (cons woman man))
            (let* ((mname (-> woman name))
                   (wife  (widen!::married-woman woman
                           (maiden-name mname)
                           (mate man))))
               (person-name-set! wife (-> man name))
               (widen!::married-man man
                  (mate woman)))))

  We can check if two people are married by
     (define (couple? woman::person man::person)
        (and (isa? woman married-woman)
             (isa? man married-man)
             (eq? (with-access::married-woman woman (mate) mate) man)
             (eq? (with-access::married-man man (mate) mate) woman)))

  Now let us study the life a 'Junior' 'Jones' and 'Pamela' 'Smith'.
Once upon a time...
     (define *junior* (birth "Jones" "Junior" 'male))
     (define *pamela* (birth "Smith" "Pamela" 'female))

  Later on, they met each other and ...  they got married:
     (define *old-boy-junior* *junior*)
     (define *old-girl-pamela* *pamela*)
     (get-married! *pamela* *junior*)

  This union can be checked:
     (couple? *pamela* *junior*)
        => #t

  We can look at the new identity of '*pamela*'
     (print *pamela*)
        -| name      : Jones
           firstname : Pamela
           sex       : FEMALE
           married to: Junior Jones

  But '*pamela*' and '*junior*' still are the same persons:
     (print (eq? *old-boy-junior* *junior*))   => #t
     (print (eq? *old-girl-pamela* *pamela*))  => #t

  Unfortunately all days are not happy days.  After having been married
'*pamela*' and '*junior*' have divorced:
     (define (divorce! woman::person man::person)
        (if (not (couple? woman man))
            (error "divorce!"
                   "Illegal divorce"
                   (cons woman man))
            (with-access::married-woman woman (maiden-name)
               (begin
                  (shrink! woman)
                  (set! (-> woman name) maiden-name))
               (shrink! man))))

     (divorce! *pamela* *junior*)

  We can look at the new identity of '*pamela*'
     (print *pamela*)
        -| name      : Smith
           firstname : Pamela
           sex       : FEMALE

  And '*pamela*' and '*junior*' still are the same persons:
     (print (eq? *old-boy-junior* *junior*))   => #t
     (print (eq? *old-girl-pamela* *pamela*))  => #t


File: bigloo.info,  Node: Object library,  Next: Object serialization,  Prev: Widening and shrinking,  Up: Object System

9.5 Object library
==================

9.5.1 Classes handling
----------------------

No type denotes Bigloo's classes.  These objects are handled by the
following library functions:

 -- bigloo procedure: find-class symbol
     Returns, if any, the class named SYMBOL.

 -- bigloo procedure: class? obj
     Returns '#t' if and only if OBJ is a class.

 -- bigloo procedure: class-super class
     Returns the _super-class_ of CLASS.

 -- bigloo procedure: class-subclasses class
     Returns the _subclasses_ of CLASS.

 -- bigloo procedure: class-name class
     Returns the name (a symbol) of CLASS.

 -- bigloo procedure: object-constructor class
     Returns CLASS's constructor.

 -- bigloo procedure: object-class object
     Returns the class that OBJECT belongs to.

9.5.2 Object handling
---------------------

 -- bigloo procedure: wide-object? object
     Returns '#t' if OBJECT is a wide object otherwise it returns '#f'.

 -- bigloo generic: object-display object [port]
     This generic function is invoked by 'display' to display objects.

 -- bigloo generic: object-write object [port]
     This generic function is invoked by 'write' to write objects.

 -- bigloo generic: object->struct object
 -- bigloo procedure: struct->object struct
     These functions converts objects into Scheme structures and
     vice-versa.

 -- bigloo generic: object-equal? object obj
     This generic function is invoked by 'equal?' when the first
     argument is an instance of 'object'.

 -- bigloo generic: object-hashnumber object
     This generic function returns an hash number of OBJECT.

 -- bigloo procedure: isa? obj class
     Returns '#t' if OBJ belongs to CLASS otherwise it returns '#f'.


File: bigloo.info,  Node: Object serialization,  Next: Equality,  Prev: Object library,  Up: Object System

9.6 Object serialization
========================

Objects can be _serialized_ and _un-serialized_ using the regular
'string->obj' and 'obj->string' functions.  Objects can be stored on
disk and restored from disk by the use of the 'output-obj' and
'input-obj' functions.

  In addition to this standard serialization mechanism, custom object
serializers and un-serializers can be specified by the means of the
'register-class-serialization!' function (see Section *note
Serialization::.


File: bigloo.info,  Node: Equality,  Next: Introspection,  Prev: Object serialization,  Up: Object System

9.7 Equality
============

Two objects can be compared with the 'equal?' function.  Two object are
equal if and only if they belong to a same class, all their field values
are equal and all their super class's field values are equal.


File: bigloo.info,  Node: Introspection,  Prev: Equality,  Up: Object System

9.8 Introspection
=================

Bigloo provides the programmer with some object introspection
facilities.  See section *note Object library:: for information on
classes and objects handling.  Introspection facilities are, by default,
available for all classes.  However, in order to shrink the code size
generation, it may be useful to disable class introspection.  This
decision can be taken on a per class basis (i.e., one class may be
provided with introspection facilities while another one is not).  The
compiler option '-fno-reflection' (see Chapter *note Compiler
Description::) prevents the compiler to generate the code required for
introspecting the classes defined in the compiled module.

 -- bigloo procedure: class-fields class
     Returns the a description of the fields of CLASS.  This description
     is a list of field descriptions where each field description can be
     accessed by the means of the following library functions.  The
     fields are those _directly_ defined in CLASS.  That is
     'class-fields' does not return fields defined in super classes of
     CLASS.

 -- bigloo procedure: class-all-fields class
     Returns the a description of the fields of CLASS.  This description
     is a list of field descriptions where each field description can be
     accessed by the means of the following library functions.  By
     contrast with 'class-fields', this function returns fields that are
     also defined in the super classes of CLASS.  in th

 -- bigloo procedure: find-class-field class symbol
     Returns the field named SYMBOL from class CLASS.  Returns '#f' is
     such a field does not exist.

 -- bigloo procedure: class-field? obj
     Returns #t if OBJ is a class field descriptor.  Otherwise returns
     #f.

 -- bigloo procedure: class-field-name field
     Returns the name of the FIELD.  The name is a symbol.

 -- bigloo procedure: class-field-accessor field
     Returns a procedure of one argument.  Applying this function to an
     object returns the value of the field described by FIELD.

 -- bigloo procedure: class-field-mutable? field
     Returns '#t' if the described field is mutable and '#f' otherwise.

 -- bigloo procedure: class-field-mutator field
     Returns a procedure of two arguments.  Applying this function to an
     object changes the value of the field described by FIELD.  It is an
     error to apply 'class-field-mutator' to an immutable field.

 -- bigloo procedure: class-field-info field
     Returns the information associated to FIELD (this the class
     declaration 'info' attribute).

  For means of an example, here is a possible implementation of the
'equal?' test for objects:

     (define (object-equal? obj1 obj2)
        (define (class-field-equal? fd)
           (let ((get-value (class-field-accessor fd)))
               (equal? (get-value obj1) (get-value obj2))))
        (let ((class1 (object-class obj1))
              (class2 (object-class obj2)))
           (cond
              ((not (eq? class1 class2))
               #f)
              (else
               (let loop ((fields (class-fields class1))
                          (class  class1))
                  (cond
                     ((null? fields)
                      (let ((super (class-super class)))
                         (if (class? super)
                             (loop (class-fields super)
                                   super)
                             #t)))
                     ((class-field-equal? (car fields))
                      (loop (cdr fields) class))
                     (else
                      #f)))))))

 -- bigloo procedure: class-creator class
     Returns the creator for CLASS.  The creator is a function for which
     the arity depends on the number of slots the class provides (see
     Section *note Creating and accessing objects::).

     When an instance is allocated by the means of the 'class-creator',
     as for direct instantiation, the class constructor is
     _automatically_ invoked.  Example:
          (module foo
             (main main)
             (static (class c1 (c1-constructor))))

          (define c1-constructor
             (let ((count 0))
                (lambda (inst)
          	 (set! count (+ 1 count))
          	 (print "creating instance: " count)
          	 inst)))

          (define (main argv)
             (let ((o1 (instantiate::c1))
          	 (o2 (instantiate::c1))
          	 (o3 ((class-creator c1))))
                'done))
             -| creating instance: 1
                creating instance: 2
                creating instance: 3

 -- bigloo procedure: class-predicate class
     Returns the predicate for CLASS.  This predicate returns '#t' when
     applied to object of type CLASS.  It returns '#f' otherwise.

