You are looking at historical revision 31169 of this page. It may differ significantly from its current revision.
Rationale
Scheme lists are mutable and untyped. The list types produced with the only exported symbol of this module, a giant macro, are typed and immutable.
Concerning mutability, Scheme's authors, G. J. Sussman and G. L. Steele jr. in their paper "The First Report on Scheme Revisited", Higher-Order and Symbolic Computation, 11, 399-404 (1998) argued:
"We also now believe that Carl Hewitt was right: we would have been better off to have introduced cells as a separate, primitive kind of object, rather than allowing assignment to any and every lambda-bound variable"
Well, cells -- or boxes, if you prefer -- exist as modules, so restricted mutability can be provided by accepting cells -- or boxes -- as item types.
Typing of list arguments on the other hand improves security of the implemented functions on the one side, but are cumbersome to use on the other: After all, we don't want to write the same routines for lists of numbers, lists of strings, lists of symbols, ... over and over again. Macros come to the rescue, you guess it! Hence this module exports only one macro, define-list-type, which implements a long list of functions, which differ mostly only by a prefix, you provide, from standard list functions, an item type, you provide as well, and last but not least a user named documentation procedure, showing you the signatures of all the generated functions.
But note, that these typed lists don't pass the list? predicate. They are different creatures, created with define-datatype and accessed with cases from the datatype module.
Programming interface
define-list-type
<macro>(define-list-type name
documentation: docu item-predicate: ok? procedure-prefix: pre)</macro>
defines a new list type, name, whose items must pass the ok? predicate, and a documentation procedure, docu, by implementing a long list of functions, most of them prefixed by the prefix pre. Exceptions of this prefix rule are the constructor and type predicate for the list, named name as well or name with an appended question mark. The list of generated functions are given by a call to docu without arguments, the signature of such a function by the call (docu 'function).
Note that most of the functions are prefixed versions of standard list functions, some of them with changed order of arguments. The reason for that is consistency: The list arguments are always the last ones.
Examples
(require-library typed-lists cells) (import typed-lists cells) (define-list-type lon documentation: lons item-predicate: (disjoin number? (cell-of? number?)) procedure-prefix: n) (define nnil (nnull)) (lon? nnil) ; -> #t (nnull? nnil) ; -> #t (null? nnil) ; -> #f (define nls (ncons 1 nnil)) (lon? nls) ; -> #t (define nlst (lon 0 1 (cell 2) 3 4)) (lon? nlst) ; -> #t (list? nlst) ; -> #f (napply + 1 2 (lon 3 4 5)) ; ->15 (nrepeat 5 0) ; -> '#,(lon 0 0 0 0 0) (neqv? (niterate-times 5 add1 0) (lon 0 1 2 3 4)) ; -> #t (niterate-while (lambda (x) (< x 5)) add1 0) ; -> '#,(lon 0 1 2 3 4)) (niterate-until (lambda (x) (= x 5)) add1 0) ; -> '#,(lon 0 1 2 3 4) (nzip (lon 1 2 3 4 5) (lon 10 20 30)) ; -> '#,(lon 1 10 2 20 3 30 4 5) (ninterpose 10 (lon 1 2 3 4 5)) ; -> '#,(lon 1 10 2 10 3 10 4 10 5) (ncdddr nlst) ; -> '#,(lon 3 4) (ncadddr nlst) ; -> 3 (nequ? = (ndrop 3 nlst) (lon 3 4)) ; -> #t (nequ? = (ndrop-while odd? (lon 1 3 2 4 5)) (lon 2 4 5)) ; -> #t (nequ? = (ntake-while odd? (lon 1 3 2 4 5)) (lon 1 3)) ; -> #t (receive (head tail) (nsplit-with even? (lon 1 3 2 4 5)) (and (neqv? head (lon 1 3)) (neqv? tail (lon 2 4 5)))) ; -> #t (ntake 2 nlst) ; -> (lon 0 1) (lon? (nnull)) ; -> #t (nnull? (nnull)) ; -> #t (nnull? nls) ; -> #f (lon? '(1 2)) ; -> #f (nnull? (ncdr nls)) ; -> #t (ncar nlst) ; -> 0 (lon? (nreverse nlst)) ; -> #t (nreverse nlst) '#,(lon 4 3 !2! 1 0) (equal? (lon->list nlst) (list 0 1 (cell 2) 3 4)) ; -> #t (equal? (nref 2 nlst) (cell 2)) ; -> #t (cell-set! (nref 2 nlst) 20) (equal? (nref 2 nlst) (cell 20)) ; -> #t (cell-ref (nref 2 nlst)) ; -> 20 (nlength nlst) ; -> 5 (nequal? (nsublist 2 4 nlst) (lon (cell 20) 3)) ; -> #t (nequ? = (nappend (lon 0 1 2 3) (lon 4 5 6)) (lon 0 1 2 3 4 5 6)) ; -> #t (nequ? = (nappend (lon 0) (lon 1) (lon 2) (lon 3 4) (lon 5 6 7) (lon 8)) (lon 0 1 2 3 4 5 6 7 8)) ; -> #t (nequ? = (nmap add1 (lon 0 1 2 3)) (lon 1 2 3 4)) ; -> #t (nequ? = (nmap + (lon 1 2 3) (lon 10 20 30 40)) (lon 11 22 33)) ; -> #t (nfold-right ncons (nnull) (lon 0 1 2 3 4)) ; -> '#,(lon 0 1 2 3 4)) (nfold-left + 0 (lon 1 2 3) (lon 10 20 30)) ; -> 66 (nfold-left cons '(100) (lon 1 2 3 4)) ; -> '(((((100) . 1) . 2) . 3) . 4) (equal? (call-with-values (lambda () (nreverse* (lon 1 2 3) (lon 10 20 30))) list) (list (lon 3 2 1) (lon 30 20 10))) ; -> #t (nremv 0 (lon 1 0 2 0 3 0 4)) ; -> '#,(lon 1 2 3 4) (nmerge < (lon 2 4 5 7 8) (lon 1 3 6 9 10)) ; -> '#,(lon 1 2 3 4 5 6 7 8 9 10)) (condition-case (nmerge < (nnull) (lon 1 3 2)) ((exn) #f)) ; -> #f (nevery? odd? (lon 1 3 5)) ; -> #t (nevery? odd? (lon)) ; -> #t (nsome odd? (lon 2 3 5)) ; -> 3 (nsome odd? (lon 2 4 6)) ; -> #f (nnot-every? odd? (lon 1 2 3)) ; -> #t (nnot-any? odd? (lon 2 4 6)) ; -> #t (define-list-type lol documentation: lols item-predicate: list? procedure-prefix: l) (lequal? (lappend (lol '(a) '(b)) (lol '(c))) (lol '(a) '(b) '(c)))
Requirements
datatype
Last update
Jul 30, 2014
Author
License
Copyright (c) 2011-2014, Juergen Lorenz All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Version History
- 0.1
- initial import