procedure-surface egg
*********************

Generic Programming Support

Written by Kon Lovett

   This manual corresponds to version 0.1 of the procedure-surface
extension library for Chicken Scheme.

1 About this egg
****************

1.1 Version history
===================

`0.1'
     Initial release

1.2 Requirements
================

This egg requires the following extensions:

   `lookup-table', `syntax-case', `misc-extn'

1.3 Usage
=========

Load this egg like so:

   `(require-extension procedure-surface)'

2 Documentation
***************

Warning - procedure surface is experimental!

   The procedure-surface egg provides a facility for generic
programming in Scheme, similar in purpose to the "structures"
egg. Unlike the normal pattern of use for "structures" this
facility will delay loading of any library or extension until an 			actual
binding is required. The use of a 'define' form as a 			procedure
reference with 'make-procedure-means' is not 			supported, unlike
the analogous 'structure' from "structures".

   Odd names are used for parsimony. Read 'interface' for
'surface', and 'implementation' for 'means'.

2.1 Syntax Interface
====================

 -- macro: define-procedure-surface
          (define-procedure-surface NAME PROC-SYM CONTRACT ... [KEY-ARG ...])

     Sets the symbol `NAME' to the described procedure 					surface. Uses
     `NAME' as the keyword argument #:name 					for the surface. See
     'make-procedure-surface' for argument 					descriptions.

 -- macro: declare-procedure-means
          (declare-procedure-means NAME SURFACE PROC-SYM PROC-REF ... [KEY-ARG ...])

     Sets the symbol `NAME' to the described procedure 					surface means.
     See 'make-procedure-means' for 					argument descriptions.

 -- macro: call-thru-procedure-means
          (call-thru-procedure-means MEANS PROC-SYM [ARG ...])

     Invoke the procedure identified by `PROC-SYM' in 					the `MEANS' with
     the `ARG ...' list.

 -- macro: apply-thru-procedure-means
          (apply-thru-procedure-means MEANS PROC-SYM ARG ...)

     Apply the procedure identified by `PROC-SYM' in 					the `MEANS' to the
     `ARG ...' list.

 -- macro: let-procedure-means
          (let-procedure-means ([(PROC-SYM ...) MEANS] ...) BODY ...)

     Bind the local symbol(s) `PROC-SYM ...' to the 					corresponding
     procedure(s) in the `MEANS' and 					evaluate the `BODY'.

 -- macro: call/means
          (call/means MEANS PROC-SYM [ARG ...])

     Abbreviation of 'call-thru-procedure-means'.

 -- macro: apply/means
          (apply/means MEANS PROC-SYM ARG ...)

     Abbreviation of 'apply-thru-procedure-means'.

 -- macro: let/means
          (let/means ([(PROC-SYM ...) MEANS] ...) BODY ...)

     Abbreviation of 'let-procedure-means'.

