srfi-43.scm 54 KB

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