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

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

  Copyright (C) 1992-99, 2000-02 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.

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


File: bigloo.info,  Node: An Extended Example,  Prev: The Regular Expressions Pattern Language,  Up: Posix Regular Expressions

An Extended Example
-------------------

  Here's an extended example from Friedl that covers many of the
features described above.  The problem is to fashion a regexp that will
match any and only IP addresses or _dotted quads_, ie, four numbers
separated by three dots, with each number between 0 and 255.  We will
use the commenting mechanism to build the final regexp with clarity.
First, a subregexp `n0-255' that matches 0 through 255.

     (define n0-255
       "(?x:
       \\d          ;  0 through   9
       | \\d\\d     ; 00 through  99
       | [01]\\d\\d ;000 through 199
       | 2[0-4]\\d  ;200 through 249
       | 25[0-5]    ;250 through 255
       )")

  The first two alternates simply get all single- and double-digit
numbers.  Since 0-padding is allowed, we need to match both 1 and 01.
We need to be careful when getting 3-digit numbers, since numbers above
255 must be excluded.  So we fashion alternates to get 000 through 199,
then 200 through 249, and finally 250 through 255.(1) (*note An
Extended Example-Footnote-1::)

  An IP-address is a string that consists of four `n0-255's with three
dots separating them.

     (define ip-re1
       (string-append
         "^"        ;nothing before
         n0-255     ;the first n0-255,
         "(?x:"     ;then the subpattern of
         "\\."      ;a dot followed by
         n0-255     ;an n0-255,
         ")"        ;which is
         "{3}"      ;repeated exactly 3 times
         "$"        ;with nothing following
         ))

  Let's try it out.

     (pregexp-match ip-re1 "1.2.3.4")        => ("1.2.3.4")
     (pregexp-match ip-re1 "55.155.255.265") => #f

  which is fine, except that we also have

     (pregexp-match ip-re1 "0.00.000.00") => ("0.00.000.00")

  All-zero sequences are not valid IP addresses!  Lookahead to the
rescue.  Before starting to match `ip-re1', we look ahead to ensure we
don't have all zeros.  We could use positive lookahead to ensure there
_is_ a digit other than zero.

     (define ip-re
       (string-append
         "(?=.*[1-9])" ;ensure there's a non-0 digit
         ip-re1))

  Or we could use negative lookahead to ensure that what's ahead isn't
composed of _only_ zeros and dots.

     (define ip-re
       (string-append
         "(?![0.]*$)" ;not just zeros and dots
                      ;(note: dot is not metachar inside [])
         ip-re1))

  The regexp `ip-re' will match all and only valid IP addresses.

     (pregexp-match ip-re "1.2.3.4") => ("1.2.3.4")
     (pregexp-match ip-re "0.0.0.0") => #f


File: bigloo.info,  Node: An Extended Example-Footnotes,  Up: An Extended Example

  (1) Note that `n0-255' lists prefixes as preferred alternates,
something we cautioned against in section *Note Alternation::. However,
since we intend to anchor this subregexp explicitly to force an overall
match, the order of the alternates does not matter.


File: bigloo.info,  Node: Pattern Matching,  Next: Object System,  Prev: Standard Library,  Up: Top

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 or structures.


* 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

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

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.

Explanations through examples
.............................

   * `?-' 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 `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: Object System,  Next: Threads,  Prev: Pattern Matching,  Up: Top

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

Class declaration
=================

  Classes are defined in a module declaration. 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:

     <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>`)'
          | `('<ident> <field-prop>`)'
          | `(*' <ident> <field-prop>`)'
     <len> ==> <fixnum> | <string>
     <field-prop> ==> `read-only'
          | `(get' <bigloo-exp>`)'
          | `(set' <bigloo-exp>`)'
          | `(default' <bigloo-exp>`)'
          | `(info' <bigloo-exp>`)'

  A class is a Bigloo type 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_ can only inherit from _final classes_.  _abstract classes_
