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.

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

Version history
===============

0.1
     Initial release

Requirements
============

This egg requires the following extensions:

lookup-table, syntax-case, misc-extn

Usage
=====

Load this egg like so:

(require-extension procedure-surface)

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

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

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.

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.

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

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.