2007-10-25 16:27:34 -04:00
|
|
|
;;; Ikarus Scheme -- A compiler for R6RS Scheme.
|
|
|
|
;;; Copyright (C) 2006,2007 Abdulaziz Ghuloum
|
|
|
|
;;;
|
|
|
|
;;; This program is free software: you can redistribute it and/or modify
|
|
|
|
;;; it under the terms of the GNU General Public License version 3 as
|
|
|
|
;;; published by the Free Software Foundation.
|
|
|
|
;;;
|
|
|
|
;;; 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2007-05-05 05:22:15 -04:00
|
|
|
|
|
|
|
(library (ikarus lists)
|
2007-09-09 23:41:12 -04:00
|
|
|
(export $memq list? list cons* make-list append length list-ref reverse
|
2007-09-10 17:09:19 -04:00
|
|
|
last-pair memq memp memv member find assq assp assv assoc
|
2007-09-10 17:28:06 -04:00
|
|
|
remq remv remove remp filter map for-each andmap ormap list-tail
|
2007-10-10 06:43:25 -04:00
|
|
|
partition for-all exists fold-left fold-right)
|
2007-05-05 05:24:37 -04:00
|
|
|
(import
|
2007-05-06 17:47:36 -04:00
|
|
|
(ikarus system $fx)
|
|
|
|
(ikarus system $pairs)
|
2007-09-09 23:41:12 -04:00
|
|
|
(except (ikarus) list? list cons* make-list append reverse
|
2007-09-10 17:09:19 -04:00
|
|
|
last-pair length list-ref memq memp memv member find
|
|
|
|
assq assp assv assoc remq remv remove remp filter
|
2007-10-09 07:56:30 -04:00
|
|
|
map for-each andmap ormap list-tail partition
|
2007-10-10 06:43:25 -04:00
|
|
|
for-all exists fold-left fold-right))
|
2007-05-05 05:22:15 -04:00
|
|
|
|
|
|
|
(define $memq
|
|
|
|
(lambda (x ls)
|
|
|
|
(let f ([x x] [ls ls])
|
|
|
|
(and (pair? ls)
|
|
|
|
(if (eq? x (car ls))
|
|
|
|
ls
|
|
|
|
(f x (cdr ls)))))))
|
2007-05-05 05:24:37 -04:00
|
|
|
|
2007-05-05 06:12:47 -04:00
|
|
|
(define list (lambda x x))
|
|
|
|
|
2007-09-09 23:31:19 -04:00
|
|
|
(define cons*
|
|
|
|
(lambda (fst . rest)
|
|
|
|
(let f ([fst fst] [rest rest])
|
|
|
|
(cond
|
|
|
|
[(null? rest) fst]
|
|
|
|
[else
|
|
|
|
(cons fst (f ($car rest) ($cdr rest)))]))))
|
2007-05-05 06:19:50 -04:00
|
|
|
|
2007-05-05 05:24:37 -04:00
|
|
|
(define list?
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(and (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t)))
|
|
|
|
(null? h)))
|
|
|
|
(null? h)))])
|
|
|
|
(lambda (x) (race x x))))
|
2007-05-05 06:12:47 -04:00
|
|
|
|
|
|
|
(module (make-list)
|
|
|
|
(define f
|
|
|
|
(lambda (n fill ls)
|
|
|
|
(cond
|
|
|
|
[($fxzero? n) ls]
|
|
|
|
[else
|
|
|
|
(f ($fxsub1 n) fill (cons fill ls))])))
|
|
|
|
(define make-list
|
|
|
|
(case-lambda
|
|
|
|
[(n)
|
|
|
|
(if (and (fixnum? n) ($fx>= n 0))
|
|
|
|
(f n (void) '())
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'make-list "not a valid length" n))]
|
2007-05-05 06:12:47 -04:00
|
|
|
[(n fill)
|
|
|
|
(if (and (fixnum? n) ($fx>= n 0))
|
|
|
|
(f n fill '())
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'make-list "not a valid length" n))])))
|
2007-05-05 06:12:47 -04:00
|
|
|
|
|
|
|
|
2007-05-05 05:29:35 -04:00
|
|
|
(define length
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls n)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls ($fx+ n 2))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'length "circular list" ls))
|
2007-05-05 05:29:35 -04:00
|
|
|
(if (null? h)
|
|
|
|
($fx+ n 1)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'length "not a proper list" ls))))
|
2007-05-05 05:29:35 -04:00
|
|
|
(if (null? h)
|
|
|
|
n
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'length "not a proper list" ls))))])
|
2007-05-05 05:29:35 -04:00
|
|
|
(lambda (ls)
|
|
|
|
(race ls ls ls 0))))
|
|
|
|
|
|
|
|
(define list-ref
|
|
|
|
(lambda (list index)
|
|
|
|
(define f
|
|
|
|
(lambda (ls i)
|
|
|
|
(cond
|
|
|
|
[($fxzero? i)
|
|
|
|
(if (pair? ls)
|
|
|
|
($car ls)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'list-ref "index is out of range" index list))]
|
2007-05-05 05:29:35 -04:00
|
|
|
[(pair? ls)
|
|
|
|
(f ($cdr ls) ($fxsub1 i))]
|
|
|
|
[(null? ls)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'list-rec "index is out of range" index list)]
|
|
|
|
[else (die 'list-ref "not a list" list)])))
|
2007-05-05 05:29:35 -04:00
|
|
|
(unless (and (fixnum? index) ($fx>= index 0))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'list-ref "not a valid index" index))
|
2007-05-05 05:29:35 -04:00
|
|
|
(f list index)))
|
|
|
|
|
2007-06-13 10:42:04 -04:00
|
|
|
|
|
|
|
(define list-tail
|
|
|
|
(lambda (list index)
|
|
|
|
(define f
|
|
|
|
(lambda (ls i)
|
|
|
|
(cond
|
|
|
|
[($fxzero? i) ls]
|
|
|
|
[(pair? ls)
|
|
|
|
(f ($cdr ls) ($fxsub1 i))]
|
|
|
|
[(null? ls)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'list-tail "index is out of range" index list)]
|
|
|
|
[else (die 'list-tail "not a list" list)])))
|
2007-06-13 10:42:04 -04:00
|
|
|
(unless (and (fixnum? index) ($fx>= index 0))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'list-tail "not a valid index" index))
|
2007-06-13 10:42:04 -04:00
|
|
|
(f list index)))
|
|
|
|
|
2007-05-05 06:04:36 -04:00
|
|
|
(module (append)
|
|
|
|
(define reverse
|
|
|
|
(lambda (h t ls ac)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)] [a1 ($car h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(let ([a2 ($car h)])
|
|
|
|
(reverse ($cdr h) ($cdr t) ls (cons a2 (cons a1 ac))))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'append "circular list" ls))
|
2007-05-05 06:04:36 -04:00
|
|
|
(if (null? h)
|
|
|
|
(cons a1 ac)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'append "not a proper list" ls))))
|
2007-05-05 06:04:36 -04:00
|
|
|
(if (null? h)
|
|
|
|
ac
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'append "not a proper list" ls)))))
|
2007-12-15 08:55:53 -05:00
|
|
|
(define rev!
|
2007-05-05 06:04:36 -04:00
|
|
|
(lambda (ls ac)
|
|
|
|
(cond
|
|
|
|
[(null? ls) ac]
|
|
|
|
[else
|
2007-12-15 08:55:53 -05:00
|
|
|
(let ([ls^ ($cdr ls)])
|
|
|
|
($set-cdr! ls ac)
|
|
|
|
(rev! ls^ ls))])))
|
2007-05-05 06:04:36 -04:00
|
|
|
(define append1
|
|
|
|
(lambda (ls ls*)
|
|
|
|
(cond
|
|
|
|
[(null? ls*) ls]
|
|
|
|
[else
|
2007-12-15 08:55:53 -05:00
|
|
|
(rev! (reverse ls ls ls '())
|
2007-05-05 06:04:36 -04:00
|
|
|
(append1 ($car ls*) ($cdr ls*)))])))
|
|
|
|
(define append
|
|
|
|
(case-lambda
|
|
|
|
[() '()]
|
|
|
|
[(ls) ls]
|
|
|
|
[(ls . ls*)
|
|
|
|
(append1 ls ls*)])))
|
|
|
|
|
2007-05-05 05:24:37 -04:00
|
|
|
(define reverse
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls ac)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)] [ac (cons ($car h) ac)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls (cons ($car h) ac))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'reverse "circular list" ls))
|
2007-05-05 05:24:37 -04:00
|
|
|
(if (null? h)
|
|
|
|
ac
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'reverse "not a proper list" ls))))
|
2007-05-05 05:24:37 -04:00
|
|
|
(if (null? h)
|
|
|
|
ac
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'reverse "not a proper list" ls))))])
|
2007-05-05 05:24:37 -04:00
|
|
|
(lambda (x)
|
|
|
|
(race x x x '()))))
|
|
|
|
|
|
|
|
(define last-pair
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls last)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)] [last h])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls h)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'last-pair "circular list" ls))
|
2007-05-05 05:24:37 -04:00
|
|
|
last))
|
|
|
|
last))])
|
|
|
|
(lambda (x)
|
|
|
|
(if (pair? x)
|
|
|
|
(let ([d (cdr x)])
|
|
|
|
(race d d x x))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'last-pair "not a pair" x)))))
|
2007-05-05 05:24:37 -04:00
|
|
|
|
2007-05-05 05:26:38 -04:00
|
|
|
(define memq
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls x)
|
|
|
|
(if (pair? h)
|
|
|
|
(if (eq? ($car h) x)
|
|
|
|
h
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (eq? ($car h) x)
|
|
|
|
h
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memq "circular list" ls)))
|
2007-05-05 05:26:38 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memq "not a proper list" ls)))))
|
2007-05-05 05:26:38 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memq "not a proper list" ls))))])
|
2007-05-05 05:26:38 -04:00
|
|
|
(lambda (x ls)
|
|
|
|
(race ls ls ls x))))
|
|
|
|
|
|
|
|
(define memv
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls x)
|
|
|
|
(if (pair? h)
|
|
|
|
(if (eqv? ($car h) x)
|
|
|
|
h
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (eqv? ($car h) x)
|
|
|
|
h
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memv "circular list" ls)))
|
2007-05-05 05:26:38 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memv "not a proper list" ls)))))
|
2007-05-05 05:26:38 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memv "not a proper list" ls))))])
|
2007-05-05 05:26:38 -04:00
|
|
|
(lambda (x ls)
|
|
|
|
(race ls ls ls x))))
|
2007-05-05 05:22:15 -04:00
|
|
|
|
2007-05-05 05:26:38 -04:00
|
|
|
(define member
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls x)
|
|
|
|
(if (pair? h)
|
|
|
|
(if (equal? ($car h) x)
|
|
|
|
h
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (equal? ($car h) x)
|
|
|
|
h
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'member "circular list" ls)))
|
2007-05-05 05:26:38 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'member "not a proper list" ls)))))
|
2007-05-05 05:26:38 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'member "not a proper list" ls))))])
|
2007-05-05 05:26:38 -04:00
|
|
|
(lambda (x ls)
|
|
|
|
(race ls ls ls x))))
|
|
|
|
|
2007-09-10 15:56:15 -04:00
|
|
|
|
|
|
|
(define memp
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls p)
|
|
|
|
(if (pair? h)
|
|
|
|
(if (p ($car h))
|
|
|
|
h
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (p ($car h))
|
|
|
|
h
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls p)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memp "circular list" ls)))
|
2007-09-10 15:56:15 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memp "not a proper list" ls)))))
|
2007-09-10 15:56:15 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memp "not a proper list" ls))))])
|
2007-09-10 15:56:15 -04:00
|
|
|
(lambda (p ls)
|
|
|
|
(unless (procedure? p)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'memp "not a procedure" p))
|
2007-09-10 15:56:15 -04:00
|
|
|
(race ls ls ls p))))
|
|
|
|
|
2007-09-10 17:09:19 -04:00
|
|
|
(define find
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls p)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([a ($car h)])
|
|
|
|
(if (p a)
|
|
|
|
a
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([a ($car h)])
|
|
|
|
(if (p a)
|
|
|
|
a
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls p)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'find "circular list" ls))))
|
2007-09-10 17:09:19 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'find "not a proper list" ls))))))
|
2007-09-10 17:09:19 -04:00
|
|
|
(if (null? h)
|
|
|
|
'#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'find "not a proper list" ls))))])
|
2007-09-10 17:09:19 -04:00
|
|
|
(lambda (p ls)
|
|
|
|
(unless (procedure? p)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'find "not a procedure" p))
|
2007-09-10 17:09:19 -04:00
|
|
|
(race ls ls ls p))))
|
2007-09-10 15:56:15 -04:00
|
|
|
|
2007-05-05 05:31:30 -04:00
|
|
|
(define assq
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (x h t ls)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([a ($car h)] [h ($cdr h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (eq? ($car a) x)
|
|
|
|
a
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(let ([a ($car h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (eq? ($car a) x)
|
|
|
|
a
|
|
|
|
(race x ($cdr h) ($cdr t) ls))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assq "malformed alist"
|
2007-05-05 05:31:30 -04:00
|
|
|
ls)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assq "circular list" ls))
|
2007-05-05 05:31:30 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assq "not a proper list" ls))))
|
|
|
|
(die 'assq "malformed alist" ls)))
|
2007-05-05 05:31:30 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assq "not a proper list" ls))))])
|
2007-05-05 05:31:30 -04:00
|
|
|
(lambda (x ls)
|
|
|
|
(race x ls ls ls))))
|
|
|
|
|
2007-09-10 15:56:15 -04:00
|
|
|
|
|
|
|
(define assp
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (p h t ls)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([a ($car h)] [h ($cdr h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (p ($car a))
|
|
|
|
a
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(let ([a ($car h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (p ($car a))
|
|
|
|
a
|
|
|
|
(race p ($cdr h) ($cdr t) ls))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assp "malformed alist"
|
2007-09-10 15:56:15 -04:00
|
|
|
ls)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assp "circular list" ls))
|
2007-09-10 15:56:15 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assp "not a proper list" ls))))
|
|
|
|
(die 'assp "malformed alist" ls)))
|
2007-09-10 15:56:15 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assp "not a proper list" ls))))])
|
2007-09-10 15:56:15 -04:00
|
|
|
(lambda (p ls)
|
|
|
|
(unless (procedure? p)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assp "not a procedure" p))
|
2007-09-10 15:56:15 -04:00
|
|
|
(race p ls ls ls))))
|
|
|
|
|
2007-05-05 05:31:30 -04:00
|
|
|
(define assv
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (x h t ls)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([a ($car h)] [h ($cdr h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (eqv? ($car a) x)
|
|
|
|
a
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(let ([a ($car h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (eqv? ($car a) x)
|
|
|
|
a
|
|
|
|
(race x ($cdr h) ($cdr t) ls))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assv "malformed alist"
|
2007-05-05 05:31:30 -04:00
|
|
|
ls)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assv "circular list" ls))
|
2007-05-05 05:31:30 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assv "not a proper list" ls))))
|
|
|
|
(die 'assv "malformed alist" ls)))
|
2007-05-05 05:31:30 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assv "not a proper list" ls))))])
|
2007-05-05 05:31:30 -04:00
|
|
|
(lambda (x ls)
|
|
|
|
(race x ls ls ls))))
|
|
|
|
|
|
|
|
(define assoc
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (x h t ls)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([a ($car h)] [h ($cdr h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (equal? ($car a) x)
|
|
|
|
a
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(let ([a ($car h)])
|
|
|
|
(if (pair? a)
|
|
|
|
(if (equal? ($car a) x)
|
|
|
|
a
|
|
|
|
(race x ($cdr h) ($cdr t) ls))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assoc "malformed alist"
|
2007-05-05 05:31:30 -04:00
|
|
|
ls)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assoc "circular list" ls))
|
2007-05-05 05:31:30 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assoc "not a proper list" ls))))
|
|
|
|
(die 'assoc "malformed alist" ls)))
|
2007-05-05 05:31:30 -04:00
|
|
|
(if (null? h)
|
|
|
|
#f
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'assoc "not a proper list" ls))))])
|
2007-05-05 05:31:30 -04:00
|
|
|
(lambda (x ls)
|
|
|
|
(race x ls ls ls))))
|
2007-05-05 05:29:35 -04:00
|
|
|
|
2007-09-10 16:33:05 -04:00
|
|
|
|
2007-09-10 17:03:40 -04:00
|
|
|
(module (remq remv remove remp filter)
|
2007-09-10 16:33:05 -04:00
|
|
|
(define-syntax define-remover
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ name cmp check)
|
|
|
|
(define name
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls x)
|
|
|
|
(if (pair? h)
|
|
|
|
(if (cmp ($car h) x)
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(if (cmp ($car h) x)
|
|
|
|
(race ($cdr h) ($cdr t) ls x)
|
|
|
|
(cons ($car h) (race ($cdr h) ($cdr t) ls x)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'name "circular list" ls))
|
2007-09-10 16:33:05 -04:00
|
|
|
(if (null? h)
|
|
|
|
'()
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'name "not a proper list" ls))))
|
2007-09-10 16:33:05 -04:00
|
|
|
(let ([a0 ($car h)] [h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(if (cmp ($car h) x)
|
|
|
|
(cons a0 (race ($cdr h) ($cdr t) ls x))
|
|
|
|
(cons* a0 ($car h) (race ($cdr h) ($cdr t) ls x)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'name "circular list" ls))
|
2007-09-10 16:33:05 -04:00
|
|
|
(if (null? h)
|
|
|
|
(list a0)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'name "not a proper list" ls)))))
|
2007-09-10 16:33:05 -04:00
|
|
|
(if (null? h)
|
|
|
|
'()
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'name "not a proper list" ls))))])
|
2007-09-10 16:33:05 -04:00
|
|
|
(lambda (x ls)
|
|
|
|
(check x ls)
|
|
|
|
(race ls ls ls x))))]))
|
|
|
|
(define-remover remq eq? (lambda (x ls) #t))
|
|
|
|
(define-remover remv eqv? (lambda (x ls) #t))
|
|
|
|
(define-remover remove equal? (lambda (x ls) #t))
|
|
|
|
(define-remover remp (lambda (elt p) (p elt))
|
|
|
|
(lambda (x ls)
|
|
|
|
(unless (procedure? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'remp "not a procedure" x))))
|
2007-09-10 17:03:40 -04:00
|
|
|
(define-remover filter (lambda (elt p) (not (p elt)))
|
|
|
|
(lambda (x ls)
|
|
|
|
(unless (procedure? x)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'filter "not a procedure" x)))))
|
2007-09-10 16:33:05 -04:00
|
|
|
|
|
|
|
|
2007-05-05 05:59:01 -04:00
|
|
|
(module (map)
|
|
|
|
(define who 'map)
|
|
|
|
(define len
|
|
|
|
(lambda (h t n)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (eq? h t)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "circular list")
|
2007-05-05 05:59:01 -04:00
|
|
|
(len ($cdr h) ($cdr t) ($fx+ n 2)))
|
|
|
|
(if (null? h)
|
|
|
|
($fxadd1 n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "improper list"))))
|
2007-05-05 05:59:01 -04:00
|
|
|
(if (null? h)
|
|
|
|
n
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "improper list")))))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define map1
|
|
|
|
(lambda (f a d n)
|
|
|
|
(cond
|
|
|
|
[(pair? d)
|
|
|
|
(if ($fxzero? n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered!")
|
2007-05-05 05:59:01 -04:00
|
|
|
(cons (f a)
|
|
|
|
(map1 f ($car d) ($cdr d) ($fxsub1 n))))]
|
|
|
|
[(null? d)
|
|
|
|
(if ($fxzero? n)
|
|
|
|
(cons (f a) '())
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered"))]
|
|
|
|
[else (die who "list was altered")])))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define map2
|
|
|
|
(lambda (f a1 a2 d1 d2 n)
|
|
|
|
(cond
|
|
|
|
[(pair? d1)
|
|
|
|
(cond
|
|
|
|
[(pair? d2)
|
|
|
|
(if ($fxzero? n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered")
|
2007-05-05 05:59:01 -04:00
|
|
|
(cons (f a1 a2)
|
|
|
|
(map2 f
|
|
|
|
($car d1) ($car d2)
|
|
|
|
($cdr d1) ($cdr d2)
|
|
|
|
($fxsub1 n))))]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "length mismatch")])]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(null? d1)
|
|
|
|
(cond
|
|
|
|
[(null? d2)
|
|
|
|
(if ($fxzero? n)
|
|
|
|
(cons (f a1 a2) '())
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered"))]
|
|
|
|
[else (die who "length mismatch")])]
|
|
|
|
[else (die who "list was altered")])))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define cars
|
|
|
|
(lambda (ls*)
|
|
|
|
(cond
|
|
|
|
[(null? ls*) '()]
|
|
|
|
[else
|
|
|
|
(let ([a (car ls*)])
|
|
|
|
(cond
|
|
|
|
[(pair? a)
|
|
|
|
(cons (car a) (cars (cdr ls*)))]
|
|
|
|
[else
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'map "length mismatch")]))])))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define cdrs
|
|
|
|
(lambda (ls*)
|
|
|
|
(cond
|
|
|
|
[(null? ls*) '()]
|
|
|
|
[else
|
|
|
|
(let ([a (car ls*)])
|
|
|
|
(cond
|
|
|
|
[(pair? a)
|
|
|
|
(cons (cdr a) (cdrs (cdr ls*)))]
|
|
|
|
[else
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'map "length mismatch")]))])))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define mapm
|
|
|
|
(lambda (f ls ls* n)
|
|
|
|
(cond
|
|
|
|
[(null? ls)
|
|
|
|
(if (andmap null? ls*)
|
|
|
|
(if (fxzero? n)
|
|
|
|
'()
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'map "lists were mutated during operation"))
|
|
|
|
(die 'map "length mismatch"))]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(fxzero? n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'map "lists were mutated during operation")]
|
2007-05-05 05:59:01 -04:00
|
|
|
[else
|
|
|
|
(cons
|
|
|
|
(apply f (car ls) (cars ls*))
|
|
|
|
(mapm f (cdr ls) (cdrs ls*) (fxsub1 n)))])))
|
|
|
|
(define map
|
|
|
|
(case-lambda
|
|
|
|
[(f ls)
|
|
|
|
(unless (procedure? f)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "not a procedure" f))
|
2007-05-05 05:59:01 -04:00
|
|
|
(cond
|
|
|
|
[(pair? ls)
|
|
|
|
(let ([d ($cdr ls)])
|
|
|
|
(map1 f ($car ls) d (len d d 0)))]
|
|
|
|
[(null? ls) '()]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "improper list")])]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(f ls ls2)
|
|
|
|
(unless (procedure? f)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "not a procedure" f))
|
2007-05-05 05:59:01 -04:00
|
|
|
(cond
|
|
|
|
[(pair? ls)
|
|
|
|
(if (pair? ls2)
|
|
|
|
(let ([d ($cdr ls)])
|
|
|
|
(map2 f ($car ls) ($car ls2) d ($cdr ls2) (len d d 0)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "length mismatch"))]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(null? ls)
|
|
|
|
(if (null? ls2)
|
|
|
|
'()
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "length mismatch"))]
|
|
|
|
[else (die who "not a list")])]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(f ls . ls*)
|
|
|
|
(unless (procedure? f)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "not a procedure" f))
|
2007-05-05 05:59:01 -04:00
|
|
|
(cond
|
|
|
|
[(pair? ls)
|
|
|
|
(let ([n (len ls ls 0)])
|
|
|
|
(mapm f ls ls* n))]
|
|
|
|
[(null? ls)
|
|
|
|
(if (andmap null? ls*)
|
|
|
|
'()
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "length mismatch"))])])))
|
2007-05-05 05:59:01 -04:00
|
|
|
|
|
|
|
(module (for-each)
|
|
|
|
(define who 'for-each)
|
|
|
|
(define len
|
|
|
|
(lambda (h t n)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (eq? h t)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "circular list")
|
2007-05-05 05:59:01 -04:00
|
|
|
(len ($cdr h) ($cdr t) ($fx+ n 2)))
|
|
|
|
(if (null? h)
|
|
|
|
($fxadd1 n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "improper list"))))
|
2007-05-05 05:59:01 -04:00
|
|
|
(if (null? h)
|
|
|
|
n
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "improper list")))))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define for-each1
|
|
|
|
(lambda (f a d n)
|
|
|
|
(cond
|
|
|
|
[(pair? d)
|
|
|
|
(if ($fxzero? n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered!")
|
2007-05-05 05:59:01 -04:00
|
|
|
(begin
|
|
|
|
(f a)
|
|
|
|
(for-each1 f ($car d) ($cdr d) ($fxsub1 n))))]
|
|
|
|
[(null? d)
|
|
|
|
(if ($fxzero? n)
|
|
|
|
(f a)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered"))]
|
|
|
|
[else (die who "list was altered")])))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define for-each2
|
|
|
|
(lambda (f a1 a2 d1 d2 n)
|
|
|
|
(cond
|
|
|
|
[(pair? d1)
|
|
|
|
(cond
|
|
|
|
[(pair? d2)
|
|
|
|
(if ($fxzero? n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered")
|
2007-05-05 05:59:01 -04:00
|
|
|
(begin
|
|
|
|
(f a1 a2)
|
|
|
|
(for-each2 f
|
|
|
|
($car d1) ($car d2)
|
|
|
|
($cdr d1) ($cdr d2)
|
|
|
|
($fxsub1 n))))]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "length mismatch")])]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(null? d1)
|
|
|
|
(cond
|
|
|
|
[(null? d2)
|
|
|
|
(if ($fxzero? n)
|
|
|
|
(f a1 a2)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered"))]
|
|
|
|
[else (die who "length mismatch")])]
|
|
|
|
[else (die who "list was altered")])))
|
2007-05-05 05:59:01 -04:00
|
|
|
(define for-each
|
|
|
|
(case-lambda
|
|
|
|
[(f ls)
|
|
|
|
(unless (procedure? f)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "not a procedure" f))
|
2007-05-05 05:59:01 -04:00
|
|
|
(cond
|
|
|
|
[(pair? ls)
|
|
|
|
(let ([d ($cdr ls)])
|
|
|
|
(for-each1 f ($car ls) d (len d d 0)))]
|
|
|
|
[(null? ls) (void)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "improper list")])]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(f ls ls2)
|
|
|
|
(unless (procedure? f)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "not a procedure" f))
|
2007-05-05 05:59:01 -04:00
|
|
|
(cond
|
|
|
|
[(pair? ls)
|
|
|
|
(if (pair? ls2)
|
|
|
|
(let ([d ($cdr ls)])
|
|
|
|
(for-each2 f
|
|
|
|
($car ls) ($car ls2) d ($cdr ls2) (len d d 0)))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "length mismatch"))]
|
2007-05-05 05:59:01 -04:00
|
|
|
[(null? ls)
|
|
|
|
(if (null? ls2)
|
|
|
|
(void)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "length mismatch"))]
|
|
|
|
[else (die who "not a list")])]
|
2007-09-09 23:50:55 -04:00
|
|
|
[(f ls . ls*)
|
|
|
|
(unless (procedure? f)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'for-each "not a procedure" f))
|
2007-09-09 23:50:55 -04:00
|
|
|
(unless (list? ls)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'for-each "not a list" ls))
|
2007-09-09 23:50:55 -04:00
|
|
|
(let ([n (length ls)])
|
|
|
|
(for-each
|
|
|
|
(lambda (x)
|
|
|
|
(unless (and (list? x) (= (length x) n))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'for-each "not a list" x)))
|
2007-09-09 23:50:55 -04:00
|
|
|
ls*)
|
|
|
|
(let loop ([n (length ls)] [ls ls] [ls* ls*])
|
|
|
|
(cond
|
|
|
|
[($fx= n 0)
|
|
|
|
(unless (and (null? ls) (andmap null? ls*))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'for-each "list modified" f))]
|
2007-09-09 23:50:55 -04:00
|
|
|
[else
|
|
|
|
(unless (and (pair? ls) (andmap pair? ls*))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'for-each "list modified" f))
|
2007-09-09 23:50:55 -04:00
|
|
|
(apply f (car ls) (map car ls*))
|
|
|
|
(loop (fx- n 1) (cdr ls) (map cdr ls*))])))])))
|
2007-05-05 05:29:35 -04:00
|
|
|
|
2007-05-05 06:02:02 -04:00
|
|
|
(module (andmap)
|
|
|
|
(define who 'andmap)
|
|
|
|
(define len
|
|
|
|
(lambda (h t n)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (eq? h t)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "circular list")
|
2007-05-05 06:02:02 -04:00
|
|
|
(len ($cdr h) ($cdr t) ($fx+ n 2)))
|
|
|
|
(if (null? h)
|
|
|
|
($fxadd1 n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "improper list"))))
|
2007-05-05 06:02:02 -04:00
|
|
|
(if (null? h)
|
|
|
|
n
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "improper list")))))
|
2007-05-05 06:02:02 -04:00
|
|
|
(define andmap1
|
|
|
|
(lambda (f a d n)
|
|
|
|
(cond
|
|
|
|
[(pair? d)
|
|
|
|
(if ($fxzero? n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered!")
|
2007-05-05 06:02:02 -04:00
|
|
|
(and (f a)
|
|
|
|
(andmap1 f ($car d) ($cdr d) ($fxsub1 n))))]
|
|
|
|
[(null? d)
|
|
|
|
(if ($fxzero? n)
|
|
|
|
(f a)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered"))]
|
|
|
|
[else (die who "list was altered")])))
|
2007-05-05 06:02:02 -04:00
|
|
|
(define andmap2
|
|
|
|
(lambda (f a1 a2 d1 d2 n)
|
|
|
|
(cond
|
|
|
|
[(pair? d1)
|
|
|
|
(cond
|
|
|
|
[(pair? d2)
|
|
|
|
(if ($fxzero? n)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die who "list was altered")
|
2007-05-05 06:02:02 -04:00
|
|
|
(and
|
|
|
|
(f a1 a2)
|
|
|
|
(andmap2 f
|
|
|
|
($car d1) ($car d2)
|
|
|
|
($cdr d1) ($cdr d2)
|
|
|
|
($fxsub1 n))))]
|
|