can't be instantiated.

  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 is 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.

  A class field defined as `(* ...)' is an indexed field and holds a
sequence of items. The length of this sequence is defined at allocation
time.

  Field marked with `read-only' declaration are immutables.

  `Default' declarations allow default field values. For indexed
fields, the default value is the default value of each element of the
sequence.

  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 indexed fields, final and wide classes by the example:
     (module example
        (export (final-class person
                    (name::string (default "Jones"))
                    (sex read-only)
                    (* children::person))
                (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 relies on
invocation to 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. Virtual fields may
not be indexed fields. 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

Creating and accessing objects
==============================

  Bigloo automatically creates functions to allocate and manipulate
objects.  Let us suppose the class declaration:
     (class CLASS
        FIELD1::TYPE1
        (* FIELD2::TYPE2))

  Theses functions are:
   * A creator:
          (make-CLASS::CLASS ::TYPE1 ::long ::TYPE2 ::TYPE3)

     This function allocates a fresh instance of CLASS and fills the
     field values with the argument. The length of the indexed field
     FIELD2 is given as argument of the function.

     Example:
          (class truc
             x::char
             (* y::bstring))

     The prototype of the allocation function is:
          (make-truc::truc x::char
                           y-len::long
                           y::bstring)

     The indexed values of the `y' and `z' fields will be set to the
     values of the formal parameters `y' and `z' respectively.

   * A filler:
          (fill-CLASS! ::CLASS ::TYPE1 ::long ::TYPE2 ::TYPE3)

     This function accepts the same arguments as the creator augmented
     with one allocated instance. This instance is filled up with the
     provided values.

   * A type checker:
          (CLASS?::bool OBJ::obj)

     This function returns `#t' if OBJ is an instance of CLASS or an
     instance of a sub-class of CLASS, otherwise, it returns `#f'.

   * Accessors and mutators:
          (CLASS-FIELD_1::TYPE_1 ::CLASS)
          (CLASS-FIELD_1-set!::obj ::CLASS ::TYPE_1)
          (CLASS-FIELD_2-len::long ::CLASS)
          (CLASS-FIELD_2-ref::TYPE_2 ::CLASS ::long)
          (CLASS-FIELD_2-set!::obj ::CLASS ::long ::TYPE_2)

     Declaring a field `read-only' prevents Bigloo from generating an
     associated `CLASS-FIELD_I-set!' function. The length of the
     indexed field is ` read-only'. Thus they do not have mutator
     functions.


  Some syntax helps with allocation and access to objects.

 - bigloo syntax: with-access::CLASS obj (ident...) body
     A reference to any of the variables named IDENT is replaced by the
     appropriate field access form. This is true for both reference and
     assignment.  For instance:
          (with-access::point p (x y)
             (set! x (- x))
             (set! y (- y)))
          is equivalent to:
          (begin
             (point-x-set! p (- (point-x p)))
             (point-y-set! p (- (point-y p))))

     When an indexed field is referenced inside the binding part of a
     `with-access' form, the functions that accesses and changes the
     fields are bound inside the body of the `with-access'. In addition,
     a variable reporting the length of the field is also bound. For a
     field FD, the getter function is `(FD-ref OFFSET)', the setter is
     `(FD-set! OFFSET VALUE)', the length variable is `FD-len'.  For
     instance:
          (with-access::truc o (y)
             (print "length: " y-len)
             (print "old y-ref(0): " (y-ref 0))
             (y-set! 0 "foo")
             (print "new y-ref(0): " (y-ref 0)))
          is equivalent to:
          (begin
             (print "length: " (truc-y-len o))
             (print "old y-ref(0): " (truc-y-ref o 0))
             (truc-y-set! o 0 "foo")
             (print "new y-ref(0): " (truc-y-ref o 0)))


 - 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:
          (make-point 0 0)
     is equivalent to:
          (instantiate::point (x 0) (y 0))

     Indexed field must be provided with exactly two values. The first
     is the length of the indexed field and the second is the default
     value of each element of the indexed field.

 - bigloo syntax: co-instantiate ((VAR VALUE) ...) body
     This form 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))))
             (+ (c2-x (c1-o2 o1)) (c2-y (c1-o2 x))))
                                                 => 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)
             (make-point x 10))
     is equivalent to:
          (duplicate::point old (y 10))

     Indexed field must be provided with exactly two values. The first
     is the length of the indexed field and the second is the default
     value of each element of the indexed field.

     Here is an example of creations and mutations of a complex object:
          (module foo
             (export (class named-tab
                        name::string
                        (* els::int))))
          
          ;; a function than print a named-tab
          (define (print-tab tab)
             (display* (named-tab-name tab) ": ")
             (let loop ((i (-fx (named-tab-els-len tab) 1)))
                (if (=fx i -1)
                    (newline)
                    (begin
                       (display* #\( i
                                 " "
                                 (named-tab-els-ref tab i)
                                 ") ")
                       (loop (-fx i 1))))))
          
          ;; we allocate a named-tab object with
          ;; 5 els, each of them initialized to 0
          (define a-tab (instantiate::named-tab
                           (name "example")
                           (els 5 0)))
          
          ;; we print its elements
          (print-tab a-tab)
          
          ;; we change the values of the indexed field
          ;; els by setting values from 0 to 10
          (let loop ((i (-fx (named-tab-els-len a-tab) 1)))
             (if (=fx i -1)
                 'done
                 (begin
                    (named-tab-els-set! a-tab i i)
                    (loop (-fx i 1)))))
          
          ;; we re-print it
          (print-tab a-tab)

     This will produce the following output:
          example: (4 0) (3 0) (2 0) (1 0) (0 0)
          example: (4 4) (3 3) (2 2) (1 1) (0 0)