2.2 Direct Call Interface
=========================

 -- procedure: make-procedure-signature
          (make-procedure-signature IDENTIFIER CONTRACT)

     Returns a procedure signature for `IDENTIFIER' 					with `CONTRACT'.

     The contract grammar is described below. Can be null, '(), 					for no
     contract.

 -- procedure: procedure-signature?
          (procedure-signature? OBJECT)

     Is `OBJECT' a procedure signature?

 -- procedure: procedure-signature-identifier
          (procedure-signature-identifier SIGNATURE)

     Returns the procedure signature identifier of the `SIGNATURE'.

 -- procedure: procedure-signature-contract
          (procedure-signature-contract SIGNATURE)

     Returns the procedure signature contract of the `SIGNATURE'.

 -- procedure: make-procedure-surface
          (make-procedure-surface PROC-SYM CONTRACT ... [#:immutable #f] [#:name #f])

     Creates and returns a procedure surface. A collection of
     procedure identifiers and contracts.

    `immutable:'
          A boolean. Immutable (#t) or mutable (#f).

    `name:'
          A symbol or string. The name of the surface. When missing 							a
          name of the form "ps#" will be created.

    `PROC-SYM'
          A symbol. The procedure identifier.

    `CONTRACT'
          A list. The source form of a procedure signature. The
          contract grammar is described below. null, '(), for no
          contract.

 -- procedure: procedure-surface?
          (procedure-surface? OBJECT)

     Is the `OBJECT' a procedure surface?

 -- procedure: procedure-surface-name
          (procedure-surface-name SURFACE)

     Returns the name, or names as list if composite, of the `SURFACE'.

 -- procedure: procedure-surface-immutable?
          (procedure-surface-immutable? SURFACE)

     Is the `SURFACE' immutable?

 -- procedure: procedure-surface-mutable?
          (procedure-surface-mutable? SURFACE)

     Is the `SURFACE' mutable?

 -- procedure: procedure-surface-ref
          (procedure-surface-ref SURFACE PROC-SYM)

     Returns the procedure signature of the `SURFACE'.

 -- procedure: procedure-surface-set!
          (procedure-surface-set! SURFACE PROC-SYM CONTRACT ...)

     Adds or updates procedure signatures in `SURFACE'.

 -- procedure: procedure-surface-delete!
          (procedure-surface-delete! SURFACE PROC-SYM)

     Removes the procedure signature for `PROC-SYM' 					from `SURFACE'.

 -- procedure: procedure-surface->alist
          (procedure-surface->alist SURFACE)

     Returns a alist, (<procedure-symbol> .
     <procedure-signature>), from `SURFACE'.

 -- procedure: make-composite-procedure-surface
          (make-composite-procedure-surface SURFACE ...)

     Returns a procedure surface, the combination of `SURFACE ...' set.
     Should any surface be immutable then the 					composite is
     immutable.

 -- procedure: composite-procedure-surface?
          (composite-procedure-surface? SURFACE)

     Is the `SURFACE' a composite?

 -- procedure: make-procedure-means
          (make-procedure-means SURFACE PROC-SYM PROC-REF ... [#:immutable #f] [#:extension #f] [#:library #f] [#:pathname #f])

     Supply procedures for the `SURFACE'.

    `immutable:'
          A boolean. Immutable (#t) or mutable (#f).

    `extension:'
          A symbol or string. The name of the extension.

    `library:'
          A symbol or string. The name of the library.

    `pathname:'
          A string. The absolute pathname of the extension or library.
          Required when the extension or library is not in the
          Chicken repository.

    `PROC-SYM'
          A symbol. The procedure identifier. Must match a
          procedure identifier from SURFACE.

    `PROC-REF'
          A boolean, symbol, or procedure. The procedure alias when 							a
          symbol. When boolean use the procedure identifier as the
          alias. Otherwise this should be a procedure.

 -- procedure: procedure-means?
          (procedure-means? OBJECT)

     Is the `OBJECT' a procedure surface?

 -- procedure: procedure-means-immutable?
          (procedure-means-immutable? MEANS)

     Are the `MEANS' immutable?

 -- procedure: procedure-means-mutable?
          (procedure-means-mutable? MEANS)

     Are the `MEANS' mutable?

 -- procedure: procedure-means-alias
          (procedure-means-alias MEANS PROC-SYM)

     Returns the alias of `PROC-SYM' in `MEANS'.

 -- procedure: procedure-means-ref
          (procedure-means-ref MEANS PROC-SYM)

     Returns the current binding of `PROC-SYM' in the 					`MEANS', which
     maybe the unbound value.

 -- procedure: procedure-means-closure
          (procedure-means-closure MEANS PROC-SYM)

     Forces a load, if necessary. Returns the current binding
     of `PROC-SYM' in the `MEANS', which maybe 					the unbound
     value.

 -- procedure: procedure-means-implements
          (procedure-means-implements MEANS)

     Returns the procedure surface, or a list of procedure
     surface when composite, that the `MEANS' 					implements.

 -- procedure: procedure-means-complete?
          (procedure-means-complete? MEANS)

     Are all procedures in the procedure surface(s) of the `MEANS'
     declared?

 -- procedure: procedure-means-bound?
          (procedure-means-bound? MEANS)

     Are all the procedures in the `MEANS' bound?

 -- procedure: procedure-means-incompletes
          (procedure-means-incompletes MEANS)

     Returns an alist, (<procedure identifier> . <procedure
     surface>), of all procedures in the procedure surface(s) of 					the
     `MEANS ...' that are undeclared.

 -- procedure: procedure-means-unbounds
          (procedure-means-unbounds MEANS)

     Returns an alist, (<procedure-symbol> .
     <procedure-surface>), of all the unbound procedures in `MEANS'.

 -- procedure: procedure-means-incomplete-closure?
          (procedure-means-incomplete-closure? MEANS PROC-SYM)

     Is the procedure identified by `PROC-SYM' without 					a declaration in
     the `MEANS'?

 -- procedure: procedure-means->alist
          (procedure-means->alist MEANS)

     Returns an alist, (<procedure-symbol> .
     <procedure-alias/closure), from the `MEANS'.

 -- procedure: procedure-means-set!
          (procedure-means-set! MEANS PROC-SYM PROC-REF ...)

     Adds or updates procedures for an existing `MEANS'.

 -- procedure: procedure-means-delete!
          (procedure-means-delete! MEANS PROC-SYM)

     Removes the procedure `PROC-SYM' from the `MEANS'.

 -- procedure: procedure-means-load!
          (procedure-means-load! MEANS)

     Load of any libraries and extensions required by the `MEANS'.

 -- procedure: make-composite-procedure-means
          (make-composite-procedure-means MEANS ...)

     Returns a procedure means, the combination of `MEANS ...' set.
     Should any means be immutable then the 					composite is
     immutable.

 -- procedure: composite-procedure-means?
          (composite-procedure-means? MEANS)

     Are the `MEANS' a composite?

 -- procedure: procedure-unbound?
          (procedure-unbound? PROCEDURE)

     Is this surface means procedure loaded?

 -- procedure: procedure-identifier->closure
          (procedure-identifier->closure SYMBOL)

     Returns the top level binding, if any, for the procedure
     named `SYMBOL'.

2.3 Signature Types
===================

The signature type system supports multiple-inheritance, via
the 'extends' property.

 -- procedure: build-signature-type-builtins
          (build-signature-type-builtins)

     Creates all the builtin types.

 -- procedure: make-signature-type
          (make-signature-type NAME #!optional (EXTENDS #f) (PREDICATE #f) (SPECIALIZER #f))

     Creates a new signature type object.

    `NAME'
          A symbol. The name of the new type.

    `EXTENDS'
          A symbol or list. The type(s) that the new type is
          extending.

    `PREDICATE'
          A procedure. Determines whether an arbitrary object is a
          value of the new type.

    `SPECIALIZER'
          A procedure. Determines whether a specialization for the 							new
          type is valid.

 -- procedure: signature-type?
          (signature-type? OBJECT)

     Is `OBJECT' a signature type?

 -- procedure: signature-extended-type?
          (signature-extended-type? TYPE/NAME)

     Does a type extend `TYPE/NAME'.

 -- procedure: signature-leaf-type?
          (signature-leaf-type? TYPE/NAME)

     Does `TYPE/NAME' not extend a type?

 -- procedure: signature-type-a-kind-of?
          (signature-type-a-kind-of? TYPE/NAME-SUB TYPE/NAME-SUPER)

     Does `TYPE/NAME-SUB' extend `TYPE/NAME-SUPER'?

     The most distant ancestor of all Scheme types is 'object'.
     However, roots are not considered when determining the kind of
     relationship from an intermediate type. So to check if a type 					is a
     kind of 'object' do so directly.

 -- procedure: signature-type-ref
          (signature-type-ref NAME)

     Returns the signature type for `NAME'.

 -- procedure: signature-type-name
          (signature-type-name TYPE)

     Returns the name of `TYPE'.

 -- procedure: signature-type-predicate
          (signature-type-predicate TYPE/NAME)

     Returns the predicate for `TYPE/NAME'.

 -- procedure: signature-type-specializer
          (signature-type-specializer TYPE/NAME)

     Returns the specializer for `TYPE/NAME'.

 -- procedure: signature-type-extends
          (signature-type-extends TYPE/NAME)

     Return a list of the types that `TYPE/NAME' extends.

 -- procedure: signature-type-extension
          (signature-type-extension TYPE/NAME)

     Return a list of the types that extend `TYPE/NAME'.

 -- procedure: signature-type-delete!
          (signature-type-delete! TYPE/NAME)

     Remove the `TYPE/NAME'.

 -- procedure: signature-type-replace!
          (signature-type-replace! TYPE/NAME #!optional (NEW-NAME #f) (EXTENDS #f) (PREDICATE #f) (SPECIALIZER #f))

     Replace the existing `TYPE/NAME' with a new 					definition.

 -- procedure: make-signature-contract
          (make-signature-contract CONTRACT)

     Validates the source form of a contract and returns the internal
     form.

2.4 Procedure Signature Grammar
===============================

`contract'
     <map> | (or <map> ...)

`type'
     <symbol> | <specialization>

`specialization'
     <map> | (<type> [<parameter> ...]) | (or <type> ...)

`parameter'
     <object>

`domain'
     [<type> ...] [#!optional <type> ...] [#!rest 						list | (list <type>
     ...)] [#!key (<keyword> <type>) ...]

`range'
     <type> | (values <type> ...)

`map'
     (-> <domain> <range> [<throw> ...])

`throw'
     (signals <exception> ...) | (aborts <exception> ...)

`exception'
     <symbol> | (<symbol> ...)

   A <map> is a specialization of '->', the type of a 				procedure.

   '()' is a synonym of 'null' for this grammar.

   Example: (-> (array (rank 2)) object (values integer complex 				vector
object)) - a procedure (<map>) taking a matrix & any 				object, returning
4 multiple values.

   Builtin Types

   * object

   * void

   * structure

   * boolean

   * symbol

   * keyword

   * char

   * string

   * vector

   * list

   * pair

   * null

   * port

   * input-port

   * output-port

   * eof

   * procedure

   * macro

   * continuation

   * promise

   * environment

   * read-table

   * hash-table

   * queue

   * condition

   * number

   * exact

   * inexact

   * real

   * integer

   * fixnum

   * flonum

   * rational

   * complex

   * u8vector

   * s8vector

   * u16vector

   * s16vector

   * u32vector

   * s32vector

   * f32vector

   * f64vector

   * char-set

   * mmap

   * terminal-port

   * tcp-listener

   * thread

   * lock

   * mutex

   * condition-variable

   * time

   * regexp

   * pointer

   * tagged-pointer

   * swig-pointer

   * locative

   * byte-vector

   * extended-procedure

   * object-evicted

   * record

   * clos-object

   * class

   * method

   * generic

   * c++-object

   * date

   * array

   * future

3 License
*********

Copyright (c) 2006, Kon Lovett.  All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the Software),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.