Create a new directory src/libraries, to hold R7RS libraries.
authorChris Hanson <org/chris-hanson/cph>
Wed, 23 Oct 2019 07:29:52 +0000 (00:29 -0700)
committerChris Hanson <org/chris-hanson/cph>
Sun, 27 Oct 2019 06:14:27 +0000 (23:14 -0700)
Initially populate this with (srfi 133) and (mit inline-testing), plus unit
tests for the former.

src/Makefile.in
src/Setup.sh
src/Tags.sh
src/configure.ac
src/etc/create-makefiles.sh
src/libraries/Makefile-fragment [new file with mode: 0644]
src/libraries/compile.scm [new file with mode: 0644]
src/libraries/inline-testing.scm [new file with mode: 0644]
src/libraries/srfi-133.scm [new file with mode: 0644]
tests/libraries/test-srfi-133.scm [new file with mode: 0644]

index 2e966f312a42a06eb082443b31b110fec017757e..39d140d18c8e380c05038d9222b2d9d2ef686dc5 100644 (file)
@@ -68,7 +68,7 @@ LIARC_BOOT_BUNDLES = compiler cref sf star-parser
 LIARC_BUNDLES = $(LIARC_BOOT_BUNDLES) ffi sos ssp xml
 
 SUBDIRS = $(INSTALLED_SUBDIRS) win32 xdoc
-INSTALLED_SUBDIRS = microcode runtime $(OPTION_SUBDIRS) $(LIARC_BUNDLES)
+INSTALLED_SUBDIRS = microcode runtime libraries $(OPTION_SUBDIRS) $(LIARC_BUNDLES)
 BASICS_SUBDIRS = microcode runtime $(LIARC_BUNDLES)
 OPTION_SUBDIRS = @OPTION_SUBDIRS@
 
@@ -557,6 +557,17 @@ ssp/ssp-unx.pkd: $(SSP_CREF_TARGETS)
 ### cross-compiler.  We should have a way to do that, and eliminate
 ### these.
 
+################
+# Libraries
+################
+
+.PHONY: compile-libraries
+compile-libraries: lib/all.com
+compile-libraries: microcode/scheme
+       (echo '(with-working-directory-pathname "libraries"' && \
+        echo '  (lambda () (load "compile")))') \
+       | ./run-build --batch-mode --no-init-file
+
 ################
 # blowfish
 ################
@@ -772,6 +783,7 @@ cross-target: $(X11_SCREEN_BUILD_TARGETS)
 cross-target: lib/all.com
 cross-target: lib/runtime.com
 cross-target: microcode/scheme
+cross-target: compile-libraries
 
 ################
 # Microcode
index 204ce6af4209b7d035b510da9c6e46a301682442..b8f9e1bed5a3fbeecf68de58992b2112727d753c 100755 (executable)
@@ -78,7 +78,7 @@ fi
 
 . etc/functions.sh
 
-INSTALLED_SUBDIRS="cref ffi sf sos ssp star-parser xml"
+INSTALLED_SUBDIRS="cref ffi libraries sf sos ssp star-parser xml"
 PLUGIN_SUBDIRS="blowfish edwin gdbm imail pgsql mcrypt x11 x11-screen"
 OTHER_SUBDIRS="6001 compiler runtime win32 xdoc microcode"
 
@@ -93,6 +93,7 @@ maybe_link lib/cref ../cref
 maybe_link lib/edwin ../edwin
 maybe_link lib/ffi ../ffi
 maybe_link lib/imail ../imail
+maybe_link lib/libraries ../libraries
 maybe_link lib/runtime ../runtime
 maybe_link lib/sf ../sf
 maybe_link lib/sos ../sos
index 94c15a3296ba8af37c674548b1f8338ac52ec67a..cda90aff235b3aba140611b4f158e810e31d67b3 100755 (executable)
@@ -37,6 +37,7 @@ DEFAULT_SUBDIRS=( \
     ffi \
     gdbm \
     imail \
+    libraries \
     mcrypt \
     microcode \
     pgsql \
index 5a4f7545074752efd4a8ff9b5e885203f013a4e3..4e150b2ff249b3826e989c6960827cde10bf9054 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 
-AC_INIT([MIT/GNU Scheme], [10.1.2], [bug-mit-scheme@gnu.org], [mit-scheme])
+AC_INIT([MIT/GNU Scheme], [10.90], [bug-mit-scheme@gnu.org], [mit-scheme])
 AC_CONFIG_SRCDIR([microcode/boot.c])
 AC_CONFIG_AUX_DIR([microcode])
 AC_PROG_MAKE_SET
@@ -441,6 +441,7 @@ Makefile.tools
 compiler/Makefile
 cref/Makefile
 ffi/Makefile
+libraries/Makefile
 runtime/Makefile
 sf/Makefile
 sos/Makefile
@@ -464,7 +465,7 @@ if test x"${mit_scheme_native_code}" = xc; then
         (cd lib; rm -f ${BN}; ${LN_S} ../${BN} .)
     done
     mkdir -p lib/lib
-    for BUNDLE in 6001 compiler cref ffi sf sos ssp star-parser \
+    for BUNDLE in 6001 compiler cref ffi libraries sf sos ssp star-parser \
                  xdoc xml; do
        SO=${BUNDLE}.so
        (cd lib/lib; rm -f ${SO}; ${LN_S} ../../${BUNDLE}/${SO} .)
index 37ef90bf02b773dd8e954102be153211f1082aa6..06408a3141a5a605b4a9401e816908784e07afe0 100755 (executable)
@@ -57,7 +57,7 @@ EOF
 
 run_cmd rm -f compiler/machine compiler/compiler.pkg
 
-for SUBDIR in ${BUNDLES} runtime win32; do
+for SUBDIR in ${BUNDLES} runtime libraries win32; do
     echo "creating ${SUBDIR}/Makefile.in"
     rm -f ${SUBDIR}/Makefile.in
     cat etc/std-makefile-prefix ${SUBDIR}/Makefile-fragment \
diff --git a/src/libraries/Makefile-fragment b/src/libraries/Makefile-fragment
new file mode 100644 (file)
index 0000000..07bcfb2
--- /dev/null
@@ -0,0 +1,6 @@
+TARGET_DIR = $(AUXDIR)/libraries
+
+install:
+       $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
+       $(INSTALL_COM) *.com $(DESTDIR)$(TARGET_DIR)/.
+       $(INSTALL_DATA) *.bci $(DESTDIR)$(TARGET_DIR)/.
diff --git a/src/libraries/compile.scm b/src/libraries/compile.scm
new file mode 100644 (file)
index 0000000..0579e39
--- /dev/null
@@ -0,0 +1,32 @@
+#| -*-Scheme-*-
+
+Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
+    2017, 2018, 2019 Massachusetts Institute of Technology
+
+This file is part of MIT/GNU Scheme.
+
+MIT/GNU Scheme is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+MIT/GNU Scheme 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 MIT/GNU Scheme; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+USA.
+
+|#
+
+(for-each (lambda (pn)
+           (if (not (string=? "compile" (pathname-name pn)))
+               (compile-file pn)))
+         (directory-read
+          (merge-pathnames "*.scm"
+                           (directory-pathname (current-load-pathname)))))
\ No newline at end of file
diff --git a/src/libraries/inline-testing.scm b/src/libraries/inline-testing.scm
new file mode 100644 (file)
index 0000000..064342e
--- /dev/null
@@ -0,0 +1,450 @@
+#| -*-Scheme-*-
+
+Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
+    2017, 2018, 2019 Massachusetts Institute of Technology
+
+This file is part of MIT/GNU Scheme.
+
+MIT/GNU Scheme is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+MIT/GNU Scheme 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 MIT/GNU Scheme; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+USA.
+
+|#
+
+;;;; Simple in-line tests
+
+;;; The idea behind this tester is that it executes a file of expressions, in
+;;; order, except that some of the expressions will be annotated with
+;;; "expectations" that must be satisfied by the evaluation of the corresponding
+;;; expression.
+
+;;; For example,
+;;;
+;;; (fib 20)
+;;; 'expect eqv? 6765
+;;;
+;;; is a trivial example.  There are also expectations involving
+;;; printed output, and others can be defined as needed.
+
+;;; This style of testing closely resembles a transcript, and has the advantage
+;;; that the code can just be loaded normally and it does the same thing without
+;;; checking the expectations.
+
+;;; This was developed as a response to GJS's dislike of the standard testing
+;;; framework.  Gerry prefers to just type at the interpreter and keep a
+;;; transcript of the results around; this closely mirrors his testing style.
+
+(define-library (mit inline-testing)
+  (import (scheme base)
+         (scheme char)
+         (scheme cxr)
+         (scheme eval)
+         (scheme read)
+         (scheme write)
+         (srfi 1)
+         (srfi 6)
+         (mit library)
+         (only (mit legacy runtime)
+               ->namestring
+               alist->bundle
+               bundle
+               call-with-output-string
+               call-with-truncated-output-string
+               call-with-truncated-output-string
+               condition?
+               default-object
+               default-object?
+               environment?
+               fresh-line
+               keyword-option-parser
+               make-bundle-predicate
+               make-settable-parameter
+               nearest-repl/environment
+               pathname-default-type
+               pp
+               read-file
+               warn
+               with-notification
+               write-to-string))
+  (export define-error-expectation
+         define-output-expectation
+         define-value-expectation
+         run-inline-tests)
+  (begin
+\f
+(define (run-inline-tests filename . options)
+  (let-values (((*eval *env *notify? *summarize?)
+               (run-option-parser options 'run-inline-tests))
+              ((exprs imports) (read-test-file filename)))
+    (let ((groups (parse-expression-groups exprs)))
+      (parameterize ((test-eval *eval)
+                    (test-env (if imports
+                                  (apply environment imports)
+                                  *env))
+                    (notify? *notify?)
+                    (summarize? *summarize?))
+       (summarize-test-results
+        (notify-filename filename
+          (lambda ()
+            (execute-expression-groups groups))))))))
+
+(define run-option-parser
+  (keyword-option-parser
+   (list (list 'eval procedure? (lambda () eval))
+        (list 'env environment? nearest-repl/environment)
+        (list 'notify? boolean? (lambda () #f))
+        (list 'summarize? boolean? (lambda () #t)))))
+
+(define test-eval (make-parameter (default-object)))
+(define test-env (make-parameter (default-object)))
+(define notify? (make-parameter (default-object)))
+(define summarize? (make-parameter (default-object)))
+
+(define (notify-filename filename thunk)
+  (if (notify?)
+      (with-notification
+         (lambda (port)
+           (display "loading test: " port)
+           (write (->namestring filename) port))
+       thunk)
+      (thunk)))
+\f
+(define (read-test-file filename)
+  (let ((pn (pathname-default-type filename "scm")))
+    (let ((source (read-r7rs-source pn)))
+      (if source
+         (let ((program (r7rs-source-program source)))
+           (if (not program)
+               (error "Inline testing requires a program:" source))
+           (if (not (null? (r7rs-source-libraries source)))
+               (error "Inline testing doesn't support inline libraries:"
+                      source))
+           (values (cdr (car (library-parsed-contents program)))
+                   (library-parsed-imports program)))
+         (values (read-file pn) #f)))))
+
+(define (parse-expression-groups exprs)
+  (if (pair? exprs)
+      (let ((to-eval (car exprs)))
+       (let ((r (parse-expectations (cdr exprs))))
+         (cons (make-group to-eval (reverse (car r)))
+               (parse-expression-groups (cdr r)))))
+      '()))
+
+(define make-group cons)
+(define group-expression car)
+(define group-expectations cdr)
+
+(define (parse-expectations exprs)
+  (let ((expectation
+        (and (pair? exprs)
+             (parse-expectation (car exprs)))))
+    (if expectation
+       (let ((r (parse-expectations (cdr exprs))))
+         (cons (cons expectation (car r))
+               (cdr r)))
+       (cons (list) exprs))))
+
+(define (parse-expectation expr)
+  (and (is-quotation? expr)
+       (let ((text (quotation-text expr)))
+        (let loop ((rules expectation-rules))
+          (if (pair? rules)
+              (or (match-rule (car rules) text)
+                  (loop (cdr rules)))
+              (begin
+                (warn "Unrecognized expectation:" text)
+                #f))))))
+
+(define (match-rule rule text)
+  (let ((keyword (expectation-rule-keyword rule))
+        (n-args (expectation-rule-n-args rule))
+        (handler (expectation-rule-handler rule)))
+    (cond ((and (pair? text)
+               (eq? (car text) keyword)
+               (list? (cdr text))
+               (= (length (cdr text)) n-args))
+          (cons handler (cdr text)))
+         ((and (eq? text keyword)
+               (= n-args 0))
+          (list handler))
+         (else #f))))
+
+(define (is-quotation? object)
+  (and (pair? object)
+       (eq? (car object) 'quote)
+       (pair? (cdr object))
+       (null? (cddr object))))
+
+(define (quotation-text expr)
+  (cadr expr))
+\f
+;;; Lots or hair here to let the test driver deal with "interesting" uses of
+;;; continuations.  In particular, the state of the driver is moved outside of
+;;; the control structure, so that if there are multiple returns from evaluating
+;;; an expression, the "current" expectations are used for each.
+
+(define groups-to-test (make-settable-parameter (default-object)))
+(define current-group (make-settable-parameter (default-object)))
+(define test-results (make-settable-parameter (default-object)))
+
+(define (execute-expression-groups groups)
+  (parameterize ((groups-to-test groups)
+                (current-group #f)
+                (test-results '()))
+    (let loop ()
+      (if (pair? (groups-to-test))
+          (begin
+            (current-group (car (groups-to-test)))
+            (groups-to-test (cdr (groups-to-test)))
+            (test-results
+            (cons (execute-expression-group (current-group))
+                  (test-results)))
+            (loop))))
+    (reverse (test-results))))
+
+(define (execute-expression-group group)
+  (let ((context (eval-to-context (car group))))
+    (cons (car group)
+         (filter-map (lambda (expectation)
+                       (apply (car expectation)
+                              context
+                              (map (lambda (expr)
+                                     (eval expr (test-env)))
+                                   (cdr expectation))))
+                     (cdr group)))))
+
+(define (eval-to-context expr)
+  (let ((output-port (open-output-string)))
+    (call-with-current-continuation
+      (lambda (k)
+       (with-exception-handler
+           (lambda (condition)
+             (k
+              (make-error-expectation-context
+               (get-output-string output-port)
+               condition)))
+         (lambda ()
+           (let ((value
+                  (parameterize ((current-output-port output-port))
+                    ((test-eval) expr (test-env)))))
+             (make-value-expectation-context
+              (get-output-string output-port)
+              value))))))))
+
+(define (make-error-expectation-context output condition)
+  (define (is-error?) #t)
+  (let ((port (open-input-string output)))
+    (define (get-port) port)
+    (define (get-condition) condition)
+    (bundle expectation-context? is-error? get-port get-condition)))
+
+(define (make-value-expectation-context output value)
+  (define (is-error?) #f)
+  (let ((port (open-input-string output)))
+    (define (get-port) port)
+    (define (get-value) value)
+    (bundle expectation-context? is-error? get-port get-value)))
+
+(define expectation-context?
+  (make-bundle-predicate 'expectation-context))
+\f
+(define (summarize-test-results results)
+  (if (summarize?)
+      (let ((failing-results (filter failing-test-result? results)))
+       (let ((failures (length failing-results))
+             (all (length results)))
+         (fresh-line)
+         (display "Ran ")
+         (write all)
+         (display " test")
+         (if (not (= 1 all))
+             (display "s"))
+         (display "; ")
+         (write failures)
+         (display " failure")
+         (if (not (= 1 failures))
+             (display "s")))
+       (for-each summarize-failing-result failing-results))))
+
+(define (failing-test-result? result)
+  (pair? (cdr result)))
+
+(define (summarize-failing-result failure)
+  (newline)
+  (newline)
+  (display "evaluating ")
+  (newline)
+  (pp (car failure))
+  (display "failed the following expectations:")
+  (newline)
+  (for-each (lambda (error)
+              (display error)
+              (newline))
+            (cdr failure)))
+
+(define (pp-to-string object)
+  (call-with-output-string
+    (lambda (port)
+      (pp object port))))
+\f
+;;;; Expectation rules
+
+(define (define-expectation keyword n-args handler)
+  (let ((rule (make-expectation-rule keyword n-args handler))
+        (tail
+         (find-tail (lambda (rule)
+                      (eq? keyword
+                           (expectation-rule-keyword rule)))
+                    expectation-rules)))
+    (if tail
+        (set-car! tail rule)
+        (set! expectation-rules
+              (cons rule
+                    expectation-rules)))))
+
+(define (define-error-expectation keyword n-args handler)
+  (define-expectation keyword n-args
+    (lambda (context . args)
+      (if (context 'is-error?)
+         (apply handler (context 'get-condition) args)
+         (string-append "expected error but instead got value\n"
+                        (write-to-string (context 'get-value)))))))
+
+(define (define-value-expectation keyword n-args handler)
+  (define-expectation keyword n-args
+    (lambda (context . args)
+      (if (context 'is-error?)
+         (string-append "Expected non-error but instead got error: "
+                        (write-to-string (context 'get-condition)))
+         (apply handler (context 'get-value) args)))))
+
+(define (define-output-expectation keyword n-args handler)
+  (define-expectation keyword n-args
+    (lambda (context . args)
+      (if (context 'is-error?)
+         (string-append "Expected non-error but instead got error: "
+                        (write-to-string (context 'get-condition)))
+         (let ((objects (read-objects (context 'get-port))))
+           (if (condition? objects)
+               "Error while reading output"
+               (apply handler objects args)))))))
+
+(define (read-objects port)
+  (call-with-current-continuation
+    (lambda (k)
+      (with-exception-handler
+         (lambda (condition)
+           (k condition))
+       (lambda ()
+         (let loop ((objects '()))
+           (let ((object (read port)))
+             (if (eof-object? object)
+                 (reverse objects)
+                 (loop (cons object objects))))))))))
+
+(define expectation-rules
+  '())
+
+(define (make-expectation-rule keyword n-args handler)
+  (list 'expectation-rule keyword n-args handler))
+
+(define expectation-rule-keyword cadr)
+(define expectation-rule-n-args caddr)
+(define expectation-rule-handler cadddr)
+\f
+(define-value-expectation 'expect 2
+  (lambda (value pred expected)
+    (if (pred expected value)
+       #f
+       (string-append "expected value\n"
+                      (write-to-string expected)
+                      "\nbut instead got value\n"
+                      (write-to-string value)))))
+
+(define-value-expectation 'expect-not 2
+  (lambda (value pred expected)
+    (if (pred expected value)
+       (string-append "expected value different from\n"
+                      (write-to-string expected)
+                      "\nbut instead got value\n"
+                      (write-to-string value))
+       #f)))
+
+(define-value-expectation 'expect-true 0
+  (lambda (value)
+    (if value
+       #f
+       (string-append "expected true value but got false"))))
+
+(define-value-expectation 'expect-false 0
+  (lambda (value)
+    (if value
+       (string-append "expected false value but got\n"
+                      (write-to-string value))
+       #f)))
+
+(define-error-expectation 'expect-error 0
+  (lambda (condition)
+    (declare (ignore condition))
+    #f))
+
+;;; General written output expectation.
+(define-output-expectation 'expect-output 2
+  (lambda (objects pred expected)
+    (let ((v (pred expected objects)))
+      (cond ((string? v) v)
+           ((eq? #t v) #f)
+           ((eq? #f v)
+            (string-append "Output\n"
+                           (pp-to-string objects)
+                           "doesn't satisfy predicate\n"
+                           (pp-to-string pred)
+                           "with expected value\n"
+                           (pp-to-string expected)))
+           (else
+            (error "illegal predicate value:" v))))))
+
+(define-output-expectation 'expect-write 1
+  (lambda (objects expected)
+    (if (and (pair? objects)
+            (null? (cdr objects))
+            (equal? (car objects) expected))
+       #f
+       (string-append "expected to see output "
+                      (write-to-string expected)
+                      "\nbut instead saw "
+                      (write-to-string objects)))))
+
+(define-output-expectation 'expect-pp-description 1
+  (lambda (objects expected)
+    (if (and (pair? objects)
+            (equal? (cdr objects) expected))
+       #f
+       (string-append "expected to see pp description "
+                      (write-to-string expected)
+                      "\nbut instead saw "
+                      (write-to-string objects)))))
+
+(define-output-expectation 'expect-no-output 0
+  (lambda (objects)
+    (if (null? objects)
+       #f
+       (string-append "expected no output but found "
+                      objects))))
+
+;; end of library
+))
\ No newline at end of file
diff --git a/src/libraries/srfi-133.scm b/src/libraries/srfi-133.scm
new file mode 100644 (file)
index 0000000..7ed1f62
--- /dev/null
@@ -0,0 +1,562 @@
+#| -*-Scheme-*-
+
+Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
+    2017, 2018, 2019 Massachusetts Institute of Technology
+
+This file is part of MIT/GNU Scheme.
+
+MIT/GNU Scheme is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+MIT/GNU Scheme 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 MIT/GNU Scheme; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+USA.
+
+|#
+
+;;;; SRFI 133
+
+;;; Loosely based on the SRFI's sample implementation.
+
+(define-library (srfi 133)
+  (import (scheme base)
+         (scheme cxr)
+         (srfi 8)
+         (only (mit legacy runtime)
+               error:bad-range-argument
+               fix:+
+               fix:-
+               fix:<
+               fix:<=
+               fix:=
+               fix:>
+               fix:>=
+               fix:end-index
+               fix:min
+               fix:quotient
+               fix:start-index
+               guarantee
+               index-fixnum?
+               unspecific))
+  (export reverse-list->vector
+         reverse-vector->list
+         vector-any
+         vector-append-subvectors
+         vector-cumulate
+         vector-empty?
+         vector-every
+         vector-fold
+         vector-fold-right
+         vector-index
+         vector-index-right
+         vector-map!
+         vector-partition
+         vector-reverse!
+         vector-reverse-copy
+         vector-skip
+         vector-skip-right
+         vector-swap!
+         vector-unfold
+         vector-unfold!
+         vector-unfold-right
+         vector-unfold-right!
+         vector=
+          vector-binary-search
+          vector-concatenate
+          vector-count
+          vector-reverse-copy!)
+  (begin
+\f
+;;; Constructors
+
+(define (vector-unfold proc n . initial-seeds)
+  (let ((v (make-vector n)))
+    (apply vector-unfold! proc v 0 n initial-seeds)
+    v))
+
+(define (vector-unfold-right proc n . initial-seeds)
+  (let ((v (make-vector n)))
+    (apply vector-unfold-right! proc v 0 n initial-seeds)
+    v))
+
+(define (vector-copy v #!optional start end)
+  (let* ((end (fix:end-index end (vector-length v) 'vector-copy))
+        (start (fix:start-index start end 'vector-copy))
+        (n (fix:- end start))
+        (result (make-vector n)))
+    (do ((i 0 (fix:+ i 1)))
+       ((not (fix:< i n)) result)
+      (vector-set! result i (vector-ref v (fix:+ start i))))))
+
+(define (vector-reverse-copy v #!optional start end)
+  (let* ((end (fix:end-index end (vector-length v) 'vector-reverse-copy))
+        (start (fix:start-index start end 'vector-reverse-copy))
+        (n (fix:- end start))
+        (last (fix:- end 1))
+        (result (make-vector n)))
+    (do ((i 0 (fix:+ i 1)))
+       ((not (fix:< i n)) result)
+      (vector-set! result i (vector-ref v (fix:- last i))))))
+
+(define (vector-append . vs)
+  (vector-concatenate vs))
+
+(define (vector-concatenate vs)
+  (let ((result
+        (make-vector
+         (let loop ((vs vs) (n 0))
+           (if (pair? vs)
+               (loop (cdr vs)
+                     (fix:+ (vector-length (car vs)) n))
+               n)))))
+    (let loop ((vs vs) (index 0))
+      (if (pair? vs)
+         (let* ((v (car vs))
+                (n (vector-length v)))
+           (do ((i 0 (fix:+ i 1))
+                (j index (fix:+ j 1)))
+               ((not (fix:< i n))
+                (loop (cdr vs) j))
+             (vector-set! result j (vector-ref v i))))
+         result))))
+
+(define (vector-append-subvectors . args)
+
+  (define (parse-specs args)
+    (let ((caller 'vector-append-subvectors))
+      (let loop ((args args) (specs '()))
+       (if (pair? args)
+           (loop (cdddr args)
+                 (cons (let* ((v (car args))
+                              (end
+                               (fix:end-index (caddr args)
+                                              (vector-length v)
+                                              caller)))
+                         (vector v
+                                 (fix:start-index (cadr args) end caller)
+                                 end))
+                       specs))
+           (reverse specs)))))
+
+  (define (compute-length specs)
+    (let loop ((specs specs) (n 0))
+      (if (pair? specs)
+         (loop (cdr specs)
+               (fix:+ n
+                      (fix:- (vector-ref (car specs) 2)
+                             (vector-ref (car specs) 1))))
+         n)))
+
+  (define (do-copies result specs)
+    (let loop ((specs specs) (at 0))
+      (if (pair? specs)
+         (let ((v (vector-ref (car specs) 0))
+               (start (vector-ref (car specs) 1))
+               (end (vector-ref (car specs) 2)))
+           (do ((i start (fix:+ i 1))
+                (at at (fix:+ at 1)))
+               ((not (fix:< i end))
+                (loop (cdr specs) at))
+             (vector-set! result at (vector-ref v i)))))))
+
+  (let* ((specs (parse-specs args))
+        (result (make-vector (compute-length specs))))
+    (do-copies result specs)
+    result))
+\f
+;;; Predicates
+
+(define (vector-empty? v)
+  (fix:= 0 (vector-length v)))
+
+(define (vector= elt= . vs)
+  (or (not (pair? vs))
+      (let* ((v (car vs))
+            (n (vector-length v)))
+       ;; Check lengths first since that's fast.
+       (and (let check-lengths ((vs* (cdr vs)))
+              (or (not (pair? vs*))
+                  (and (fix:= n (vector-length (car vs*)))
+                       (check-lengths (cdr vs*)))))
+            (let check-elts ((vs (cdr vs)))
+              (or (not (pair? vs))
+                  (let ((v* (car vs)))
+                    (let loop ((i 0))
+                      (if (fix:< i n)
+                          (and (elt= (vector-ref v i)
+                                     (vector-ref v* i))
+                               (loop (fix:+ i 1)))
+                          (check-elts (cdr vs)))))))))))
+\f
+;;; Iteration
+
+(define (vector-fold kons knil v . vs)
+  (if (null? vs)
+      (let ((n (vector-length v)))
+       (do ((i 0 (fix:+ i 1))
+            (knil* knil (kons knil* (vector-ref v i))))
+           ((not (fix:< i n)) knil*)))
+      (let* ((vs (cons v vs))
+            (n (vectors-length vs)))
+       (do ((i 0 (fix:+ i 1))
+            (knil* knil (apply kons knil* (vectors-ref vs i))))
+           ((not (fix:< i n)) knil*)))))
+
+(define (vector-fold-right kons knil v . vs)
+  (if (null? vs)
+      (do ((i (fix:- (vector-length v) 1) (fix:- i 1))
+          (knil* knil (kons knil* (vector-ref v i))))
+         ((not (fix:>= i 0)) knil*))
+      (let ((vs (cons v vs)))
+       (do ((i (fix:- (vectors-length vs) 1) (fix:- i 1))
+            (knil* knil (apply kons knil* (vectors-ref vs i))))
+           ((not (fix:>= i 0)) knil*)))))
+
+(define (vector-map proc v . vs)
+  (if (null? vs)
+      (let* ((n (vector-length v))
+            (target (make-vector n)))
+       (do ((i 0 (fix:+ i 1)))
+           ((not (fix:< i n)) target)
+         (vector-set! target i (proc (vector-ref v i)))))
+      (let* ((vs (cons v vs))
+            (n (vectors-length vs))
+            (target (make-vector n)))
+       (do ((i 0 (fix:+ i 1)))
+           ((not (fix:< i n)) target)
+         (vector-set! target i (apply proc (vectors-ref v i)))))))
+
+(define (vector-map! proc v . vs)
+  (if (null? vs)
+      (let* ((n (vector-length v)))
+       (do ((i 0 (fix:+ i 1)))
+           ((not (fix:< i n)) unspecific)
+         (vector-set! v i (proc (vector-ref v i)))))
+      (let* ((vs (cons v vs))
+            (n (vectors-length vs)))
+       (do ((i 0 (fix:+ i 1)))
+           ((not (fix:< i n)) unspecific)
+         (vector-set! v i (apply proc (vectors-ref vs i)))))))
+
+(define (vector-for-each proc v . vs)
+  (if (null? vs)
+      (let ((n (vector-length v)))
+       (do ((i 0 (fix:+ i 1)))
+           ((not (fix:< i n)) unspecific)
+         (proc (vector-ref v i))))
+      (let* ((vs (cons v vs))
+            (n (vectors-length vs)))
+       (do ((i 0 (fix:+ i 1)))
+           ((not (fix:< i n)) unspecific)
+         (apply proc (vectors-ref vs i))))))
+
+(define (vector-count pred v . vs)
+  (if (null? vs)
+      (let ((n (vector-length v)))
+       (do ((i 0 (fix:+ i 1))
+            (j 0 (if (pred (vector-ref v i)) (fix:+ j 1) j)))
+           ((not (fix:< i n)) j)))
+      (let* ((vs (cons v vs))
+            (n (vectors-length vs)))
+       (do ((i 0 (fix:+ i 1))
+            (j 0 (if (apply pred (vectors-ref vs i)) (fix:+ j 1) j)))
+           ((not (fix:< i n)) j)))))
+
+(define (vector-cumulate proc knil v)
+  (let* ((n (vector-length v))
+         (result (make-vector n)))
+    (let loop ((i 0) (left knil))
+      (if (fix:< i n)
+          (let ((left* (proc left (vector-ref v i))))
+            (vector-set! result i left*)
+            (loop (fix:+ i 1) left*))
+          result))))
+\f
+;;; Searching
+
+(define (vector-index pred v . vs)
+  (if (null? vs)
+      (let ((n (vector-length v)))
+       (let loop ((i 0))
+         (and (fix:< i n)
+              (if (pred (vector-ref v i))
+                  i
+                  (loop (fix:+ i 1))))))
+      (let* ((vs (cons v vs))
+            (n (vectors-length vs)))
+       (let loop ((i 0))
+         (and (fix:< i n)
+              (if (apply pred (vectors-ref vs i))
+                  i
+                  (loop (fix:+ i 1))))))))
+
+(define (vector-index-right pred v . vs)
+  (if (null? v)
+      (let loop ((i (fix:- (vector-length v) 1)))
+       (and (fix:>= i 0)
+            (if (pred (vector-ref v i))
+                i
+                (loop (fix:- i 1)))))
+      (let ((vs (cons v vs)))
+       (let loop ((i (fix:- (vectors-length vs) 1)))
+         (and (fix:>= i 0)
+              (if (apply pred (vectors-ref vs i))
+                  i
+                  (loop (fix:- i 1))))))))
+
+(define (vector-skip pred v . vs)
+  (if (null? vs)
+      (let ((n (vector-length v)))
+       (let loop ((i 0))
+         (and (fix:< i n)
+              (if (pred (vector-ref v i))
+                  (loop (fix:+ i 1))
+                  i))))
+      (let* ((vs (cons v vs))
+            (n (vectors-length vs)))
+       (let loop ((i 0))
+         (and (fix:< i n)
+              (if (apply pred (vectors-ref vs i))
+                  (loop (fix:+ i 1))
+                  i))))))
+
+(define (vector-skip-right pred v . vs)
+  (if (null? v)
+      (let loop ((i (fix:- (vector-length v) 1)))
+       (and (fix:>= i 0)
+            (if (pred (vector-ref v i))
+                (loop (fix:- i 1))
+                i)))
+      (let ((vs (cons v vs)))
+       (let loop ((i (fix:- (vectors-length vs) 1)))
+         (and (fix:>= i 0)
+              (if (apply pred (vectors-ref vs i))
+                  (loop (fix:- i 1))
+                  i))))))
+
+(define (vector-binary-search v value cmp)
+  (let loop ((start 0) (end (vector-length v)))
+    (and (fix:< start end)
+        (let ((midpoint (fix:quotient (fix:+ start end) 2)))
+          (let ((c (cmp (vector-ref v midpoint) value)))
+            (cond ((zero? c) midpoint)
+                  ((positive? c) (loop start midpoint))
+                  (else (loop (fix:+ midpoint 1) end))))))))
+
+(define (vector-any pred v . vs)
+  (if (null? vs)
+      (let ((n (vector-length v)))
+       (let loop ((i 0))
+         (and (fix:< i n)
+              (or (pred (vector-ref v i))
+                  (loop (fix:+ i 1))))))
+      (let ((vs (cons v vs))
+           (n (vectors-length vs)))
+       (let loop ((i 0))
+         (and (fix:< i n)
+              (or (apply pred (vectors-ref vs i))
+                  (loop (fix:+ i 1))))))))
+
+(define (vector-every pred v . vs)
+  (if (null? vs)
+      (let ((n (vector-length v)))
+       (let loop ((i 0))
+         (if (fix:< i n)
+             (and (pred (vector-ref v i))
+                  (loop (fix:+ i 1)))
+             #t)))
+      (let ((vs (cons v vs))
+           (n (vectors-length vs)))
+       (let loop ((i 0))
+         (if (fix:< i n)
+             (and (apply pred (vectors-ref vs i))
+                  (loop (fix:+ i 1)))
+             #t)))))
+
+(define (vector-partition pred v)
+  (let* ((n (vector-length v))
+         (result (make-vector n)))
+    (let loop ((i 0) (yes 0) (no (fix:- n 1)))
+      (if (fix:< i n)
+          (let ((elt (vector-ref v i)))
+            (if (pred elt)
+               (begin
+                 (vector-set! result yes elt)
+                 (loop (fix:+ i 1) (fix:+ yes 1) no))
+               (begin
+                 (vector-set! result no elt)
+                 (loop (fix:+ i 1) yes (fix:- no 1)))))
+         (begin
+           (%vector-reverse! result yes n)
+           (values result yes))))))
+\f
+;;; Mutators
+
+(define (vector-swap! v i1 i2)
+  (let ((x (vector-ref v i1)))
+    (vector-set! v i1 (vector-ref v i2))
+    (vector-set! v i2 x)))
+
+(define (vector-reverse! v #!optional start end)
+  (let ((end (fix:end-index end (vector-length v) 'vector-reverse!)))
+    (%vector-reverse! v
+                     (fix:start-index start end 'vector-reverse!)
+                     end)))
+
+(define (%vector-reverse! v start end)
+  (let loop ((i start) (j (fix:- end 1)))
+    (if (fix:< i j)
+       (let ((elt (vector-ref v i)))
+         (vector-set! v i (vector-ref v j))
+         (vector-set! v j elt)
+         (loop (fix:+ i 1) (fix:- j 1))))))
+
+(define (vector-copy! to at from #!optional start end)
+  (let* ((end (fix:end-index end (vector-length from) 'vector-copy!))
+        (start (fix:start-index start end 'vector-copy!)))
+    (let ((tend
+          (to-end-index at
+                        (fix:- end start)
+                        (vector-length to)
+                        'vector-copy!)))
+      (cond ((or (not (eq? to from)) (fix:< at start))
+            (do ((i start (fix:+ i 1))
+                 (j at (fix:+ j 1)))
+                ((not (fix:< i end)) unspecific)
+              (vector-set! to j (vector-ref from i))))
+           ((fix:> at start)
+            (do ((i (fix:- end 1) (fix:- i 1))
+                 (j (fix:- tend 1) (fix:- j 1)))
+                ((not (fix:>= i start)) unspecific)
+              (vector-set! to j (vector-ref from i))))))))
+
+(define (vector-reverse-copy! to at from #!optional start end)
+  (let* ((end (fix:end-index end (vector-length from) 'vector-reverse-copy!))
+        (start (fix:start-index start end 'vector-reverse-copy!)))
+    (let ((tend
+          (to-end-index at
+                        (fix:- end start)
+                        (vector-length to)
+                        'vector-copy!)))
+
+      (define (do-copy tend start end)
+       (do ((i start (fix:+ i 1))
+            (j (fix:- tend 1) (fix:- j 1)))
+           ((not (fix:< i end)) unspecific)
+         (vector-set! to j (vector-ref from i))))
+
+      (cond ((or (not (eq? to from)) (fix:<= end at) (fix:<= tend start))
+            (do-copy tend start end))
+           ((fix:< at start)
+            (do-copy at tend end)
+            (%vector-reverse! to start tend))
+           ((fix:> at start)
+            (do-copy start end tend)
+            (%vector-reverse! to at end))))))
+
+(define (vector-unfold! proc v start end . initial-seeds)
+  (let* ((end (fix:end-index end (vector-length v) 'vector-unfold!))
+        (start (fix:start-index start end 'vector-unfold!)))
+    (cond ((null? initial-seeds)
+          (do ((i start (fix:+ i 1)))
+              ((not (fix:< i end)) unspecific)
+            (vector-set! v i (proc i))))
+         ((null? (cdr initial-seeds))
+          (let loop ((i start) (seed (car initial-seeds)))
+            (if (fix:< i end)
+                (receive (elt seed*) (proc i seed)
+                  (vector-set! v i elt)
+                  (loop (fix:+ i 1) seed*)))))
+         (else
+          (let loop ((i start) (seeds initial-seeds))
+            (if (fix:< i end)
+                (receive (elt . seeds*) (apply proc i seeds)
+                  (vector-set! v i elt)
+                  (loop (fix:+ i 1) seeds*))))))))
+
+(define (vector-unfold-right! proc v start end . initial-seeds)
+  (let* ((end (fix:end-index end (vector-length v) 'vector-unfold!))
+        (start (fix:start-index start end 'vector-unfold!)))
+    (cond ((null? initial-seeds)
+          (do ((i (fix:- end 1) (fix:- i 1)))
+              ((not (fix:>= i start)) unspecific)
+            (vector-set! v i (proc i))))
+         ((null? (cdr initial-seeds))
+          (let loop ((i (fix:- end 1)) (seed (car initial-seeds)))
+            (if (fix:>= i start)
+                (receive (elt seed*) (proc i seed)
+                  (vector-set! v i elt)
+                  (loop (fix:- i 1) seed*)))))
+         (else
+          (let loop ((i (fix:- end 1)) (seeds initial-seeds))
+            (if (fix:>= i start)
+                (receive (elt . seeds*) (apply proc i seeds)
+                  (vector-set! v i elt)
+                  (loop (fix:- i 1) seeds*))))))))
+\f
+;;; Conversion
+
+(define (vector->list v #!optional start end)
+  (let* ((end (fix:end-index end (vector-length v) 'vector->list))
+        (start (fix:start-index start end 'vector->list)))
+    (do ((i (fix:- end 1) (fix:- i 1))
+        (result '() (cons (vector-ref v i) result)))
+       ((not (fix:>= i start)) result))))
+
+(define (reverse-vector->list v #!optional start end)
+  (let* ((end (fix:end-index end (vector-length v) 'reverse-vector->list))
+        (start (fix:start-index start end 'reverse-vector->list)))
+    (do ((i start (fix:+ i 1))
+        (result '() (cons (vector-ref v i) result)))
+       ((not (fix:< i end)) result))))
+
+(define (list->vector l)
+  (let* ((n (length l))
+        (result (make-vector n)))
+    (do ((i 0 (fix:+ i 1))
+        (l l (cdr l)))
+       ((not (fix:< i n)) result)
+      (vector-set! result i (car l)))))
+
+(define (reverse-list->vector l)
+  (let* ((n (length l))
+        (result (make-vector n)))
+    (do ((i (fix:- n 1) (fix:- i 1))
+        (l l (cdr l)))
+       ((not (fix:>= i 0)) result)
+      (vector-set! result i (car l)))))
+
+;;; Internal
+
+(define (vectors-ref vs i)
+  (let loop ((vs vs))
+    (if (pair? vs)
+       (cons (vector-ref (car vs) i)
+             (loop (cdr vs)))
+       '())))
+
+(define (vectors-length vs)
+  (let loop ((vs (cdr vs)) (n (vector-length (car vs))))
+    (if (pair? vs)
+       (loop (cdr vs) (fix:min n (vector-length (car vs))))
+       n)))
+
+(define (to-end-index start n limit caller)
+  (guarantee index-fixnum? start caller)
+  (let ((end (fix:+ start n)))
+    (if (not (fix:<= n limit))
+       (error:bad-range-argument start caller))
+    end))
+
+;; end of library
+))
\ No newline at end of file
diff --git a/tests/libraries/test-srfi-133.scm b/tests/libraries/test-srfi-133.scm
new file mode 100644 (file)
index 0000000..c597eb3
--- /dev/null
@@ -0,0 +1,219 @@
+(import (scheme base)
+       (srfi 133))
+
+(define v (make-vector 3 3))
+
+(vector? #(1 2 3)) 'expect-true
+(vector? (make-vector 10)) 'expect-true
+(vector-ref v 0) '(expect eqv? 3)
+(vector-ref v 1) '(expect eqv? 3)
+(vector-ref v 2) '(expect eqv? 3)
+(vector-ref v -1) 'expect-error
+(vector-ref v 3) 'expect-error
+
+(vector-set! v 0 -32)
+(vector-ref v 0) '(expect eqv? -32)
+(vector-length v) '(expect = 3)
+(vector-length '#()) '(expect = 0)
+
+(define a2i '#(a b c d e f g h i))
+
+(vector 0 1 2 3 4) '(expect equal? '#(0 1 2 3 4))
+(vector-copy a2i) '(expect equal? a2i)
+(vector-copy a2i) '(expect-not eqv? a2i)
+
+(vector-unfold (lambda (i x) (declare (ignore i)) (values x (- x 1))) 10 0)
+'(expect equal? '#(0 -1 -2 -3 -4 -5 -6 -7 -8 -9))
+(vector-unfold values 7)
+'(expect equal? '#(0 1 2 3 4 5 6))
+(vector-unfold-right (lambda (i x) (values (cons i x) (+ x 1))) 5 0)
+'(expect equal? '#((0 . 4) (1 . 3) (2 . 2) (3 . 1) (4 . 0)))
+
+(vector-copy a2i 6) '(expect equal? '#(g h i))
+(vector-copy a2i 3 6) '(expect equal? '#(d e f))
+(vector-reverse-copy '#(5 4 3 2 1 0) 1 5) '(expect equal? '#(1 2 3 4))
+
+(vector-append '#(x) '#(y)) '(expect equal? '#(x y))
+(vector-append '#(a) '#(b c d)) '(expect equal? '#(a b c d))
+(vector-append '#(a #(b)) '#(#(c))) '(expect equal? '#(a #(b) #(c)))
+(vector-concatenate '(#(a b) #(c d))) '(expect equal? '#(a b c d))
+
+(vector-append-subvectors '#(a b c d e) 0 2 '#(f g h i j) 2 4)
+'(expect equal? '#(a b h i))
+
+(vector-empty? '#(a)) 'expect-false
+(vector-empty? '#(())) 'expect-false
+(vector-empty? '#(#())) 'expect-false
+(vector-empty? '#()) 'expect-true
+(vector= eq? '#(a b c d) '#(a b c d)) 'expect-true
+(vector= eq? '#(a b c d) '#(a b d c)) 'expect-false
+(vector= = '#(1 2 3 4 5) '#(1 2 3 4)) 'expect-false
+(vector= = '#(+nan.0) '#(+nan.0)) 'expect-false
+(let ((nan '+nan.0)) (vector= = (vector nan) (vector nan))) 'expect-false
+(let ((nanvec '#(+nan.0))) (vector= = nanvec nanvec)) 'expect-false
+(vector= eq?) 'expect-true
+(vector= eq? '#(a)) 'expect-true
+(vector= eq? (vector (vector 'a)) (vector (vector 'a))) 'expect-false
+(vector= equal? (vector (vector 'a)) (vector (vector 'a))) 'expect-true
+
+(define vos '#("abc" "abcde" "abcd"))
+(define vec '#(0 1 2 3 4 5))
+(define vec2 (vector 0 1 2 3 4))
+(define vec3 (vector 1 2 3 4 5))
+(define result '())
+(define (sqr x) (* x x))
+(vector-fold (lambda (len str) (max (string-length str) len)) 0 vos)
+'(expect eqv? 5)
+(vector-fold (lambda (tail elt) (cons elt tail)) '() vec)
+'(expect equal? '(5 4 3 2 1 0))
+(vector-fold (lambda (ctr n) (if (even? n) (+ ctr 1) ctr)) 0 vec)
+'(expect eqv? 3)
+(vector-fold-right (lambda (tail elt) (cons elt tail)) '() '#(a b c d))
+'(expect equal? '(a b c d))
+(vector-map sqr '#(1 2 3 4))
+'(expect equal? '#(1 4 9 16))
+(vector-map * '#(1 2 3 4 5) '#(5 4 3 2 1))
+'(expect equal? '#(5 8 9 8 5))
+(vector-map! sqr vec2)
+(vector-copy vec2)
+'(expect equal? '#(0 1 4 9 16))
+(vector-map! * vec2 vec3)
+(vector-copy vec2)
+'(expect equal? '#(0 2 12 36 80))
+(vector-for-each (lambda (x) (set! result (cons x result))) vec)
+(cons (car result) (cdr result))
+'(expect equal? '(5 4 3 2 1 0))
+(vector-count even? '#(3 1 4 1 5 9 2 5 6))
+'(expect eqv? 3)
+(vector-count < '#(1 3 6 9) '#(2 4 6 8 10 12))
+'(expect eqv? 2)
+(vector-cumulate + 0 '#(3 1 4 1 5 9 2 5 6))
+'(expect equal? '#(3 4 8 9 14 23 25 30 36))
+
+(define (cmp a b)
+  (cond
+     ((< a b) -1)
+     ((= a b) 0)
+     (else 1)))
+(define v '#(0 2 4 6 8 10 12))
+(vector-index even? '#(3 1 4 1 5 9 6)) '(expect eqv? 2)
+(vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2)) '(expect eqv? 1)
+(vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2)) 'expect-false
+(vector-index-right odd? '#(3 1 4 1 5 9 6)) '(expect eqv? 5)
+(vector-index-right < '#(3 1 4 1 5) '#(2 7 1 8 2)) '(expect eqv? 3)
+(vector-skip number? '#(1 2 a b 3 4 c d)) '(expect eqv? 2)
+(vector-skip = '#(1 2 3 4 5) '#(1 2 -3 4)) '(expect eqv? 2)
+(vector-skip-right number? '#(1 2 a b 3 4 c d)) '(expect eqv? 7)
+(vector-skip-right = '#(1 2 3 4 5) '#(1 2 -3 -4 5)) '(expect eqv? 3)
+(vector-binary-search v 0 cmp) '(expect eqv? 0)
+(vector-binary-search v 6 cmp) '(expect eqv? 3)
+(vector-binary-search v 1 cmp) 'expect-false
+(vector-any number? '#(1 2 x y z)) 'expect-true
+(vector-any < '#(1 2 3 4 5) '#(2 1 3 4 5)) 'expect-true
+(vector-any number? '#(a b c d e)) 'expect-false
+(vector-any > '#(1 2 3 4 5) '#(1 2 3 4 5)) 'expect-false
+(vector-every number? '#(1 2 x y z)) 'expect-false
+(vector-every number? '#(1 2 3 4 5)) 'expect-true
+(vector-every < '#(1 2 3) '#(2 3 3)) 'expect-false
+(vector-every < '#(1 2 3) '#(2 3 4)) 'expect-true
+(vector-any (lambda (x) (if (number? x) 'yes #f)) '#(1 2 x y z))
+ '(expect eqv? 'yes)
+
+(define vp
+  (let-values (((new off) (vector-partition number? '#(1 x 2 y 3 z))))
+    (cons new off)))
+(vector-copy (car vp)) '(expect equal? '#(1 2 3 x y z))
+(cdr vp) '(expect eqv? 3)
+
+(define vs (vector 1 2 3))
+(define vf0 (vector 1 2 3))
+(define vf1 (vector 1 2 3))
+(define vf2 (vector 1 2 3))
+(define vr0 (vector 1 2 3))
+(define vr1 (vector 1 2 3))
+(define vr2 (vector 1 2 3))
+(define vc0 (vector 1 2 3 4 5))
+(define vc1 (vector 1 2 3 4 5))
+(define vc2 (vector 1 2 3 4 5))
+(define vrc0 (vector 1 2 3 4 5))
+(define vrc1 (vector 1 2 3 4 5))
+(define vrc2 (vector 1 2 3 4 5))
+(define vu0 (vector 1 2 3 4 5))
+(define vu1 (vector 1 2 3 4 5))
+(define vu2 (vector 1 2 3 4 5))
+(define vur0 (vector 1 2 3 4 5))
+(define vur1 (vector 1 2 3 4 5))
+(define vur2 (vector 1 2 3 4 5))
+(vector-swap! vs 0 1)
+(vector-copy vs)
+'(expect equal? '#(2 1 3))
+(vector-fill! vf0 0)
+(vector-copy vf0)
+'(expect equal? '#(0 0 0))
+(vector-fill! vf1 0 1)
+(vector-copy vf1)
+'(expect equal? '#(1 0 0))
+(vector-fill! vf2 0 0 1)
+(vector-copy vf2)
+'(expect equal? '#(0 2 3))
+(vector-reverse! vr0)
+(vector-copy vr0)
+'(expect equal? '#(3 2 1))
+(vector-reverse! vr1 1)
+(vector-copy vr1)
+'(expect equal? '#(1 3 2))
+(vector-reverse! vr2 0 2)
+(vector-copy vr2)
+'(expect equal? '#(2 1 3))
+(vector-copy! vc0 1 '#(10 20 30))
+(vector-copy vc0)
+'(expect equal? '#(1 10 20 30 5))
+(vector-copy! vc1 1 '#(0 10 20 30 40) 1)
+(vector-copy vc1)
+'(expect equal? '#(1 10 20 30 40))
+(vector-copy! vc2 1 '#(0 10 20 30 40) 1 4)
+(vector-copy vc2)
+'(expect equal? '#(1 10 20 30 5))
+(vector-reverse-copy! vrc0 1 '#(10 20 30))
+(vector-copy vrc0)
+'(expect equal? '#(1 30 20 10 5))
+(vector-reverse-copy! vrc1 1 '#(0 10 20 30 40) 1)
+(vector-copy vrc1)
+'(expect equal? '#(1 40 30 20 10))
+(vector-reverse-copy! vrc2 1 '#(0 10 20 30 40) 1 4)
+(vector-copy vrc2)
+'(expect equal? '#(1 30 20 10 5))
+(vector-unfold! (lambda (i) (+ 10 i)) vu0 1 4)
+(vector-copy vu0)
+'(expect equal? '#(1 11 12 13 5))
+(vector-unfold! (lambda (i x) (values (+ i x) (+ x 1))) vu1 1 4 0)
+(vector-copy vu1)
+'(expect equal? '#(1 1 3 5 5))
+(vector-unfold! (lambda (i x y) (values (+ i x y) (+ x 1) (+ x 1))) vu2 1 4 0 0)
+(vector-copy vu2)
+'(expect equal? '#(1 1 4 7 5))
+(vector-unfold-right! (lambda (i) (+ 10 i)) vur0 1 4)
+(vector-copy vur0)
+'(expect equal? '#(1 11 12 13 5))
+(vector-unfold-right! (lambda (i x) (values (+ i x) (+ x 1))) vur1 1 4 0)
+(vector-copy vur1)
+'(expect equal? '#(1 3 3 3 5))
+(vector-unfold-right! (lambda (i x y) (values (+ i x y) (+ x 1) (+ x 1)))
+                     vur2 1 4 0 0)
+(vector-copy vur2)
+'(expect equal? '#(1 5 4 3 5))
+
+(vector->list '#(1 2 3)) '(expect equal? '(1 2 3))
+(vector->list '#(1 2 3) 1) '(expect equal? '(2 3))
+(vector->list '#(1 2 3) 0 2) '(expect equal? '(1 2))
+(list->vector '(1 2 3)) '(expect equal? '#(1 2 3))
+(reverse-vector->list '#(1 2 3)) '(expect equal? '(3 2 1))
+(reverse-vector->list '#(1 2 3) 1) '(expect equal? '(3 2))
+(reverse-vector->list '#(1 2 3) 0 2) '(expect equal? '(2 1))
+(reverse-list->vector '(1 2 3)) '(expect equal? '#(3 2 1))
+(vector->string '#(#\a #\b #\c)) '(expect equal? "abc")
+(vector->string '#(#\a #\b #\c) 1) '(expect equal? "bc")
+(vector->string '#(#\a #\b #\c) 0 2) '(expect equal? "ab")
+(string->vector "abc") '(expect equal? '#(#\a #\b #\c))
+(string->vector "abc" 1) '(expect equal? '#(#\b #\c))
+(string->vector "abc" 0 2) '(expect equal? '#(#\a #\b))