File: bigloo.info,  Node: Generic functions,  Next: Widening and shrinking,  Prev: Creating and accessing objects,  Up: Object System

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
     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 p "firstname : " (person-fname p))
           (fprint p "name      : " (person-name p))
           (fprint p "sex       : " (person-sex p))
           p))


File: bigloo.info,  Node: Widening and shrinking,  Next: Object library,  Prev: Generic functions,  Up: Object System

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 (named? *point*))           ==> #t
     (print (named-point? *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 (named-point? n-point))  ==> #t
     (print (named? n-point))        ==> #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 (named-point? *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: " (person-fname mate)
                                 " "
                                 (person-name 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? (person-sex woman) 'female)
                      (eq? (person-sex man) 'male)))
            (error "get-married"
                   "Illegal wedding"
                   (cons woman man))
            (let* ((mname (person-name woman))
                   (wife  (widen!::married-woman woman
                           (maiden-name mname)
                           (mate man))))
               (person-name-set! wife (person-name man))
               (widen!::married-man man
                  (mate woman)))))

  We can check if two people are married by
     (define (couple? woman::person man::person)
        (and (married-woman? woman)
             (married-man? man)
             (eq? (married-woman-mate woman) man)
             (eq? (married-man-mate man) 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))
            (let ((mname (married-woman-maiden-name
                           woman)))
               (begin
                  (shrink! woman)
                  (person-name-set! woman mname))
               (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

Object library
==============

Classes handling
----------------

  No type denotes Bigloo's classes. These objects are handled by the
following library functions:

 - 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.

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: is-a? 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

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.


File: bigloo.info,  Node: Equality,  Next: Introspection,  Prev: Object serialization,  Up: Object System

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

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-indexed? field
     Returns `#t' if the described field is indexed and `#f' otherwise.

 - 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-len-accessor field
     A one argument function is returned. Applying this function to an
     object returns the length value of the field described by field.
     It is an error to apply `class-field-len-accessor' to a
     non-indexed 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 three, or two, arguments depending on
     whether the field is indexed or not. 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)))
              (if (not (class-field-indexed? fd))
                  (equal? (get-value obj1)
                          (get-value obj2))
                  (let* ((len (class-field-len-accessor
                               fd)))
                         (len1 (len obj1))
                         (len2 (len obj2)))
                     (and (=fx len1 len2)
                          (let loop ((i 0))
                             (cond
                                ((=fx i len1)
                                 #t)
                                ((equal?
                                  (get-value obj1 i)
                                  (get-value obj2 i))
                                 (loop (+fx i 1)))
                                (else
                                 #f))))))))
        (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

     For each indexed field, two values must be sent to the function
     returned by `class-creator'. The first value denotes the size of
     the indexed field. The second value denote the initial values of
     the fields. For instance:
          (module example
             (export (class point x y (* z))))
          
          (let ((create (class-creator point)))
             (print (create 10 23 5 3)))

     Produces   -| #|POINT [X: 10] [Y: 23] [Z: 3 3 3 3 3]|


File: bigloo.info,  Node: Threads,  Next: Regular Parsing,  Prev: Object System,  Up: Top

Threads
*******

  Bigloo supports fair threads (see Section *Note Thread::), a
specification of cooperative threads. In this framework a thread must
explicitly or implicitly _yield_ the processor to the scheduler (see
Section *Note Scheduler::). Explicit cooperation is achieved by library
functions such as `thread-yield!' or `thread-sleep!'.  Implicit
cooperation is achieved by forms such as `(thread-await!
(make-input-signal p '(#\Newline)))' that blocks the current thread
until the character `#\Newline' is read on input port P. The scheduler
does not preempt a running thread to allocate the processor to another
waiting thread. Fair threads have two drawbacks over preemptive threads:

   * Cooperative threads are not skilled to benefit of multi processors
          platforms.

   * Single threads programs must be adapted in order to be ran
     concurrently.

  On the other hand, Fair threads have advantages that make them
suitable for a high level programming language such as Scheme:

   * Fair threads have a strong and well defined semantic. Multi
     threaded       programs using Fair threads are _deterministic_
     thus programs       that deploy Fair threads are _predictable_.

   * Fair threads are easier to program with because they hide most the
          of the concurrent programming pitfalls. In particular, since
     Fair       threads enforce a strong synchronization, there
     is no need to deploy techniques such as _mutex_, _semaphore_
     or _condition variables_.

* Menu:

* Introduction::
* Programming with Fair threads::
* Fair Threads Api::
* SRFI-18::

  This whole chapter has been written in collaboration with Frédéric
Boussinot. It uses materials on Fair threads that can be found at
<http://www-sop.inria.fr/mimosa/rp/FairThreads/html/FairThreads.html>.


File: bigloo.info,  Node: Introduction,  Next: Programming with Fair threads,  Up: Threads

Introduction to Fair Threads
============================

  Fair threads are cooperative threads run by a fair scheduler which
gives them equal access to the processor. Fair threads can communicate
using broadcast events. Their semantics does not depends on the
executing platform. Fine control over fair threads execution is
possible allowing the programming of specific user-defined scheduling
strategies.

  Contrary to standard sequential programming where the processor
executes a single program, in concurrent programming the processor is a
shared resource which is dispatched to several programs. The term
_concurrent_ is appropriate because programs can be seen as
concurrently competing to gain access to the processor, in order to
execute.

  Threads are a basic mean for concurrent programming, and are widely
used in operating systems. At language level, threads offer a way to
structure programs by decomposing systems in several concurrent
components; in this respect, threads are useful for modularity.

  However, threads are generally considered as low-level primitives
leading to over-complex programming. Moreover, threads generally have
loose semantics, in particular depending on the underlying executing
platform; to give them a precise semantics is a difficult task, and
this is a clearly identified problem to get portable code.

  Bigloo proposes a new framework with clear and simple semantics, and
with an efficient implementation. In it, threads are called _fair_;
basically a fair thread is a cooperative thread executed in a context
in which all threads always have equal access to the processor. Fair
threads have a deterministic semantics, relying on previous work
belonging to the so-called reactive approach.

