mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Write a proper vector-map and vector-for-each for (rnrs base)
* module/rnrs/base.scm (vector-map vector-for-each): Rewrite to not be slow. * NEWS: Update.
This commit is contained in:
parent
5046385df8
commit
0bd7497b61
2 changed files with 81 additions and 9 deletions
9
NEWS
9
NEWS
|
@ -138,10 +138,6 @@ The Gnulib compatibility library has been updated, for the first time
|
||||||
since 2017 or so. We expect no functional change but look forward to
|
since 2017 or so. We expect no functional change but look forward to
|
||||||
any bug reports.
|
any bug reports.
|
||||||
|
|
||||||
** Optimized "eof-object?"
|
|
||||||
|
|
||||||
This predicate is now understood by the compiler.
|
|
||||||
|
|
||||||
* New interfaces and functionality
|
* New interfaces and functionality
|
||||||
|
|
||||||
** `call-with-port'
|
** `call-with-port'
|
||||||
|
@ -180,6 +176,11 @@ See "Syntax Case" in the manual.
|
||||||
|
|
||||||
See "Syntax Transformer Helpers" in the manual.
|
See "Syntax Transformer Helpers" in the manual.
|
||||||
|
|
||||||
|
* Optimizations
|
||||||
|
|
||||||
|
** eof-object?
|
||||||
|
** R6RS vector-map, vector-for-each
|
||||||
|
|
||||||
* Bug fixes
|
* Bug fixes
|
||||||
|
|
||||||
** Fix reverse-list->string docstring
|
** Fix reverse-list->string docstring
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; base.scm --- The R6RS base library
|
;;; base.scm --- The R6RS base library
|
||||||
|
|
||||||
;; Copyright (C) 2010, 2011, 2019 Free Software Foundation, Inc.
|
;; Copyright (C) 2010, 2011, 2019, 2021 Free Software Foundation, Inc.
|
||||||
;;
|
;;
|
||||||
;; This library is free software; you can redistribute it and/or
|
;; This library is free software; you can redistribute it and/or
|
||||||
;; modify it under the terms of the GNU Lesser General Public
|
;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -231,10 +231,81 @@
|
||||||
(and (rational-valued? x)
|
(and (rational-valued? x)
|
||||||
(= x (floor (real-part x)))))
|
(= x (floor (real-part x)))))
|
||||||
|
|
||||||
(define (vector-for-each proc . vecs)
|
;; Auxiliary procedure for vector-map and vector-for-each
|
||||||
(apply for-each (cons proc (map vector->list vecs))))
|
(define (vector-lengths who vs)
|
||||||
(define (vector-map proc . vecs)
|
(let ((lengths (map vector-length vs)))
|
||||||
(list->vector (apply map (cons proc (map vector->list vecs)))))
|
(unless (apply = lengths)
|
||||||
|
(error (string-append (symbol->string who)
|
||||||
|
": Vectors of uneven length.")
|
||||||
|
vs))
|
||||||
|
(car lengths)))
|
||||||
|
|
||||||
|
(define vector-map
|
||||||
|
(case-lambda
|
||||||
|
"(vector-map f vec2 vec2 ...) -> vector
|
||||||
|
|
||||||
|
Return a new vector of the size of the vector arguments, which must be
|
||||||
|
of equal length. Each element at index @var{i} of the new vector is
|
||||||
|
mapped from the old vectors by @code{(f (vector-ref vec1 i)
|
||||||
|
(vector-ref vec2 i) ...)}. The dynamic order of application of
|
||||||
|
@var{f} is unspecified."
|
||||||
|
((f v)
|
||||||
|
(let* ((len (vector-length v))
|
||||||
|
(result (make-vector len)))
|
||||||
|
(let loop ((i 0))
|
||||||
|
(unless (= i len)
|
||||||
|
(vector-set! result i (f (vector-ref v i)))
|
||||||
|
(loop (+ i 1))))
|
||||||
|
result))
|
||||||
|
((f v1 v2)
|
||||||
|
(let* ((len (vector-lengths 'vector-map (list v1 v2)))
|
||||||
|
(result (make-vector len)))
|
||||||
|
(let loop ((i 0))
|
||||||
|
(unless (= i len)
|
||||||
|
(vector-set! result
|
||||||
|
i
|
||||||
|
(f (vector-ref v1 i) (vector-ref v2 i)))
|
||||||
|
(loop (+ i 1)))
|
||||||
|
result)))
|
||||||
|
((f v . vs)
|
||||||
|
(let* ((vs (cons v vs))
|
||||||
|
(len (vector-lengths 'vector-map vs))
|
||||||
|
(result (make-vector len)))
|
||||||
|
(let loop ((i 0))
|
||||||
|
(unless (= i len)
|
||||||
|
(vector-set! result
|
||||||
|
i
|
||||||
|
(apply f (map (lambda (v) (vector-ref v i)) vs)))
|
||||||
|
(loop (+ i 1))))
|
||||||
|
result))))
|
||||||
|
|
||||||
|
(define vector-for-each
|
||||||
|
(case-lambda
|
||||||
|
"(vector-for-each f vec1 vec2 ...) -> unspecified
|
||||||
|
|
||||||
|
Call @code{(f (vector-ref vec1 i) (vector-ref vec2 i) ...)} for each index
|
||||||
|
in the provided vectors, which have to be of equal length. The iteration
|
||||||
|
is strictly left-to-right."
|
||||||
|
((f v)
|
||||||
|
(let ((len (vector-length v)))
|
||||||
|
(let loop ((i 0))
|
||||||
|
(unless (= i len)
|
||||||
|
(f (vector-ref v i))
|
||||||
|
(loop (+ i 1))))))
|
||||||
|
((f v1 v2)
|
||||||
|
(let ((len (vector-lengths 'vector-for-each (list v1 v2))))
|
||||||
|
(let loop ((i 0))
|
||||||
|
(unless (= i len)
|
||||||
|
(f (vector-ref v1 i) (vector-ref v2 i))
|
||||||
|
(loop (+ i 1))))))
|
||||||
|
((f v . vs)
|
||||||
|
(let* ((vs (cons v vs))
|
||||||
|
(len (vector-lengths 'vector-for-each vs)))
|
||||||
|
(let loop ((i 0))
|
||||||
|
(unless (= i len)
|
||||||
|
(apply f (map (lambda (v) (vector-ref v i)) vs))
|
||||||
|
(loop (+ i 1))))))))
|
||||||
|
|
||||||
|
|
||||||
(define-syntax define-proxy
|
(define-syntax define-proxy
|
||||||
(syntax-rules (@)
|
(syntax-rules (@)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue