srfi-43.scm 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  1. ;;;;;; SRFI 43: Vector library -*- Scheme -*-
  2. ;;; Taylor Campbell wrote this code; he places it in the public domain.
  3. ;;; --------------------
  4. ;;; Exported procedure index
  5. ;;;
  6. ;;; * Constructors
  7. ;;; make-vector vector
  8. ;;; vector-unfold vector-unfold-right
  9. ;;; vector-copy vector-reverse-copy
  10. ;;; vector-append vector-concatenate
  11. ;;;
  12. ;;; * Predicates
  13. ;;; vector?
  14. ;;; vector-empty?
  15. ;;; vector=
  16. ;;;
  17. ;;; * Selectors
  18. ;;; vector-ref
  19. ;;; vector-length
  20. ;;;
  21. ;;; * Iteration
  22. ;;; vector-fold vector-fold-right
  23. ;;; vector-map vector-map!
  24. ;;; vector-for-each
  25. ;;; vector-count
  26. ;;;
  27. ;;; * Searching
  28. ;;; vector-index vector-skip
  29. ;;; vector-index-right vector-skip-right
  30. ;;; vector-binary-search
  31. ;;; vector-any vector-every
  32. ;;;
  33. ;;; * Mutators
  34. ;;; vector-set!
  35. ;;; vector-swap!
  36. ;;; vector-fill!
  37. ;;; vector-reverse!
  38. ;;; vector-copy! vector-reverse-copy!
  39. ;;; vector-reverse!
  40. ;;;
  41. ;;; * Conversion
  42. ;;; vector->list reverse-vector->list
  43. ;;; list->vector reverse-list->vector
  44. ;;; --------------------
  45. ;;; Commentary on efficiency of the code
  46. ;;; This code is somewhat tuned for efficiency. There are several
  47. ;;; internal routines that can be optimized greatly to greatly improve
  48. ;;; the performance of much of the library. These internal procedures
  49. ;;; are already carefully tuned for performance, and lambda-lifted by
  50. ;;; hand. Some other routines are lambda-lifted by hand, but only the
  51. ;;; loops are lambda-lifted, and only if some routine has two possible
  52. ;;; loops -- a fast path and an n-ary case --, whereas _all_ of the
  53. ;;; internal routines' loops are lambda-lifted so as to never cons a
  54. ;;; closure in their body (VECTOR-PARSE-START+END doesn't have a loop),
  55. ;;; even in Scheme systems that perform no loop optimization (which is
  56. ;;; most of them, unfortunately).
  57. ;;;
  58. ;;; Fast paths are provided for common cases in most of the loops in
  59. ;;; this library.
  60. ;;;
  61. ;;; All calls to primitive vector operations are protected by a prior
  62. ;;; type check; they can be safely converted to use unsafe equivalents
  63. ;;; of the operations, if available. Ideally, the compiler should be
  64. ;;; able to determine this, but the state of Scheme compilers today is
  65. ;;; not a happy one.
  66. ;;;
  67. ;;; Efficiency of the actual algorithms is a rather mundane point to
  68. ;;; mention; vector operations are rarely beyond being straightforward.
  69. ;;; --------------------
  70. ;;; Utilities
  71. ;;; Not the best LET*-OPTIONALS, but not the worst, either. Use Olin's
  72. ;;; if it's available to you.
  73. (define-syntax let*-optionals
  74. (syntax-rules ()
  75. ((let*-optionals (?x ...) ((?var ?default) ...) ?body1 ?body2 ...)
  76. (let ((args (?x ...)))
  77. (let*-optionals args ((?var ?default) ...) ?body1 ?body2 ...)))
  78. ((let*-optionals ?args ((?var ?default) ...) ?body1 ?body2 ...)
  79. (let*-optionals:aux ?args ?args ((?var ?default) ...)
  80. ?body1 ?body2 ...))))
  81. (define-syntax let*-optionals:aux
  82. (syntax-rules ()
  83. ((aux ?orig-args-var ?args-var () ?body1 ?body2 ...)
  84. (if (null? ?args-var)
  85. (let () ?body1 ?body2 ...)
  86. (error "too many arguments" (length ?orig-args-var)
  87. ?orig-args-var)))
  88. ((aux ?orig-args-var ?args-var
  89. ((?var ?default) ?more ...)
  90. ?body1 ?body2 ...)
  91. (if (null? ?args-var)
  92. (let* ((?var ?default) ?more ...) ?body1 ?body2 ...)
  93. (let ((?var (car ?args-var))
  94. (new-args (cdr ?args-var)))
  95. (let*-optionals:aux ?orig-args-var new-args
  96. (?more ...)
  97. ?body1 ?body2 ...))))))
  98. (define (nonneg-int? x)
  99. (and (integer? x)
  100. (not (negative? x))))
  101. (define (between? x y z)
  102. (and (< x y)
  103. (<= y z)))
  104. ; (define (unspecified-value) (if #f #f))
  105. ;++ This should be implemented more efficiently. It shouldn't cons a
  106. ;++ closure, and the cons cells used in the loops when using this could
  107. ;++ be reused.
  108. (define (vectors-ref vectors i)
  109. (map (lambda (v) (vector-ref v i)) vectors))
  110. ;;; --------------------
  111. ;;; Error checking
  112. ;;; Error signalling (not checking) is done in a way that tries to be
  113. ;;; as helpful to the person who gets the debugging prompt as possible.
  114. ;;; That said, error _checking_ tries to be as unredundant as possible.
  115. ;;; I don't use any sort of general condition mechanism; I use simply
  116. ;;; SRFI 23's ERROR, even in cases where it might be better to use such
  117. ;;; a general condition mechanism. Fix that when porting this to a
  118. ;;; Scheme implementation that has its own condition system.
  119. ;;; In argument checks, upon receiving an invalid argument, the checker
  120. ;;; procedure recursively calls itself, but in one of the arguments to
  121. ;;; itself is a call to ERROR; this mechanism is used in the hopes that
  122. ;;; the user may be thrown into a debugger prompt, proceed with another
  123. ;;; value, and let it be checked again.
  124. ;;; Type checking is pretty basic, but easily factored out and replaced
  125. ;;; with whatever your implementation's preferred type checking method
  126. ;;; is. I doubt there will be many other methods of index checking,
  127. ;;; though the index checkers might be better implemented natively.
  128. ;;; (CHECK-TYPE <type-predicate?> <value> <callee>) -> value
  129. ;;; Ensure that VALUE satisfies TYPE-PREDICATE?; if not, signal an
  130. ;;; error stating that VALUE did not satisfy TYPE-PREDICATE?, showing
  131. ;;; that this happened while calling CALLEE. Return VALUE if no
  132. ;;; error was signalled.
  133. (define (check-type pred? value callee)
  134. (if (pred? value)
  135. value
  136. ;; Recur: when (or if) the user gets a debugger prompt, he can
  137. ;; proceed where the call to ERROR was with the correct value.
  138. (check-type pred?
  139. (error "erroneous value"
  140. (list pred? value)
  141. `(while calling ,callee))
  142. callee)))
  143. ;;; (CHECK-INDEX <vector> <index> <callee>) -> index
  144. ;;; Ensure that INDEX is a valid index into VECTOR; if not, signal an
  145. ;;; error stating that it is not and that this happened in a call to
  146. ;;; CALLEE. Return INDEX when it is valid. (Note that this does NOT
  147. ;;; check that VECTOR is indeed a vector.)
  148. (define (check-index vec index callee)
  149. (let ((index (check-type integer? index callee)))
  150. (cond ((< index 0)
  151. (check-index vec
  152. (error "vector index too low"
  153. index
  154. `(into vector ,vec)
  155. `(while calling ,callee))
  156. callee))
  157. ((>= index (vector-length vec))
  158. (check-index vec
  159. (error "vector index too high"
  160. index
  161. `(into vector ,vec)
  162. `(while calling ,callee))
  163. callee))
  164. (else index))))
  165. ;;; (CHECK-INDICES <vector>
  166. ;;; <start> <start-name>
  167. ;;; <end> <end-name>
  168. ;;; <caller>) -> [start end]
  169. ;;; Ensure that START and END are valid bounds of a range within
  170. ;;; VECTOR; if not, signal an error stating that they are not, with
  171. ;;; the message being informative about what the argument names were
  172. ;;; called -- by using START-NAME & END-NAME --, and that it occurred
  173. ;;; while calling CALLEE. Also ensure that VEC is in fact a vector.
  174. ;;; Returns no useful value.
  175. (define (check-indices vec start start-name end end-name callee)
  176. (let ((lose (lambda things
  177. (apply error "vector range out of bounds"
  178. (append things
  179. `(vector was ,vec)
  180. `(,start-name was ,start)
  181. `(,end-name was ,end)
  182. `(while calling ,callee)))))
  183. (start (check-type integer? start callee))
  184. (end (check-type integer? end callee)))
  185. (cond ((> start end)
  186. ;; I'm not sure how well this will work. The intent is that
  187. ;; the programmer tells the debugger to proceed with both a
  188. ;; new START & a new END by returning multiple values
  189. ;; somewhere.
  190. (receive (new-start new-end)
  191. (lose `(,end-name < ,start-name))
  192. (check-indices vec
  193. new-start start-name
  194. new-end end-name
  195. callee)))
  196. ((< start 0)
  197. (check-indices vec
  198. (lose `(,start-name < 0))
  199. start-name
  200. end end-name
  201. callee))
  202. ((>= start (vector-length vec))
  203. (check-indices vec
  204. (lose `(,start-name > len)
  205. `(len was ,(vector-length vec)))
  206. start-name
  207. end end-name
  208. callee))
  209. ((> end (vector-length vec))
  210. (check-indices vec
  211. start start-name
  212. (lose `(,end-name > len)
  213. `(len was ,(vector-length vec)))
  214. end-name
  215. callee))
  216. (else
  217. (values start end)))))
  218. ;;; --------------------
  219. ;;; Internal routines
  220. ;;; These should all be integrated, native, or otherwise optimized --
  221. ;;; they're used a _lot_ --. All of the loops and LETs inside loops
  222. ;;; are lambda-lifted by hand, just so as not to cons closures in the
  223. ;;; loops. (If your compiler can do better than that if they're not
  224. ;;; lambda-lifted, then lambda-drop (?) them.)
  225. ;;; (VECTOR-PARSE-START+END <vector> <arguments>
  226. ;;; <start-name> <end-name>
  227. ;;; <callee>)
  228. ;;; -> [start end]
  229. ;;; Return two values, composing a valid range within VECTOR, as
  230. ;;; extracted from ARGUMENTS or defaulted from VECTOR -- 0 for START
  231. ;;; and the length of VECTOR for END --; START-NAME and END-NAME are
  232. ;;; purely for error checking.
  233. (define (vector-parse-start+end vec args start-name end-name callee)
  234. (let ((len (vector-length vec)))
  235. (cond ((null? args)
  236. (values 0 len))
  237. ((null? (cdr args))
  238. (check-indices vec
  239. (car args) start-name
  240. len end-name
  241. callee))
  242. ((null? (cddr args))
  243. (check-indices vec
  244. (car args) start-name
  245. (cadr args) end-name
  246. callee))
  247. (else
  248. (error "too many arguments"
  249. `(extra args were ,(cddr args))
  250. `(while calling ,callee))))))
  251. (define-syntax let-vector-start+end
  252. (syntax-rules ()
  253. ((let-vector-start+end ?callee ?vec ?args (?start ?end)
  254. ?body1 ?body2 ...)
  255. (let ((?vec (check-type vector? ?vec ?callee)))
  256. (receive (?start ?end)
  257. (vector-parse-start+end ?vec ?args '?start '?end
  258. ?callee)
  259. ?body1 ?body2 ...)))))
  260. ;;; (%SMALLEST-LENGTH <vector-list> <default-length> <callee>)
  261. ;;; -> exact, nonnegative integer
  262. ;;; Compute the smallest length of VECTOR-LIST. DEFAULT-LENGTH is
  263. ;;; the length that is returned if VECTOR-LIST is empty. Common use
  264. ;;; of this is in n-ary vector routines:
  265. ;;; (define (f vec . vectors)
  266. ;;; (let ((vec (check-type vector? vec f)))
  267. ;;; ...(%smallest-length vectors (vector-length vec) f)...))
  268. ;;; %SMALLEST-LENGTH takes care of the type checking -- which is what
  269. ;;; the CALLEE argument is for --; thus, the design is tuned for
  270. ;;; avoiding redundant type checks.
  271. (define %smallest-length
  272. (letrec ((loop (lambda (vector-list length callee)
  273. (if (null? vector-list)
  274. length
  275. (loop (cdr vector-list)
  276. (min (vector-length
  277. (check-type vector?
  278. (car vector-list)
  279. callee))
  280. length)
  281. callee)))))
  282. loop))
  283. ;;; (%VECTOR-COPY! <target> <tstart> <source> <sstart> <send>)
  284. ;;; Copy elements at locations SSTART to SEND from SOURCE to TARGET,
  285. ;;; starting at TSTART in TARGET.
  286. ;;;
  287. ;;; Optimize this! Probably with some combination of:
  288. ;;; - Force it to be integrated.
  289. ;;; - Let it use unsafe vector element dereferencing routines: bounds
  290. ;;; checking already happens outside of it. (Or use a compiler
  291. ;;; that figures this out, but Olin Shivers' PhD thesis seems to
  292. ;;; have been largely ignored in actual implementations...)
  293. ;;; - Implement it natively as a VM primitive: the VM can undoubtedly
  294. ;;; perform much faster than it can make Scheme perform, even with
  295. ;;; bounds checking.
  296. ;;; - Implement it in assembly: you _want_ the fine control that
  297. ;;; assembly can give you for this.
  298. ;;; I already lambda-lift it by hand, but you should be able to make it
  299. ;;; even better than that.
  300. (define %vector-copy!
  301. (letrec ((loop/l->r (lambda (target source send i j)
  302. (cond ((< i send)
  303. (vector-set! target j
  304. (vector-ref source i))
  305. (loop/l->r target source send
  306. (+ i 1) (+ j 1))))))
  307. (loop/r->l (lambda (target source sstart i j)
  308. (cond ((>= i sstart)
  309. (vector-set! target j
  310. (vector-ref source i))
  311. (loop/r->l target source sstart
  312. (- i 1) (- j 1)))))))
  313. (lambda (target tstart source sstart send)
  314. (if (> sstart tstart) ; Make sure we don't copy over
  315. ; ourselves.
  316. (loop/l->r target source send sstart tstart)
  317. (loop/r->l target source sstart (- send 1)
  318. (+ -1 tstart send (- sstart)))))))
  319. ;;; (%VECTOR-REVERSE-COPY! <target> <tstart> <source> <sstart> <send>)
  320. ;;; Copy elements from SSTART to SEND from SOURCE to TARGET, in the
  321. ;;; reverse order.
  322. (define %vector-reverse-copy!
  323. (letrec ((loop (lambda (target source sstart i j)
  324. (cond ((>= i sstart)
  325. (vector-set! target j (vector-ref source i))
  326. (loop target source sstart
  327. (- i 1)
  328. (+ j 1)))))))
  329. (lambda (target tstart source sstart send)
  330. (loop target source sstart
  331. (- send 1)
  332. tstart))))
  333. ;;; (%VECTOR-REVERSE! <vector>)
  334. (define %vector-reverse!
  335. (letrec ((loop (lambda (vec i j)
  336. (cond ((<= i j)
  337. (let ((v (vector-ref vec i)))
  338. (vector-set! vec i (vector-ref vec j))
  339. (vector-set! vec j v)
  340. (loop vec (+ i 1) (- j 1))))))))
  341. (lambda (vec start end)
  342. (loop vec start (- end 1)))))
  343. ;;; (%VECTOR-FOLD1 <kons> <knil> <vector>) -> knil'
  344. ;;; (KONS <index> <knil> <elt>) -> knil'
  345. (define %vector-fold1
  346. (letrec ((loop (lambda (kons knil len vec i)
  347. (if (= i len)
  348. knil
  349. (loop kons
  350. (kons i knil (vector-ref vec i))
  351. len vec (+ i 1))))))
  352. (lambda (kons knil len vec)
  353. (loop kons knil len vec 0))))
  354. ;;; (%VECTOR-FOLD2+ <kons> <knil> <vector> ...) -> knil'
  355. ;;; (KONS <index> <knil> <elt> ...) -> knil'
  356. (define %vector-fold2+
  357. (letrec ((loop (lambda (kons knil len vectors i)
  358. (if (= i len)
  359. knil
  360. (loop kons
  361. (apply kons i knil
  362. (vectors-ref vectors i))
  363. len vectors (+ i 1))))))
  364. (lambda (kons knil len vectors)
  365. (loop kons knil len vectors 0))))
  366. ;;; (%VECTOR-MAP! <f> <target> <length> <vector>) -> target
  367. ;;; (F <index> <elt>) -> elt'
  368. (define %vector-map1!
  369. (letrec ((loop (lambda (f target vec i)
  370. (if (zero? i)
  371. target
  372. (let ((j (- i 1)))
  373. (vector-set! target j
  374. (f j (vector-ref vec j)))
  375. (loop f target vec j))))))
  376. (lambda (f target vec len)
  377. (loop f target vec len))))
  378. ;;; (%VECTOR-MAP2+! <f> <target> <vectors> <len>) -> target
  379. ;;; (F <index> <elt> ...) -> elt'
  380. (define %vector-map2+!
  381. (letrec ((loop (lambda (f target vectors i)
  382. (if (zero? i)
  383. target
  384. (let ((j (- i 1)))
  385. (vector-set! target j
  386. (apply f j (vectors-ref vectors j)))
  387. (loop f target vectors j))))))
  388. (lambda (f target vectors len)
  389. (loop f target vectors len))))
  390. ;;;;;;;;;;;;;;;;;;;;;;;; ***** vector-lib ***** ;;;;;;;;;;;;;;;;;;;;;;;
  391. ;;; --------------------
  392. ;;; Constructors
  393. ;;; (MAKE-VECTOR <size> [<fill>]) -> vector
  394. ;;; [R5RS] Create a vector of length LENGTH. If FILL is present,
  395. ;;; initialize each slot in the vector with it; if not, the vector's
  396. ;;; initial contents are unspecified.
  397. ;(define make-vector make-vector)
  398. ;;; (VECTOR <elt> ...) -> vector
  399. ;;; [R5RS] Create a vector containing ELEMENT ..., in order.
  400. ;(define vector vector)
  401. ;;; This ought to be able to be implemented much more efficiently -- if
  402. ;;; we have the number of arguments available to us, we can create the
  403. ;;; vector without using LENGTH to determine the number of elements it
  404. ;;; should have.
  405. ;(define (vector . elements) (list->vector elements))
  406. ;;; (VECTOR-UNFOLD <f> <length> <initial-seed> ...) -> vector
  407. ;;; (F <index> <seed> ...) -> [elt seed' ...]
  408. ;;; The fundamental vector constructor. Creates a vector whose
  409. ;;; length is LENGTH and iterates across each index K between 0 and
  410. ;;; LENGTH, applying F at each iteration to the current index and the
  411. ;;; current seeds to receive N+1 values: first, the element to put in
  412. ;;; the Kth slot and then N new seeds for the next iteration.
  413. (define vector-unfold
  414. (letrec ((tabulate! ; Special zero-seed case.
  415. (lambda (f vec i len)
  416. (cond ((< i len)
  417. (vector-set! vec i (f i))
  418. (tabulate! f vec (+ i 1) len)))))
  419. (unfold1! ; Fast path for one seed.
  420. (lambda (f vec i len seed)
  421. (if (< i len)
  422. (receive (elt new-seed)
  423. (f i seed)
  424. (vector-set! vec i elt)
  425. (unfold1! f vec (+ i 1) len new-seed)))))
  426. (unfold2+! ; Slower variant for N seeds.
  427. (lambda (f vec i len seeds)
  428. (if (< i len)
  429. (receive (elt . new-seeds)
  430. (apply f i seeds)
  431. (vector-set! vec i elt)
  432. (unfold2+! f vec (+ i 1) len new-seeds))))))
  433. (lambda (f len . initial-seeds)
  434. (let ((f (check-type procedure? f vector-unfold))
  435. (len (check-type nonneg-int? len vector-unfold)))
  436. (let ((vec (make-vector len)))
  437. (cond ((null? initial-seeds)
  438. (tabulate! f vec 0 len))
  439. ((null? (cdr initial-seeds))
  440. (unfold1! f vec 0 len (car initial-seeds)))
  441. (else
  442. (unfold2+! f vec 0 len initial-seeds)))
  443. vec)))))
  444. ;;; (VECTOR-UNFOLD-RIGHT <f> <length> <initial-seed> ...) -> vector
  445. ;;; (F <seed> ...) -> [seed' ...]
  446. ;;; Like VECTOR-UNFOLD, but it generates elements from LENGTH to 0
  447. ;;; (still exclusive with LENGTH and inclusive with 0), not 0 to
  448. ;;; LENGTH as with VECTOR-UNFOLD.
  449. (define vector-unfold-right
  450. (letrec ((tabulate!
  451. (lambda (f vec i)
  452. (cond ((>= i 0)
  453. (vector-set! vec i (f i))
  454. (tabulate! f vec (- i 1))))))
  455. (unfold1!
  456. (lambda (f vec i seed)
  457. (if (>= i 0)
  458. (receive (elt new-seed)
  459. (f i seed)
  460. (vector-set! vec i elt)
  461. (unfold1! f vec (- i 1) new-seed)))))
  462. (unfold2+!
  463. (lambda (f vec i seeds)
  464. (if (>= i 0)
  465. (receive (elt . new-seeds)
  466. (apply f i seeds)
  467. (vector-set! vec i elt)
  468. (unfold2+! f vec (- i 1) new-seeds))))))
  469. (lambda (f len . initial-seeds)
  470. (let ((f (check-type procedure? f vector-unfold-right))
  471. (len (check-type nonneg-int? len vector-unfold-right)))
  472. (let ((vec (make-vector len))
  473. (i (- len 1)))
  474. (cond ((null? initial-seeds)
  475. (tabulate! f vec i))
  476. ((null? (cdr initial-seeds))
  477. (unfold1! f vec i (car initial-seeds)))
  478. (else
  479. (unfold2+! f vec i initial-seeds)))
  480. vec)))))
  481. ;;; (VECTOR-COPY <vector> [<start> <end> <fill>]) -> vector
  482. ;;; Create a newly allocated vector containing the elements from the
  483. ;;; range [START,END) in VECTOR. START defaults to 0; END defaults
  484. ;;; to the length of VECTOR. END may be greater than the length of
  485. ;;; VECTOR, in which case the vector is enlarged; if FILL is passed,
  486. ;;; the new locations from which there is no respective element in
  487. ;;; VECTOR are filled with FILL.
  488. (define (vector-copy vec . args)
  489. (let ((vec (check-type vector? vec vector-copy)))
  490. ;; We can't use LET-VECTOR-START+END, because we have one more
  491. ;; argument, and we want finer control, too.
  492. ;;
  493. ;; Olin's implementation of LET*-OPTIONALS would prove useful here:
  494. ;; the built-in argument-checks-as-you-go-along produces almost
  495. ;; _exactly_ the same code as VECTOR-COPY:PARSE-ARGS.
  496. (receive (start end fill)
  497. (vector-copy:parse-args vec args)
  498. (let ((new-vector (make-vector (- end start) fill)))
  499. (%vector-copy! new-vector 0
  500. vec start
  501. (if (> end (vector-length vec))
  502. (vector-length vec)
  503. end))
  504. new-vector))))
  505. ;;; Auxiliary for VECTOR-COPY.
  506. (define (vector-copy:parse-args vec args)
  507. (if (null? args)
  508. (values 0 (vector-length vec) (unspecified-value))
  509. (let ((start (check-index vec (car args) vector-copy)))
  510. (if (null? (cdr args))
  511. (values start (vector-length vec) (unspecified-value))
  512. (let ((end (check-type nonneg-int? (cadr args)
  513. vector-copy)))
  514. (cond ((>= start (vector-length vec))
  515. (error "start bound out of bounds"
  516. `(start was ,start)
  517. `(end was ,end)
  518. `(vector was ,vec)
  519. `(while calling ,vector-copy)))
  520. ((> start end)
  521. (error "can't invert a vector copy!"
  522. `(start was ,start)
  523. `(end was ,end)
  524. `(vector was ,vec)
  525. `(while calling ,vector-copy)))
  526. ((null? (cddr args))
  527. (values start end (unspecified-value)))
  528. (else
  529. (let ((fill (caddr args)))
  530. (if (null? (cdddr args))
  531. (values start end fill)
  532. (error "too many arguments"
  533. vector-copy
  534. (cdddr args)))))))))))
  535. ;;; (VECTOR-REVERSE-COPY <vector> [<start> <end>]) -> vector
  536. ;;; Create a newly allocated vector whose elements are the reversed
  537. ;;; sequence of elements between START and END in VECTOR. START's
  538. ;;; default is 0; END's default is the length of VECTOR.
  539. (define (vector-reverse-copy vec . maybe-start+end)
  540. (let-vector-start+end vector-reverse-copy vec maybe-start+end
  541. (start end)
  542. (let ((new (make-vector (- end start))))
  543. (%vector-reverse-copy! new 0 vec start end)
  544. new)))
  545. ;;; (VECTOR-APPEND <vector> ...) -> vector
  546. ;;; Append VECTOR ... into a newly allocated vector and return that
  547. ;;; new vector.
  548. (define (vector-append . vectors)
  549. (vector-concatenate:aux vectors vector-append))
  550. ;;; (VECTOR-CONCATENATE <vector-list>) -> vector
  551. ;;; Concatenate the vectors in VECTOR-LIST. This is equivalent to
  552. ;;; (apply vector-append VECTOR-LIST)
  553. ;;; but VECTOR-APPEND tends to be implemented in terms of
  554. ;;; VECTOR-CONCATENATE, and some Schemes bork when the list to apply
  555. ;;; a function to is too long.
  556. ;;;
  557. ;;; Actually, they're both implemented in terms of an internal routine.
  558. (define (vector-concatenate vector-list)
  559. (vector-concatenate:aux vector-list vector-concatenate))
  560. ;;; Auxiliary for VECTOR-APPEND and VECTOR-CONCATENATE
  561. (define vector-concatenate:aux
  562. (letrec ((compute-length
  563. (lambda (vectors len callee)
  564. (if (null? vectors)
  565. len
  566. (let ((vec (check-type vector? (car vectors)
  567. callee)))
  568. (compute-length (cdr vectors)
  569. (+ (vector-length vec) len)
  570. callee)))))
  571. (concatenate!
  572. (lambda (vectors target to)
  573. (if (null? vectors)
  574. target
  575. (let* ((vec1 (car vectors))
  576. (len (vector-length vec1)))
  577. (%vector-copy! target to vec1 0 len)
  578. (concatenate! (cdr vectors) target
  579. (+ to len)))))))
  580. (lambda (vectors callee)
  581. (cond ((null? vectors) ;+++
  582. (make-vector 0))
  583. ((null? (cdr vectors)) ;+++
  584. ;; Blech, we still have to allocate a new one.
  585. (let* ((vec (check-type vector? (car vectors) callee))
  586. (len (vector-length vec))
  587. (new (make-vector len)))
  588. (%vector-copy! new 0 vec 0 len)
  589. new))
  590. (else
  591. (let ((new-vector
  592. (make-vector (compute-length vectors 0 callee))))
  593. (concatenate! vectors new-vector 0)
  594. new-vector))))))
  595. ;;; --------------------
  596. ;;; Predicates
  597. ;;; (VECTOR? <value>) -> boolean
  598. ;;; [R5RS] Return #T if VALUE is a vector and #F if not.
  599. ;(define vector? vector?)
  600. ;;; (VECTOR-EMPTY? <vector>) -> boolean
  601. ;;; Return #T if VECTOR has zero elements in it, i.e. VECTOR's length
  602. ;;; is 0, and #F if not.
  603. (define (vector-empty? vec)
  604. (let ((vec (check-type vector? vec vector-empty?)))
  605. (zero? (vector-length vec))))
  606. ;;; (VECTOR= <elt=?> <vector> ...) -> boolean
  607. ;;; (ELT=? <value> <value>) -> boolean
  608. ;;; Determine vector equality generalized across element comparators.
  609. ;;; Vectors A and B are equal iff their lengths are the same and for
  610. ;;; each respective elements E_a and E_b (element=? E_a E_b) returns
  611. ;;; a true value. ELT=? is always applied to two arguments. Element
  612. ;;; comparison must be consistent wtih EQ?; that is, if (eq? E_a E_b)
  613. ;;; results in a true value, then (ELEMENT=? E_a E_b) must result in a
  614. ;;; true value. This may be exploited to avoid multiple unnecessary
  615. ;;; element comparisons. (This implementation does, but does not deal
  616. ;;; with the situation that ELEMENT=? is EQ? to avoid more unnecessary
  617. ;;; comparisons, but I believe this optimization is probably fairly
  618. ;;; insignificant.)
  619. ;;;
  620. ;;; If the number of vector arguments is zero or one, then #T is
  621. ;;; automatically returned. If there are N vector arguments,
  622. ;;; VECTOR_1 VECTOR_2 ... VECTOR_N, then VECTOR_1 & VECTOR_2 are
  623. ;;; compared; if they are equal, the vectors VECTOR_2 ... VECTOR_N
  624. ;;; are compared. The precise order in which ELT=? is applied is not
  625. ;;; specified.
  626. (define (vector= elt=? . vectors)
  627. (let ((elt=? (check-type procedure? elt=? vector=)))
  628. (cond ((null? vectors)
  629. #t)
  630. ((null? (cdr vectors))
  631. (check-type vector? (car vectors) vector=)
  632. #t)
  633. (else
  634. (let loop ((vecs vectors))
  635. (let ((vec1 (check-type vector? (car vecs) vector=))
  636. (vec2+ (cdr vecs)))
  637. (or (null? vec2+)
  638. (and (binary-vector= elt=? vec1 (car vec2+))
  639. (loop vec2+)))))))))
  640. (define (binary-vector= elt=? vector-a vector-b)
  641. (or (eq? vector-a vector-b) ;+++
  642. (let ((length-a (vector-length vector-a))
  643. (length-b (vector-length vector-b)))
  644. (letrec ((loop (lambda (i)
  645. (or (= i length-a)
  646. (and (< i length-b)
  647. (test (vector-ref vector-a i)
  648. (vector-ref vector-b i)
  649. i)))))
  650. (test (lambda (elt-a elt-b i)
  651. (and (or (eq? elt-a elt-b) ;+++
  652. (elt=? elt-a elt-b))
  653. (loop (+ i 1))))))
  654. (and (= length-a length-b)
  655. (loop 0))))))
  656. ;;; --------------------
  657. ;;; Selectors
  658. ;;; (VECTOR-REF <vector> <index>) -> value
  659. ;;; [R5RS] Return the value that the location in VECTOR at INDEX is
  660. ;;; mapped to in the store.
  661. ;(define vector-ref vector-ref)
  662. ;;; (VECTOR-LENGTH <vector>) -> exact, nonnegative integer
  663. ;;; [R5RS] Return the length of VECTOR.
  664. ;(define vector-length vector-length)
  665. ;;; --------------------
  666. ;;; Iteration
  667. ;;; (VECTOR-FOLD <kons> <initial-knil> <vector> ...) -> knil
  668. ;;; (KONS <knil> <elt> ...) -> knil' ; N vectors -> N+1 args
  669. ;;; The fundamental vector iterator. KONS is iterated over each
  670. ;;; index in all of the vectors in parallel, stopping at the end of
  671. ;;; the shortest; KONS is applied to an argument list of (list I
  672. ;;; STATE (vector-ref VEC I) ...), where STATE is the current state
  673. ;;; value -- the state value begins with KNIL and becomes whatever
  674. ;;; KONS returned at the respective iteration --, and I is the
  675. ;;; current index in the iteration. The iteration is strictly left-
  676. ;;; to-right.
  677. ;;; (vector-fold KONS KNIL (vector E_1 E_2 ... E_N))
  678. ;;; <=>
  679. ;;; (KONS (... (KONS (KONS KNIL E_1) E_2) ... E_N-1) E_N)
  680. (define (vector-fold kons knil vec . vectors)
  681. (let ((kons (check-type procedure? kons vector-fold))
  682. (vec (check-type vector? vec vector-fold)))
  683. (if (null? vectors)
  684. (%vector-fold1 kons knil (vector-length vec) vec)
  685. (%vector-fold2+ kons knil
  686. (%smallest-length vectors
  687. (vector-length vec)
  688. vector-fold)
  689. (cons vec vectors)))))
  690. ;;; (VECTOR-FOLD-RIGHT <kons> <initial-knil> <vector> ...) -> knil
  691. ;;; (KONS <knil> <elt> ...) -> knil' ; N vectors => N+1 args
  692. ;;; The fundamental vector recursor. Iterates in parallel across
  693. ;;; VECTOR ... right to left, applying KONS to the elements and the
  694. ;;; current state value; the state value becomes what KONS returns
  695. ;;; at each next iteration. KNIL is the initial state value.
  696. ;;; (vector-fold-right KONS KNIL (vector E_1 E_2 ... E_N))
  697. ;;; <=>
  698. ;;; (KONS (... (KONS (KONS KNIL E_N) E_N-1) ... E_2) E_1)
  699. ;;;
  700. ;;; Not implemented in terms of a more primitive operations that might
  701. ;;; called %VECTOR-FOLD-RIGHT due to the fact that it wouldn't be very
  702. ;;; useful elsewhere.
  703. (define vector-fold-right
  704. (letrec ((loop1 (lambda (kons knil vec i)
  705. (if (negative? i)
  706. knil
  707. (loop1 kons (kons i knil (vector-ref vec i))
  708. vec
  709. (- i 1)))))
  710. (loop2+ (lambda (kons knil vectors i)
  711. (if (negative? i)
  712. knil
  713. (loop2+ kons
  714. (apply kons i knil
  715. (vectors-ref vectors i))
  716. vectors
  717. (- i 1))))))
  718. (lambda (kons knil vec . vectors)
  719. (let ((kons (check-type procedure? kons vector-fold-right))
  720. (vec (check-type vector? vec vector-fold-right)))
  721. (if (null? vectors)
  722. (loop1 kons knil vec (- (vector-length vec) 1))
  723. (loop2+ kons knil (cons vec vectors)
  724. (- (%smallest-length vectors
  725. (vector-length vec)
  726. vector-fold-right)
  727. 1)))))))
  728. ;;; (VECTOR-MAP <f> <vector> ...) -> vector
  729. ;;; (F <elt> ...) -> value ; N vectors -> N args
  730. ;;; Constructs a new vector of the shortest length of the vector
  731. ;;; arguments. Each element at index I of the new vector is mapped
  732. ;;; from the old vectors by (F I (vector-ref VECTOR I) ...). The
  733. ;;; dynamic order of application of F is unspecified.
  734. (define (vector-map f vec . vectors)
  735. (let ((f (check-type procedure? f vector-map))
  736. (vec (check-type vector? vec vector-map)))
  737. (if (null? vectors)
  738. (let ((len (vector-length vec)))
  739. (%vector-map1! f (make-vector len) vec len))
  740. (let ((len (%smallest-length vectors
  741. (vector-length vec)
  742. vector-map)))
  743. (%vector-map2+! f (make-vector len) (cons vec vectors)
  744. len)))))
  745. ;;; (VECTOR-MAP! <f> <vector> ...) -> unspecified
  746. ;;; (F <elt> ...) -> element' ; N vectors -> N args
  747. ;;; Similar to VECTOR-MAP, but rather than mapping the new elements
  748. ;;; into a new vector, the new mapped elements are destructively
  749. ;;; inserted into the first vector. Again, the dynamic order of
  750. ;;; application of F is unspecified, so it is dangerous for F to
  751. ;;; manipulate the first VECTOR.
  752. (define (vector-map! f vec . vectors)
  753. (let ((f (check-type procedure? f vector-map!))
  754. (vec (check-type vector? vec vector-map!)))
  755. (if (null? vectors)
  756. (%vector-map1! f vec vec (vector-length vec))
  757. (%vector-map2+! f vec (cons vec vectors)
  758. (%smallest-length vectors
  759. (vector-length vec)
  760. vector-map!)))
  761. (unspecified-value)))
  762. ;;; (VECTOR-FOR-EACH <f> <vector> ...) -> unspecified
  763. ;;; (F <elt> ...) ; N vectors -> N args
  764. ;;; Simple vector iterator: applies F to each index in the range [0,
  765. ;;; LENGTH), where LENGTH is the length of the smallest vector
  766. ;;; argument passed, and the respective element at that index. In
  767. ;;; contrast with VECTOR-MAP, F is reliably applied to each
  768. ;;; subsequent elements, starting at index 0 from left to right, in
  769. ;;; the vectors.
  770. (define vector-for-each
  771. (letrec ((for-each1
  772. (lambda (f vec i len)
  773. (cond ((< i len)
  774. (f i (vector-ref vec i))
  775. (for-each1 f vec (+ i 1) len)))))
  776. (for-each2+
  777. (lambda (f vecs i len)
  778. (cond ((< i len)
  779. (apply f i (vectors-ref vecs i))
  780. (for-each2+ f vecs (+ i 1) len))))))
  781. (lambda (f vec . vectors)
  782. (let ((f (check-type procedure? f vector-for-each))
  783. (vec (check-type vector? vec vector-for-each)))
  784. (if (null? vectors)
  785. (for-each1 f vec 0 (vector-length vec))
  786. (for-each2+ f (cons vec vectors) 0
  787. (%smallest-length vectors
  788. (vector-length vec)
  789. vector-for-each)))))))
  790. ;;; (VECTOR-COUNT <predicate?> <vector> ...)
  791. ;;; -> exact, nonnegative integer
  792. ;;; (PREDICATE? <index> <value> ...) ; N vectors -> N+1 args
  793. ;;; PREDICATE? is applied element-wise to the elements of VECTOR ...,
  794. ;;; and a count is tallied of the number of elements for which a
  795. ;;; true value is produced by PREDICATE?. This count is returned.
  796. (define (vector-count pred? vec . vectors)
  797. (let ((pred? (check-type procedure? pred? vector-count))
  798. (vec (check-type vector? vec vector-count)))
  799. (if (null? vectors)
  800. (%vector-fold1 (lambda (index count elt)
  801. (if (pred? index elt)
  802. (+ count 1)
  803. count))
  804. 0
  805. (vector-length vec)
  806. vec)
  807. (%vector-fold2+ (lambda (index count . elts)
  808. (if (apply pred? index elts)
  809. (+ count 1)
  810. count))
  811. 0
  812. (%smallest-length vectors
  813. (vector-length vec)
  814. vector-count)
  815. (cons vec vectors)))))
  816. ;;; --------------------
  817. ;;; Searching
  818. ;;; (VECTOR-INDEX <predicate?> <vector> ...)
  819. ;;; -> exact, nonnegative integer or #F
  820. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  821. ;;; Search left-to-right across VECTOR ... in parallel, returning the
  822. ;;; index of the first set of values VALUE ... such that (PREDICATE?
  823. ;;; VALUE ...) returns a true value; if no such set of elements is
  824. ;;; reached, return #F.
  825. (define (vector-index pred? vec . vectors)
  826. (vector-index/skip pred? vec vectors vector-index))
  827. ;;; (VECTOR-SKIP <predicate?> <vector> ...)
  828. ;;; -> exact, nonnegative integer or #F
  829. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  830. ;;; (vector-index (lambda elts (not (apply PREDICATE? elts)))
  831. ;;; VECTOR ...)
  832. ;;; Like VECTOR-INDEX, but find the index of the first set of values
  833. ;;; that do _not_ satisfy PREDICATE?.
  834. (define (vector-skip pred? vec . vectors)
  835. (vector-index/skip (lambda elts (not (apply pred? elts)))
  836. vec vectors
  837. vector-skip))
  838. ;;; Auxiliary for VECTOR-INDEX & VECTOR-SKIP
  839. (define vector-index/skip
  840. (letrec ((loop1 (lambda (pred? vec len i)
  841. (cond ((= i len) #f)
  842. ((pred? (vector-ref vec i)) i)
  843. (else (loop1 pred? vec len (+ i 1))))))
  844. (loop2+ (lambda (pred? vectors len i)
  845. (cond ((= i len) #f)
  846. ((apply pred? (vectors-ref vectors i)) i)
  847. (else (loop2+ pred? vectors len
  848. (+ i 1)))))))
  849. (lambda (pred? vec vectors callee)
  850. (let ((pred? (check-type procedure? pred? callee))
  851. (vec (check-type vector? vec callee)))
  852. (if (null? vectors)
  853. (loop1 pred? vec (vector-length vec) 0)
  854. (loop2+ pred? (cons vec vectors)
  855. (%smallest-length vectors
  856. (vector-length vec)
  857. callee)
  858. 0))))))
  859. ;;; (VECTOR-INDEX-RIGHT <predicate?> <vector> ...)
  860. ;;; -> exact, nonnegative integer or #F
  861. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  862. ;;; Right-to-left variant of VECTOR-INDEX.
  863. (define (vector-index-right pred? vec . vectors)
  864. (vector-index/skip-right pred? vec vectors vector-index-right))
  865. ;;; (VECTOR-SKIP-RIGHT <predicate?> <vector> ...)
  866. ;;; -> exact, nonnegative integer or #F
  867. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  868. ;;; Right-to-left variant of VECTOR-SKIP.
  869. (define (vector-skip-right pred? vec . vectors)
  870. (vector-index/skip-right (lambda elts (not (apply pred? elts)))
  871. vec vectors
  872. vector-index-right))
  873. (define vector-index/skip-right
  874. (letrec ((loop1 (lambda (pred? vec i)
  875. (cond ((negative? i) #f)
  876. ((pred? (vector-ref vec i)) i)
  877. (else (loop1 pred? vec (- i 1))))))
  878. (loop2+ (lambda (pred? vectors i)
  879. (cond ((negative? i) #f)
  880. ((apply pred? (vectors-ref vectors i)) i)
  881. (else (loop2+ pred? vectors (- i 1)))))))
  882. (lambda (pred? vec vectors callee)
  883. (let ((pred? (check-type procedure? pred? callee))
  884. (vec (check-type vector? vec callee)))
  885. (if (null? vectors)
  886. (loop1 pred? vec (- (vector-length vec) 1))
  887. (loop2+ pred? (cons vec vectors)
  888. (- (%smallest-length vectors
  889. (vector-length vec)
  890. callee)
  891. 1)))))))
  892. ;;; (VECTOR-BINARY-SEARCH <vector> <value> <cmp> [<start> <end>])
  893. ;;; -> exact, nonnegative integer or #F
  894. ;;; (CMP <value1> <value2>) -> integer
  895. ;;; positive -> VALUE1 > VALUE2
  896. ;;; zero -> VALUE1 = VALUE2
  897. ;;; negative -> VALUE1 < VALUE2
  898. ;;; Perform a binary search through VECTOR for VALUE, comparing each
  899. ;;; element to VALUE with CMP.
  900. (define (vector-binary-search vec value cmp . maybe-start+end)
  901. (let ((cmp (check-type procedure? cmp vector-binary-search)))
  902. (let-vector-start+end vector-binary-search vec maybe-start+end
  903. (start end)
  904. (let loop ((start start) (end end) (j #f))
  905. (let ((i (quotient (+ start end) 2)))
  906. (if (or (= start end) (and j (= i j)))
  907. #f
  908. (let ((comparison
  909. (check-type integer?
  910. (cmp (vector-ref vec i) value)
  911. `(,cmp for ,vector-binary-search))))
  912. (cond ((zero? comparison) i)
  913. ((positive? comparison) (loop start i i))
  914. (else (loop i end i))))))))))
  915. ;;; (VECTOR-ANY <pred?> <vector> ...) -> value
  916. ;;; Apply PRED? to each parallel element in each VECTOR ...; if PRED?
  917. ;;; should ever return a true value, immediately stop and return that
  918. ;;; value; otherwise, when the shortest vector runs out, return #F.
  919. ;;; The iteration and order of application of PRED? across elements
  920. ;;; is of the vectors is strictly left-to-right.
  921. (define vector-any
  922. (letrec ((loop1 (lambda (pred? vec i len len-1)
  923. (and (not (= i len))
  924. (if (= i len-1)
  925. (pred? (vector-ref vec i))
  926. (or (pred? (vector-ref vec i))
  927. (loop1 pred? vec (+ i 1)
  928. len len-1))))))
  929. (loop2+ (lambda (pred? vectors i len len-1)
  930. (and (not (= i len))
  931. (if (= i len-1)
  932. (apply pred? (vectors-ref vectors i))
  933. (or (apply pred? (vectors-ref vectors i))
  934. (loop2+ pred? vectors (+ i 1)
  935. len len-1)))))))
  936. (lambda (pred? vec . vectors)
  937. (let ((pred? (check-type procedure? pred? vector-any))
  938. (vec (check-type vector? vec vector-any)))
  939. (if (null? vectors)
  940. (let ((len (vector-length vec)))
  941. (loop1 pred? vec 0 len (- len 1)))
  942. (let ((len (%smallest-length vectors
  943. (vector-length vec)
  944. vector-any)))
  945. (loop2+ pred? (cons vec vectors) 0 len (- len 1))))))))
  946. ;;; (VECTOR-EVERY <pred?> <vector> ...) -> value
  947. ;;; Apply PRED? to each parallel value in each VECTOR ...; if PRED?
  948. ;;; should ever return #F, immediately stop and return #F; otherwise,
  949. ;;; if PRED? should return a true value for each element, stopping at
  950. ;;; the end of the shortest vector, return the last value that PRED?
  951. ;;; returned. In the case that there is an empty vector, return #T.
  952. ;;; The iteration and order of application of PRED? across elements
  953. ;;; is of the vectors is strictly left-to-right.
  954. (define vector-every
  955. (letrec ((loop1 (lambda (pred? vec i len len-1)
  956. (or (= i len)
  957. (if (= i len-1)
  958. (pred? (vector-ref vec i))
  959. (and (pred? (vector-ref vec i))
  960. (loop1 pred? vec (+ i 1)
  961. len len-1))))))
  962. (loop2+ (lambda (pred? vectors i len len-1)
  963. (or (= i len)
  964. (if (= i len-1)
  965. (apply pred? (vectors-ref vectors i))
  966. (and (apply pred? (vectors-ref vectors i))
  967. (loop2+ pred? vectors (+ i 1)
  968. len len-1)))))))
  969. (lambda (pred? vec . vectors)
  970. (let ((pred? (check-type procedure? pred? vector-every))
  971. (vec (check-type vector? vec vector-every)))
  972. (if (null? vectors)
  973. (let ((len (vector-length vec)))
  974. (loop1 pred? vec 0 len (- len 1)))
  975. (let ((len (%smallest-length vectors
  976. (vector-length vec)
  977. vector-every)))
  978. (loop2+ pred? (cons vec vectors) 0 len (- len 1))))))))
  979. ;;; --------------------
  980. ;;; Mutators
  981. ;;; (VECTOR-SET! <vector> <index> <value>) -> unspecified
  982. ;;; [R5RS] Assign the location at INDEX in VECTOR to VALUE.
  983. ;(define vector-set! vector-set!)
  984. ;;; (VECTOR-SWAP! <vector> <index1> <index2>) -> unspecified
  985. ;;; Swap the values in the locations at INDEX1 and INDEX2.
  986. (define (vector-swap! vec i j)
  987. (let ((vec (check-type vector? vec vector-swap!)))
  988. (let ((i (check-index vec i vector-swap!))
  989. (j (check-index vec j vector-swap!)))
  990. (let ((x (vector-ref vec i)))
  991. (vector-set! vec i (vector-ref vec j))
  992. (vector-set! vec j x)))))
  993. ;;; (VECTOR-FILL! <vector> <value> [<start> <end>]) -> unspecified
  994. ;;; [R5RS+] Fill the locations in VECTOR between START, whose default
  995. ;;; is 0, and END, whose default is the length of VECTOR, with VALUE.
  996. ;;;
  997. ;;; This one can probably be made really fast natively.
  998. (define vector-fill!
  999. ; (let ((%vector-fill! vector-fill!)) ; Take the native one, under
  1000. ; the assumption that it's
  1001. ; faster, so we can use it if
  1002. ; there are no optional
  1003. ; arguments.
  1004. (lambda (vec value . maybe-start+end)
  1005. (if (null? maybe-start+end)
  1006. (%vector-fill! vec value) ;+++
  1007. (let-vector-start+end vector-fill! vec maybe-start+end
  1008. (start end)
  1009. (do ((i start (+ i 1)))
  1010. ((= i end))
  1011. (vector-set! vec i value))))))
  1012. ; )
  1013. ;;; (VECTOR-COPY! <target> <tstart> <source> [<sstart> <send>])
  1014. ;;; -> unspecified
  1015. ;;; Copy the values in the locations in [SSTART,SEND) from SOURCE to
  1016. ;;; to TARGET, starting at TSTART in TARGET.
  1017. (define (vector-copy! target tstart source . maybe-sstart+send)
  1018. (let* ((target (check-type vector? target vector-copy!))
  1019. (tstart (check-index target tstart vector-copy!)))
  1020. (let-vector-start+end vector-copy! source maybe-sstart+send
  1021. (sstart send)
  1022. (let* ((source-length (vector-length source))
  1023. (lose (lambda (argument)
  1024. (error "vector range out of bounds"
  1025. argument
  1026. `(while calling ,vector-copy!)
  1027. `(target was ,target)
  1028. `(target-length was ,(vector-length target))
  1029. `(tstart was ,tstart)
  1030. `(source was ,source)
  1031. `(source-length was ,source-length)
  1032. `(sstart was ,sstart)
  1033. `(send was ,send)))))
  1034. (cond ((< sstart 0)
  1035. (lose '(sstart < 0)))
  1036. ((< send 0)
  1037. (lose '(send < 0)))
  1038. ((> sstart send)
  1039. (lose '(sstart > send)))
  1040. ((>= sstart source-length)
  1041. (lose '(sstart >= source-length)))
  1042. ((> send source-length)
  1043. (lose '(send > source-length)))
  1044. (else
  1045. (%vector-copy! target tstart
  1046. source sstart send)))))))
  1047. ;;; (VECTOR-REVERSE-COPY! <target> <tstart> <source> [<sstart> <send>])
  1048. (define (vector-reverse-copy! target tstart source . maybe-sstart+send)
  1049. (let* ((target (check-type vector? target vector-reverse-copy!))
  1050. (tstart (check-index target tstart vector-reverse-copy!)))
  1051. (let-vector-start+end vector-reverse-copy source maybe-sstart+send
  1052. (sstart send)
  1053. (let* ((source-length (vector-length source))
  1054. (lose (lambda (argument)
  1055. (error "vector range out of bounds"
  1056. argument
  1057. `(while calling ,vector-reverse-copy!)
  1058. `(target was ,target)
  1059. `(target-length was ,(vector-length target))
  1060. `(tstart was ,tstart)
  1061. `(source was ,source)
  1062. `(source-length was ,source-length)
  1063. `(sstart was ,sstart)
  1064. `(send was ,send)))))
  1065. (cond ((< sstart 0)
  1066. (lose '(sstart < 0)))
  1067. ((< send 0)
  1068. (lose '(send < 0)))
  1069. ((> sstart send)
  1070. (lose '(sstart > send)))
  1071. ((>= sstart source-length)
  1072. (lose '(sstart >= source-length)))
  1073. ((> send source-length)
  1074. (lose '(send > source-length)))
  1075. ((and (eq? target source)
  1076. (= sstart tstart))
  1077. (%vector-reverse! target tstart send))
  1078. ((and (eq? target source)
  1079. (or (between? sstart tstart send)
  1080. (between? tstart sstart
  1081. (+ tstart (- send sstart)))))
  1082. (error "vector range for self-copying overlaps"
  1083. vector-reverse-copy!
  1084. `(vector was ,target)
  1085. `(tstart was ,tstart)
  1086. `(sstart was ,sstart)
  1087. `(send was ,send)))
  1088. (else
  1089. (%vector-reverse-copy! target tstart
  1090. source sstart send)))))))
  1091. ;;; (VECTOR-REVERSE! <vector> [<start> <end>]) -> unspecified
  1092. ;;; Destructively reverse the contents of the sequence of locations
  1093. ;;; in VECTOR between START, whose default is 0, and END, whose
  1094. ;;; default is the length of VECTOR.
  1095. (define (vector-reverse! vec . start+end)
  1096. (let-vector-start+end vector-reverse! vec start+end
  1097. (start end)
  1098. (%vector-reverse! vec start end)))
  1099. ;;; --------------------
  1100. ;;; Conversion
  1101. ;;; (VECTOR->LIST <vector> [<start> <end>]) -> list
  1102. ;;; [R5RS+] Produce a list containing the elements in the locations
  1103. ;;; between START, whose default is 0, and END, whose default is the
  1104. ;;; length of VECTOR, from VECTOR.
  1105. (define vector->list
  1106. ; (let ((%vector->list vector->list))
  1107. (lambda (vec . maybe-start+end)
  1108. (if (null? maybe-start+end) ; Oughta use CASE-LAMBDA.
  1109. (%vector->list vec) ;+++
  1110. (let-vector-start+end vector->list vec maybe-start+end
  1111. (start end)
  1112. ;(unfold (lambda (i) ; No SRFI 1.
  1113. ; (< i start))
  1114. ; (lambda (i) (vector-ref vec i))
  1115. ; (lambda (i) (- i 1))
  1116. ; (- end 1))
  1117. (do ((i (- end 1) (- i 1))
  1118. (result '() (cons (vector-ref vec i) result)))
  1119. ((< i start) result))))))
  1120. ; )
  1121. ;;; (REVERSE-VECTOR->LIST <vector> [<start> <end>]) -> list
  1122. ;;; Produce a list containing the elements in the locations between
  1123. ;;; START, whose default is 0, and END, whose default is the length
  1124. ;;; of VECTOR, from VECTOR, in reverse order.
  1125. (define (reverse-vector->list vec . maybe-start+end)
  1126. (let-vector-start+end reverse-vector->list vec maybe-start+end
  1127. (start end)
  1128. ;(unfold (lambda (i) (= i end)) ; No SRFI 1.
  1129. ; (lambda (i) (vector-ref vec i))
  1130. ; (lambda (i) (+ i 1))
  1131. ; start)
  1132. (do ((i start (+ i 1))
  1133. (result '() (cons (vector-ref vec i) result)))
  1134. ((= i end) result))))
  1135. ;;; (LIST->VECTOR <list> [<start> <end>]) -> vector
  1136. ;;; [R5RS+] Produce a vector containing the elements in LIST, which
  1137. ;;; must be a proper list, between START, whose default is 0, & END,
  1138. ;;; whose default is the length of LIST. It is suggested that if the
  1139. ;;; length of LIST is known in advance, the START and END arguments
  1140. ;;; be passed, so that LIST->VECTOR need not call LENGTH to determine
  1141. ;;; the the length.
  1142. ;;;
  1143. ;;; This implementation diverges on circular lists, unless LENGTH fails
  1144. ;;; and causes - to fail as well. Given a LENGTH* that computes the
  1145. ;;; length of a list's cycle, this wouldn't diverge, and would work
  1146. ;;; great for circular lists.
  1147. (define list->vector
  1148. ; (let ((%list->vector list->vector))
  1149. (lambda (lst . maybe-start+end)
  1150. ;; Checking the type of a proper list is expensive, so we do it
  1151. ;; amortizedly, or let %LIST->VECTOR or LIST-TAIL do it.
  1152. (if (null? maybe-start+end) ; Oughta use CASE-LAMBDA.
  1153. (%list->vector lst) ;+++
  1154. ;; We can't use LET-VECTOR-START+END, because we're using the
  1155. ;; bounds of a _list_, not a vector.
  1156. (let*-optionals maybe-start+end
  1157. ((start 0)
  1158. (end (length lst))) ; Ugh -- LENGTH
  1159. (let ((start (check-type nonneg-int? start list->vector))
  1160. (end (check-type nonneg-int? end list->vector)))
  1161. ((lambda (f)
  1162. (vector-unfold f (- end start) (list-tail lst start)))
  1163. (lambda (index l)
  1164. (cond ((null? l)
  1165. (error "list was too short"
  1166. `(list was ,lst)
  1167. `(attempted end was ,end)
  1168. `(while calling ,list->vector)))
  1169. ((pair? l)
  1170. (values (car l) (cdr l)))
  1171. (else
  1172. ;; Make this look as much like what CHECK-TYPE
  1173. ;; would report as possible.
  1174. (error "erroneous value"
  1175. ;; We want SRFI 1's PROPER-LIST?, but it
  1176. ;; would be a waste to link all of SRFI
  1177. ;; 1 to this module for only the single
  1178. ;; function PROPER-LIST?.
  1179. (list list? lst)
  1180. `(while calling
  1181. ,list->vector)))))))))))
  1182. ; )
  1183. ;;; (REVERSE-LIST->VECTOR <list> [<start> <end>]) -> vector
  1184. ;;; Produce a vector containing the elements in LIST, which must be a
  1185. ;;; proper list, between START, whose default is 0, and END, whose
  1186. ;;; default is the length of LIST, in reverse order. It is suggested
  1187. ;;; that if the length of LIST is known in advance, the START and END
  1188. ;;; arguments be passed, so that REVERSE-LIST->VECTOR need not call
  1189. ;;; LENGTH to determine the the length.
  1190. ;;;
  1191. ;;; This also diverges on circular lists unless, again, LENGTH returns
  1192. ;;; something that makes - bork.
  1193. (define (reverse-list->vector lst . maybe-start+end)
  1194. (let*-optionals maybe-start+end
  1195. ((start 0)
  1196. (end (length lst))) ; Ugh -- LENGTH
  1197. (let ((start (check-type nonneg-int? start reverse-list->vector))
  1198. (end (check-type nonneg-int? end reverse-list->vector)))
  1199. ((lambda (f)
  1200. (vector-unfold-right f (- end start) (list-tail lst start)))
  1201. (lambda (index l)
  1202. (cond ((null? l)
  1203. (error "list too short"
  1204. `(list was ,lst)
  1205. `(attempted end was ,end)
  1206. `(while calling ,reverse-list->vector)))
  1207. ((pair? l)
  1208. (values (car l) (cdr l)))
  1209. (else
  1210. (error "erroneous value"
  1211. (list list? lst)
  1212. `(while calling ,reverse-list->vector)))))))))