diff options
Diffstat (limited to 'slib.info-3')
-rw-r--r-- | slib.info-3 | 859 |
1 files changed, 0 insertions, 859 deletions
diff --git a/slib.info-3 b/slib.info-3 deleted file mode 100644 index 7109890..0000000 --- a/slib.info-3 +++ /dev/null @@ -1,859 +0,0 @@ -This is Info file slib.info, produced by Makeinfo-1.64 from the input -file slib.texi. - - This file documents SLIB, the portable Scheme library. - - Copyright (C) 1993 Todd R. Eigenschink Copyright (C) 1993, 1994, 1995 -Aubrey Jaffer - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be stated in a -translation approved by the author. - - -File: slib.info, Node: Weight-Balanced Trees, Next: Structures, Prev: Relational Database, Up: Data Structures - -Weight-Balanced Trees -===================== - - `(require 'wt-tree)' - - Balanced binary trees are a useful data structure for maintaining -large sets of ordered objects or sets of associations whose keys are -ordered. MIT Scheme has an comprehensive implementation of -weight-balanced binary trees which has several advantages over the -other data structures for large aggregates: - - * In addition to the usual element-level operations like insertion, - deletion and lookup, there is a full complement of collection-level - operations, like set intersection, set union and subset test, all - of which are implemented with good orders of growth in time and - space. This makes weight balanced trees ideal for rapid - prototyping of functionally derived specifications. - - * An element in a tree may be indexed by its position under the - ordering of the keys, and the ordinal position of an element may - be determined, both with reasonable efficiency. - - * Operations to find and remove minimum element make weight balanced - trees simple to use for priority queues. - - * The implementation is *functional* rather than *imperative*. This - means that operations like `inserting' an association in a tree do - not destroy the old tree, in much the same way that `(+ 1 x)' - modifies neither the constant 1 nor the value bound to `x'. The - trees are referentially transparent thus the programmer need not - worry about copying the trees. Referential transparency allows - space efficiency to be achieved by sharing subtrees. - - These features make weight-balanced trees suitable for a wide range of -applications, especially those that require large numbers of sets or -discrete maps. Applications that have a few global databases and/or -concentrate on element-level operations like insertion and lookup are -probably better off using hash-tables or red-black trees. - - The *size* of a tree is the number of associations that it contains. -Weight balanced binary trees are balanced to keep the sizes of the -subtrees of each node within a constant factor of each other. This -ensures logarithmic times for single-path operations (like lookup and -insertion). A weight balanced tree takes space that is proportional to -the number of associations in the tree. For the current -implementation, the constant of proportionality is six words per -association. - - Weight balanced trees can be used as an implementation for either -discrete sets or discrete maps (associations). Sets are implemented by -ignoring the datum that is associated with the key. Under this scheme -if an associations exists in the tree this indicates that the key of the -association is a member of the set. Typically a value such as `()', -`#t' or `#f' is associated with the key. - - Many operations can be viewed as computing a result that, depending on -whether the tree arguments are thought of as sets or maps, is known by -two different names. An example is `wt-tree/member?', which, when -regarding the tree argument as a set, computes the set membership -operation, but, when regarding the tree as a discrete map, -`wt-tree/member?' is the predicate testing if the map is defined at an -element in its domain. Most names in this package have been chosen -based on interpreting the trees as sets, hence the name -`wt-tree/member?' rather than `wt-tree/defined-at?'. - - The weight balanced tree implementation is a run-time-loadable option. -To use weight balanced trees, execute - - (load-option 'wt-tree) - -once before calling any of the procedures defined here. - -* Menu: - -* Construction of Weight-Balanced Trees:: -* Basic Operations on Weight-Balanced Trees:: -* Advanced Operations on Weight-Balanced Trees:: -* Indexing Operations on Weight-Balanced Trees:: - - -File: slib.info, Node: Construction of Weight-Balanced Trees, Next: Basic Operations on Weight-Balanced Trees, Prev: Weight-Balanced Trees, Up: Weight-Balanced Trees - -Construction of Weight-Balanced Trees -------------------------------------- - - Binary trees require there to be a total order on the keys used to -arrange the elements in the tree. Weight balanced trees are organized -by *types*, where the type is an object encapsulating the ordering -relation. Creating a tree is a two-stage process. First a tree type -must be created from the predicate which gives the ordering. The tree -type is then used for making trees, either empty or singleton trees or -trees from other aggregate structures like association lists. Once -created, a tree `knows' its type and the type is used to test -compatibility between trees in operations taking two trees. Usually a -small number of tree types are created at the beginning of a program -and used many times throughout the program's execution. - - - procedure+: make-wt-tree-type KEY<? - This procedure creates and returns a new tree type based on the - ordering predicate KEY<?. KEY<? must be a total ordering, having - the property that for all key values `a', `b' and `c': - - (key<? a a) => #f - (and (key<? a b) (key<? b a)) => #f - (if (and (key<? a b) (key<? b c)) - (key<? a c) - #t) => #t - - Two key values are assumed to be equal if neither is less than the - other by KEY<?. - - Each call to `make-wt-tree-type' returns a distinct value, and - trees are only compatible if their tree types are `eq?'. A - consequence is that trees that are intended to be used in binary - tree operations must all be created with a tree type originating - from the same call to `make-wt-tree-type'. - - - variable+: number-wt-type - A standard tree type for trees with numeric keys. `Number-wt-type' - could have been defined by - - (define number-wt-type (make-wt-tree-type <)) - - - variable+: string-wt-type - A standard tree type for trees with string keys. `String-wt-type' - could have been defined by - - (define string-wt-type (make-wt-tree-type string<?)) - - - procedure+: make-wt-tree WT-TREE-TYPE - This procedure creates and returns a newly allocated weight - balanced tree. The tree is empty, i.e. it contains no - associations. WT-TREE-TYPE is a weight balanced tree type - obtained by calling `make-wt-tree-type'; the returned tree has - this type. - - - procedure+: singleton-wt-tree WT-TREE-TYPE KEY DATUM - This procedure creates and returns a newly allocated weight - balanced tree. The tree contains a single association, that of - DATUM with KEY. WT-TREE-TYPE is a weight balanced tree type - obtained by calling `make-wt-tree-type'; the returned tree has - this type. - - - procedure+: alist->wt-tree TREE-TYPE ALIST - Returns a newly allocated weight-balanced tree that contains the - same associations as ALIST. This procedure is equivalent to: - - (lambda (type alist) - (let ((tree (make-wt-tree type))) - (for-each (lambda (association) - (wt-tree/add! tree - (car association) - (cdr association))) - alist) - tree)) - - -File: slib.info, Node: Basic Operations on Weight-Balanced Trees, Next: Advanced Operations on Weight-Balanced Trees, Prev: Construction of Weight-Balanced Trees, Up: Weight-Balanced Trees - -Basic Operations on Weight-Balanced Trees ------------------------------------------ - - This section describes the basic tree operations on weight balanced -trees. These operations are the usual tree operations for insertion, -deletion and lookup, some predicates and a procedure for determining the -number of associations in a tree. - - - procedure+: wt-tree? OBJECT - Returns `#t' if OBJECT is a weight-balanced tree, otherwise - returns `#f'. - - - procedure+: wt-tree/empty? WT-TREE - Returns `#t' if WT-TREE contains no associations, otherwise - returns `#f'. - - - procedure+: wt-tree/size WT-TREE - Returns the number of associations in WT-TREE, an exact - non-negative integer. This operation takes constant time. - - - procedure+: wt-tree/add WT-TREE KEY DATUM - Returns a new tree containing all the associations in WT-TREE and - the association of DATUM with KEY. If WT-TREE already had an - association for KEY, the new association overrides the old. The - average and worst-case times required by this operation are - proportional to the logarithm of the number of associations in - WT-TREE. - - - procedure+: wt-tree/add! WT-TREE KEY DATUM - Associates DATUM with KEY in WT-TREE and returns an unspecified - value. If WT-TREE already has an association for KEY, that - association is replaced. The average and worst-case times - required by this operation are proportional to the logarithm of - the number of associations in WT-TREE. - - - procedure+: wt-tree/member? KEY WT-TREE - Returns `#t' if WT-TREE contains an association for KEY, otherwise - returns `#f'. The average and worst-case times required by this - operation are proportional to the logarithm of the number of - associations in WT-TREE. - - - procedure+: wt-tree/lookup WT-TREE KEY DEFAULT - Returns the datum associated with KEY in WT-TREE. If WT-TREE - doesn't contain an association for KEY, DEFAULT is returned. The - average and worst-case times required by this operation are - proportional to the logarithm of the number of associations in - WT-TREE. - - - procedure+: wt-tree/delete WT-TREE KEY - Returns a new tree containing all the associations in WT-TREE, - except that if WT-TREE contains an association for KEY, it is - removed from the result. The average and worst-case times required - by this operation are proportional to the logarithm of the number - of associations in WT-TREE. - - - procedure+: wt-tree/delete! WT-TREE KEY - If WT-TREE contains an association for KEY the association is - removed. Returns an unspecified value. The average and worst-case - times required by this operation are proportional to the logarithm - of the number of associations in WT-TREE. - - -File: slib.info, Node: Advanced Operations on Weight-Balanced Trees, Next: Indexing Operations on Weight-Balanced Trees, Prev: Basic Operations on Weight-Balanced Trees, Up: Weight-Balanced Trees - -Advanced Operations on Weight-Balanced Trees --------------------------------------------- - - In the following the *size* of a tree is the number of associations -that the tree contains, and a *smaller* tree contains fewer -associations. - - - procedure+: wt-tree/split< WT-TREE BOUND - Returns a new tree containing all and only the associations in - WT-TREE which have a key that is less than BOUND in the ordering - relation of the tree type of WT-TREE. The average and worst-case - times required by this operation are proportional to the logarithm - of the size of WT-TREE. - - - procedure+: wt-tree/split> WT-TREE BOUND - Returns a new tree containing all and only the associations in - WT-TREE which have a key that is greater than BOUND in the - ordering relation of the tree type of WT-TREE. The average and - worst-case times required by this operation are proportional to the - logarithm of size of WT-TREE. - - - procedure+: wt-tree/union WT-TREE-1 WT-TREE-2 - Returns a new tree containing all the associations from both trees. - This operation is asymmetric: when both trees have an association - for the same key, the returned tree associates the datum from - WT-TREE-2 with the key. Thus if the trees are viewed as discrete - maps then `wt-tree/union' computes the map override of WT-TREE-1 by - WT-TREE-2. If the trees are viewed as sets the result is the set - union of the arguments. The worst-case time required by this - operation is proportional to the sum of the sizes of both trees. - If the minimum key of one tree is greater than the maximum key of - the other tree then the time required is at worst proportional to - the logarithm of the size of the larger tree. - - - procedure+: wt-tree/intersection WT-TREE-1 WT-TREE-2 - Returns a new tree containing all and only those associations from - WT-TREE-1 which have keys appearing as the key of an association - in WT-TREE-2. Thus the associated data in the result are those - from WT-TREE-1. If the trees are being used as sets the result is - the set intersection of the arguments. As a discrete map - operation, `wt-tree/intersection' computes the domain restriction - of WT-TREE-1 to (the domain of) WT-TREE-2. The time required by - this operation is never worse that proportional to the sum of the - sizes of the trees. - - - procedure+: wt-tree/difference WT-TREE-1 WT-TREE-2 - Returns a new tree containing all and only those associations from - WT-TREE-1 which have keys that *do not* appear as the key of an - association in WT-TREE-2. If the trees are viewed as sets the - result is the asymmetric set difference of the arguments. As a - discrete map operation, it computes the domain restriction of - WT-TREE-1 to the complement of (the domain of) WT-TREE-2. The - time required by this operation is never worse that proportional to - the sum of the sizes of the trees. - - - procedure+: wt-tree/subset? WT-TREE-1 WT-TREE-2 - Returns `#t' iff the key of each association in WT-TREE-1 is the - key of some association in WT-TREE-2, otherwise returns `#f'. - Viewed as a set operation, `wt-tree/subset?' is the improper subset - predicate. A proper subset predicate can be constructed: - - (define (proper-subset? s1 s2) - (and (wt-tree/subset? s1 s2) - (< (wt-tree/size s1) (wt-tree/size s2)))) - - As a discrete map operation, `wt-tree/subset?' is the subset test - on the domain(s) of the map(s). In the worst-case the time - required by this operation is proportional to the size of - WT-TREE-1. - - - procedure+: wt-tree/set-equal? WT-TREE-1 WT-TREE-2 - Returns `#t' iff for every association in WT-TREE-1 there is an - association in WT-TREE-2 that has the same key, and *vice versa*. - - Viewing the arguments as sets `wt-tree/set-equal?' is the set - equality predicate. As a map operation it determines if two maps - are defined on the same domain. - - This procedure is equivalent to - - (lambda (wt-tree-1 wt-tree-2) - (and (wt-tree/subset? wt-tree-1 wt-tree-2 - (wt-tree/subset? wt-tree-2 wt-tree-1))) - - In the worst-case the time required by this operation is - proportional to the size of the smaller tree. - - - procedure+: wt-tree/fold COMBINER INITIAL WT-TREE - This procedure reduces WT-TREE by combining all the associations, - using an reverse in-order traversal, so the associations are - visited in reverse order. COMBINER is a procedure of three - arguments: a key, a datum and the accumulated result so far. - Provided COMBINER takes time bounded by a constant, `wt-tree/fold' - takes time proportional to the size of WT-TREE. - - A sorted association list can be derived simply: - - (wt-tree/fold (lambda (key datum list) - (cons (cons key datum) list)) - '() - WT-TREE)) - - The data in the associations can be summed like this: - - (wt-tree/fold (lambda (key datum sum) (+ sum datum)) - 0 - WT-TREE) - - - procedure+: wt-tree/for-each ACTION WT-TREE - This procedure traverses the tree in-order, applying ACTION to - each association. The associations are processed in increasing - order of their keys. ACTION is a procedure of two arguments which - take the key and datum respectively of the association. Provided - ACTION takes time bounded by a constant, `wt-tree/for-each' takes - time proportional to in the size of WT-TREE. The example prints - the tree: - - (wt-tree/for-each (lambda (key value) - (display (list key value))) - WT-TREE)) - - -File: slib.info, Node: Indexing Operations on Weight-Balanced Trees, Prev: Advanced Operations on Weight-Balanced Trees, Up: Weight-Balanced Trees - -Indexing Operations on Weight-Balanced Trees --------------------------------------------- - - Weight balanced trees support operations that view the tree as sorted -sequence of associations. Elements of the sequence can be accessed by -position, and the position of an element in the sequence can be -determined, both in logarthmic time. - - - procedure+: wt-tree/index WT-TREE INDEX - - procedure+: wt-tree/index-datum WT-TREE INDEX - - procedure+: wt-tree/index-pair WT-TREE INDEX - Returns the 0-based INDEXth association of WT-TREE in the sorted - sequence under the tree's ordering relation on the keys. - `wt-tree/index' returns the INDEXth key, `wt-tree/index-datum' - returns the datum associated with the INDEXth key and - `wt-tree/index-pair' returns a new pair `(KEY . DATUM)' which is - the `cons' of the INDEXth key and its datum. The average and - worst-case times required by this operation are proportional to - the logarithm of the number of associations in the tree. - - These operations signal an error if the tree is empty, if - INDEX`<0', or if INDEX is greater than or equal to the number of - associations in the tree. - - Indexing can be used to find the median and maximum keys in the - tree as follows: - - median: (wt-tree/index WT-TREE (quotient (wt-tree/size WT-TREE) 2)) - - maximum: (wt-tree/index WT-TREE (-1+ (wt-tree/size WT-TREE))) - - - procedure+: wt-tree/rank WT-TREE KEY - Determines the 0-based position of KEY in the sorted sequence of - the keys under the tree's ordering relation, or `#f' if the tree - has no association with for KEY. This procedure returns either an - exact non-negative integer or `#f'. The average and worst-case - times required by this operation are proportional to the logarithm - of the number of associations in the tree. - - - procedure+: wt-tree/min WT-TREE - - procedure+: wt-tree/min-datum WT-TREE - - procedure+: wt-tree/min-pair WT-TREE - Returns the association of WT-TREE that has the least key under - the tree's ordering relation. `wt-tree/min' returns the least key, - `wt-tree/min-datum' returns the datum associated with the least - key and `wt-tree/min-pair' returns a new pair `(key . datum)' - which is the `cons' of the minimum key and its datum. The average - and worst-case times required by this operation are proportional - to the logarithm of the number of associations in the tree. - - These operations signal an error if the tree is empty. They could - be written - (define (wt-tree/min tree) (wt-tree/index tree 0)) - (define (wt-tree/min-datum tree) (wt-tree/index-datum tree 0)) - (define (wt-tree/min-pair tree) (wt-tree/index-pair tree 0)) - - - procedure+: wt-tree/delete-min WT-TREE - Returns a new tree containing all of the associations in WT-TREE - except the association with the least key under the WT-TREE's - ordering relation. An error is signalled if the tree is empty. - The average and worst-case times required by this operation are - proportional to the logarithm of the number of associations in the - tree. This operation is equivalent to - - (wt-tree/delete WT-TREE (wt-tree/min WT-TREE)) - - - procedure+: wt-tree/delete-min! WT-TREE - Removes the association with the least key under the WT-TREE's - ordering relation. An error is signalled if the tree is empty. - The average and worst-case times required by this operation are - proportional to the logarithm of the number of associations in the - tree. This operation is equivalent to - - (wt-tree/delete! WT-TREE (wt-tree/min WT-TREE)) - - -File: slib.info, Node: Structures, Prev: Weight-Balanced Trees, Up: Data Structures - -Structures -========== - - `(require 'struct)' (uses defmacros) - - `defmacro's which implement "records" from the book `Essentials of -Programming Languages' by Daniel P. Friedman, M. Wand and C.T. Haynes. -Copyright 1992 Jeff Alexander, Shinnder Lee, and Lewis Patterson - - Matthew McDonald <mafm@cs.uwa.edu.au> added field setters. - - - Macro: define-record TAG (VAR1 VAR2 ...) - Defines several functions pertaining to record-name TAG: - - - Function: make-TAG VAR1 VAR2 ... - - - Function: TAG? OBJ - - - Function: TAG->VAR1 OBJ - - - Function: TAG->VAR2 OBJ - ... - - - Function: set-TAG-VAR1! OBJ VAL - - - Function: set-TAG-VAR2! OBJ VAL - ... - - Here is an example of its use. - - (define-record term (operator left right)) - => #<unspecified> - (define foo (make-term 'plus 1 2)) - => foo - (term-left foo) - => 1 - (set-term-left! foo 2345) - => #<unspecified> - (term-left foo) - => 2345 - - - Macro: variant-case EXP (TAG (VAR1 VAR2 ...) BODY) ... - executes the following for the matching clause: - - ((lambda (VAR1 VAR ...) BODY) - (TAG->VAR1 EXP) - (TAG->VAR2 EXP) ...) - - -File: slib.info, Node: Macros, Next: Numerics, Prev: Data Structures, Up: Top - -Macros -****** - -* Menu: - -* Defmacro:: Supported by all implementations - -* R4RS Macros:: 'macro -* Macro by Example:: 'macro-by-example -* Macros That Work:: 'macros-that-work -* Syntactic Closures:: 'syntactic-closures -* Syntax-Case Macros:: 'syntax-case - -Syntax extensions (macros) included with SLIB. Also *Note Structures::. - -* Fluid-Let:: 'fluid-let -* Yasos:: 'yasos, 'oop, 'collect - - -File: slib.info, Node: Defmacro, Next: R4RS Macros, Prev: Macros, Up: Macros - -Defmacro -======== - - Defmacros are supported by all implementations. - - - Function: gentemp - Returns a new (interned) symbol each time it is called. The symbol - names are implementation-dependent - (gentemp) => scm:G0 - (gentemp) => scm:G1 - - - Function: defmacro:eval E - Returns the `slib:eval' of expanding all defmacros in scheme - expression E. - - - Function: defmacro:load FILENAME - FILENAME should be a string. If filename names an existing file, - the `defmacro:load' procedure reads Scheme source code expressions - and definitions from the file and evaluates them sequentially. - These source code expressions and definitions may contain defmacro - definitions. The `macro:load' procedure does not affect the values - returned by `current-input-port' and `current-output-port'. - - - Function: defmacro? SYM - Returns `#t' if SYM has been defined by `defmacro', `#f' otherwise. - - - Function: macroexpand-1 FORM - - Function: macroexpand FORM - If FORM is a macro call, `macroexpand-1' will expand the macro - call once and return it. A FORM is considered to be a macro call - only if it is a cons whose `car' is a symbol for which a `defmacr' - has been defined. - - `macroexpand' is similar to `macroexpand-1', but repeatedly - expands FORM until it is no longer a macro call. - - - Macro: defmacro NAME LAMBDA-LIST FORM ... - When encountered by `defmacro:eval', `defmacro:macroexpand*', or - `defmacro:load' defines a new macro which will henceforth be - expanded when encountered by `defmacro:eval', - `defmacro:macroexpand*', or `defmacro:load'. - -Defmacroexpand --------------- - - `(require 'defmacroexpand)' - - - Function: defmacro:expand* E - Returns the result of expanding all defmacros in scheme expression - E. - - -File: slib.info, Node: R4RS Macros, Next: Macro by Example, Prev: Defmacro, Up: Macros - -R4RS Macros -=========== - - `(require 'macro)' is the appropriate call if you want R4RS -high-level macros but don't care about the low level implementation. If -an SLIB R4RS macro implementation is already loaded it will be used. -Otherwise, one of the R4RS macros implemetations is loaded. - - The SLIB R4RS macro implementations support the following uniform -interface: - - - Function: macro:expand SEXPRESSION - Takes an R4RS expression, macro-expands it, and returns the result - of the macro expansion. - - - Function: macro:eval SEXPRESSION - Takes an R4RS expression, macro-expands it, evals the result of the - macro expansion, and returns the result of the evaluation. - - - Procedure: macro:load FILENAME - FILENAME should be a string. If filename names an existing file, - the `macro:load' procedure reads Scheme source code expressions and - definitions from the file and evaluates them sequentially. These - source code expressions and definitions may contain macro - definitions. The `macro:load' procedure does not affect the - values returned by `current-input-port' and `current-output-port'. - - -File: slib.info, Node: Macro by Example, Next: Macros That Work, Prev: R4RS Macros, Up: Macros - -Macro by Example -================ - - `(require 'macro-by-example)' - - A vanilla implementation of `Macro by Example' (Eugene Kohlbecker, -R4RS) by Dorai Sitaram, (dorai@cs.rice.edu) using `defmacro'. - - * generating hygienic global `define-syntax' Macro-by-Example macros - *cheaply*. - - * can define macros which use `...'. - - * needn't worry about a lexical variable in a macro definition - clashing with a variable from the macro use context - - * don't suffer the overhead of redefining the repl if `defmacro' - natively supported (most implementations) - -Caveat ------- - - These macros are not referentially transparent (*note Macros: -(r4rs)Macros.). Lexically scoped macros (i.e., `let-syntax' and -`letrec-syntax') are not supported. In any case, the problem of -referential transparency gains poignancy only when `let-syntax' and -`letrec-syntax' are used. So you will not be courting large-scale -disaster unless you're using system-function names as local variables -with unintuitive bindings that the macro can't use. However, if you -must have the full `r4rs' macro functionality, look to the more -featureful (but also more expensive) versions of syntax-rules available -in slib *Note Macros That Work::, *Note Syntactic Closures::, and *Note -Syntax-Case Macros::. - - - Macro: define-syntax KEYWORD TRANSFORMER-SPEC - The KEYWORD is an identifier, and the TRANSFORMER-SPEC should be - an instance of `syntax-rules'. - - The top-level syntactic environment is extended by binding the - KEYWORD to the specified transformer. - - (define-syntax let* - (syntax-rules () - ((let* () body1 body2 ...) - (let () body1 body2 ...)) - ((let* ((name1 val1) (name2 val2) ...) - body1 body2 ...) - (let ((name1 val1)) - (let* (( name2 val2) ...) - body1 body2 ...))))) - - - Macro: syntax-rules LITERALS SYNTAX-RULE ... - LITERALS is a list of identifiers, and each SYNTAX-RULE should be - of the form - - `(PATTERN TEMPLATE)' - - where the PATTERN and TEMPLATE are as in the grammar above. - - An instance of `syntax-rules' produces a new macro transformer by - specifying a sequence of hygienic rewrite rules. A use of a macro - whose keyword is associated with a transformer specified by - `syntax-rules' is matched against the patterns contained in the - SYNTAX-RULEs, beginning with the leftmost SYNTAX-RULE. When a - match is found, the macro use is trancribed hygienically according - to the template. - - Each pattern begins with the keyword for the macro. This keyword - is not involved in the matching and is not considered a pattern - variable or literal identifier. - - -File: slib.info, Node: Macros That Work, Next: Syntactic Closures, Prev: Macro by Example, Up: Macros - -Macros That Work -================ - - `(require 'macros-that-work)' - - `Macros That Work' differs from the other R4RS macro implementations -in that it does not expand derived expression types to primitive -expression types. - - - Function: macro:expand EXPRESSION - - Function: macwork:expand EXPRESSION - Takes an R4RS expression, macro-expands it, and returns the result - of the macro expansion. - - - Function: macro:eval EXPRESSION - - Function: macwork:eval EXPRESSION - `macro:eval' returns the value of EXPRESSION in the current top - level environment. EXPRESSION can contain macro definitions. - Side effects of EXPRESSION will affect the top level environment. - - - Procedure: macro:load FILENAME - - Procedure: macwork:load FILENAME - FILENAME should be a string. If filename names an existing file, - the `macro:load' procedure reads Scheme source code expressions and - definitions from the file and evaluates them sequentially. These - source code expressions and definitions may contain macro - definitions. The `macro:load' procedure does not affect the - values returned by `current-input-port' and `current-output-port'. - - References: - - The `Revised^4 Report on the Algorithmic Language Scheme' Clinger and -Rees [editors]. To appear in LISP Pointers. Also available as a -technical report from the University of Oregon, MIT AI Lab, and Cornell. - - Macros That Work. Clinger and Rees. POPL '91. - - The supported syntax differs from the R4RS in that vectors are allowed -as patterns and as templates and are not allowed as pattern or template -data. - - transformer spec ==> (syntax-rules literals rules) - - rules ==> () - | (rule . rules) - - rule ==> (pattern template) - - pattern ==> pattern_var ; a symbol not in literals - | symbol ; a symbol in literals - | () - | (pattern . pattern) - | (ellipsis_pattern) - | #(pattern*) ; extends R4RS - | #(pattern* ellipsis_pattern) ; extends R4RS - | pattern_datum - - template ==> pattern_var - | symbol - | () - | (template2 . template2) - | #(template*) ; extends R4RS - | pattern_datum - - template2 ==> template - | ellipsis_template - - pattern_datum ==> string ; no vector - | character - | boolean - | number - - ellipsis_pattern ==> pattern ... - - ellipsis_template ==> template ... - - pattern_var ==> symbol ; not in literals - - literals ==> () - | (symbol . literals) - -Definitions ------------ - -Scope of an ellipsis - Within a pattern or template, the scope of an ellipsis (`...') is - the pattern or template that appears to its left. - -Rank of a pattern variable - The rank of a pattern variable is the number of ellipses within - whose scope it appears in the pattern. - -Rank of a subtemplate - The rank of a subtemplate is the number of ellipses within whose - scope it appears in the template. - -Template rank of an occurrence of a pattern variable - The template rank of an occurrence of a pattern variable within a - template is the rank of that occurrence, viewed as a subtemplate. - -Variables bound by a pattern - The variables bound by a pattern are the pattern variables that - appear within it. - -Referenced variables of a subtemplate - The referenced variables of a subtemplate are the pattern - variables that appear within it. - -Variables opened by an ellipsis template - The variables opened by an ellipsis template are the referenced - pattern variables whose rank is greater than the rank of the - ellipsis template. - -Restrictions ------------- - - No pattern variable appears more than once within a pattern. - - For every occurrence of a pattern variable within a template, the -template rank of the occurrence must be greater than or equal to the -pattern variable's rank. - - Every ellipsis template must open at least one variable. - - For every ellipsis template, the variables opened by an ellipsis -template must all be bound to sequences of the same length. - - The compiled form of a RULE is - - rule ==> (pattern template inserted) - - pattern ==> pattern_var - | symbol - | () - | (pattern . pattern) - | ellipsis_pattern - | #(pattern) - | pattern_datum - - template ==> pattern_var - | symbol - | () - | (template2 . template2) - | #(pattern) - | pattern_datum - - template2 ==> template - | ellipsis_template - - pattern_datum ==> string - | character - | boolean - | number - - pattern_var ==> #(V symbol rank) - - ellipsis_pattern ==> #(E pattern pattern_vars) - - ellipsis_template ==> #(E template pattern_vars) - - inserted ==> () - | (symbol . inserted) - - pattern_vars ==> () - | (pattern_var . pattern_vars) - - rank ==> exact non-negative integer - - where V and E are unforgeable values. - - The pattern variables associated with an ellipsis pattern are the -variables bound by the pattern, and the pattern variables associated -with an ellipsis template are the variables opened by the ellipsis -template. - - If the template contains a big chunk that contains no pattern -variables or inserted identifiers, then the big chunk will be copied -unnecessarily. That shouldn't matter very often. - |