From b8efd58aca7287d3150e0843e08e604e1372cade Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 17 Dec 2012 15:53:44 -0700 Subject: [PATCH] Array changes in response to user feedback (and my personal neuroses) * `list->array' now accepts an optional shape argument, and always returns an immutable array * `vector->array' now accepts an optional shape argument, and always returns a mutable array * Removed `make-mutable-array' because `vector->array' does its job now (I never liked the name anyway) * Renamed `unsafe-mutable-array' to `unsafe-vector->array' * Added optional type annotation to `array' macro to match `mutable-array' * Reworded error messages in array broadcasting functions * Made minor array doc fixes --- .../math/private/array/array-broadcast.rkt | 8 +- .../private/array/array-comprehension.rkt | 8 +- collects/math/private/array/array-convert.rkt | 2 - .../math/private/array/array-parallel.rkt | 4 +- collects/math/private/array/array-struct.rkt | 21 ++++- collects/math/private/array/array-syntax.rkt | 5 +- collects/math/private/array/mutable-array.rkt | 13 +-- .../private/array/typed-array-convert.rkt | 8 -- .../math/private/array/typed-array-struct.rkt | 25 +++-- .../private/array/typed-mutable-array.rkt | 31 ++++--- .../private/array/untyped-array-convert.rkt | 2 +- collects/math/scribblings/math-array.scrbl | 91 ++++++++++++------- collects/math/tests/array-tests.rkt | 36 ++++---- 13 files changed, 150 insertions(+), 104 deletions(-) diff --git a/collects/math/private/array/array-broadcast.rkt b/collects/math/private/array/array-broadcast.rkt index 63d40b1027..83775401c4 100644 --- a/collects/math/private/array/array-broadcast.rkt +++ b/collects/math/private/array/array-broadcast.rkt @@ -21,7 +21,7 @@ (let ([shift (- new-dims old-dims)]) (cond [(index? shift) shift] [else (error 'array-broadcast - "cannot broadcast to lower-dimensional array; given ~e and ~e" + "cannot broadcast to a lower-dimensional shape; given ~e and ~e" arr new-ds)]))) (define old-js (make-thread-local-indexes old-dims)) (define old-f (unsafe-array-proc arr)) @@ -95,8 +95,10 @@ (: array-shape-broadcast (case-> ((Listof Indexes) -> Indexes) ((Listof Indexes) (U #f #t 'permissive) -> Indexes))) (define (array-shape-broadcast dss [broadcasting (array-broadcasting)]) - (define (fail) (error 'array-shape-broadcast "incompatible array shapes (broadcasting ~v): ~a" - broadcasting (string-join (map (λ (ds) (format "~e" ds)) dss) ", "))) + (define (fail) (error 'array-shape-broadcast + "incompatible array shapes (array-broadcasting ~v): ~a" + broadcasting + (string-join (map (λ (ds) (format "~e" ds)) dss) ", "))) (cond [(empty? dss) #()] [else (for/fold ([new-ds (first dss)]) ([ds (in-list (rest dss))]) (shape-broadcast2 new-ds ds fail broadcasting))])) diff --git a/collects/math/private/array/array-comprehension.rkt b/collects/math/private/array/array-comprehension.rkt index fc5268b56a..46e040e2e9 100644 --- a/collects/math/private/array/array-comprehension.rkt +++ b/collects/math/private/array/array-comprehension.rkt @@ -23,14 +23,14 @@ ds (λ () (raise-argument-error 'name "Indexes" ds)))]) (define vs (for/vector #:length (array-shape-size ds) maybe-fill ... (clause ...) maybe-type ... body ...)) - (unsafe-mutable-array ds vs))))] + (unsafe-vector->array ds vs))))] [(_ name:id for/vector:id (clause ...) (~optional (~seq : A:expr)) body:expr ...+) (with-syntax ([(maybe-type ...) (if (attribute A) #'(: A) #'())]) (syntax/loc stx (let () (define vs (for/vector (clause ...) maybe-type ... body ...)) (define ds ((inst vector Index) (vector-length vs))) - (unsafe-mutable-array ds vs))))])) + (unsafe-vector->array ds vs))))])) (define-syntax-rule (for/array: e ...) (base-for/array: for/array: for/vector: e ...)) @@ -49,13 +49,13 @@ ds (λ () (raise-argument-error 'name "Indexes" ds)))]) (define vs (for/vector #:length (array-shape-size ds) maybe-fill ... (clause ...) body ...)) - (unsafe-mutable-array ds vs))))] + (unsafe-vector->array ds vs))))] [(_ name:id for/vector:id (clause ...) body:expr ...+) (syntax/loc stx (let () (define vs (for/vector (clause ...) body ...)) (define ds ((inst vector Index) (vector-length vs))) - (unsafe-mutable-array ds vs)))])) + (unsafe-vector->array ds vs)))])) (define-syntax-rule (for/array e ...) (base-for/array for/array for/vector e ...)) diff --git a/collects/math/private/array/array-convert.rkt b/collects/math/private/array/array-convert.rkt index f1cb9e5cb1..aa4ce5d304 100644 --- a/collects/math/private/array/array-convert.rkt +++ b/collects/math/private/array/array-convert.rkt @@ -15,8 +15,6 @@ vector*->array array->list* array->vector* - list->array - vector->array array->list array->vector) diff --git a/collects/math/private/array/array-parallel.rkt b/collects/math/private/array/array-parallel.rkt index fffbf53e56..0fb3b4b592 100644 --- a/collects/math/private/array/array-parallel.rkt +++ b/collects/math/private/array/array-parallel.rkt @@ -37,7 +37,7 @@ (define (parallel-array->mutable-array arr) (define size (array-size arr)) (cond - [(zero? size) (unsafe-mutable-array (array-shape arr) (vector))] + [(zero? size) (unsafe-vector->array (array-shape arr) (vector))] [else (define ds (array-shape arr)) (define dims (vector-length ds)) @@ -61,7 +61,7 @@ (for: ([f (in-list futures)]) (touch f)) - (unsafe-mutable-array ds vs))])) + (unsafe-vector->array ds vs))])) (: parallel-array-strict (All (A) ((Array A) -> (Array A)))) (define (parallel-array-strict arr) diff --git a/collects/math/private/array/array-struct.rkt b/collects/math/private/array/array-struct.rkt index e4d9e2f6c9..62a2fa6f62 100644 --- a/collects/math/private/array/array-struct.rkt +++ b/collects/math/private/array/array-struct.rkt @@ -4,13 +4,18 @@ typed/racket/base (for-syntax racket/base syntax/parse) "array-syntax.rkt" - (except-in "typed-array-struct.rkt" build-array build-strict-array)) + (except-in "typed-array-struct.rkt" + build-array + build-strict-array + list->array)) (require/untyped-contract (begin (require "typed-array-struct.rkt")) "typed-array-struct.rkt" [build-array (All (A) ((Vectorof Integer) ((Vectorof Index) -> A) -> (Array A)))] - [build-strict-array (All (A) ((Vectorof Integer) ((Vectorof Index) -> A) -> (Array A)))]) + [build-strict-array (All (A) ((Vectorof Integer) ((Vectorof Index) -> A) -> (Array A)))] + [list->array (All (A) (case-> ((Listof A) -> (Array A)) + ((Vectorof Integer) (Listof A) -> (Array A))))]) (define-syntax array? (make-rename-transformer #'Array?)) (define-syntax array-shape (make-rename-transformer #'Array-shape)) @@ -27,10 +32,13 @@ array-strict array-strict! array-strict? - make-unsafe-array-proc build-array + build-strict-array + list->array + make-unsafe-array-proc unsafe-build-array unsafe-build-strict-array + unsafe-list->array unsafe-array-proc array-lazy array @@ -46,8 +54,11 @@ array-lift-comparison) (define-syntax (array stx) - (syntax-parse stx - [(_ e:expr) (syntax/loc stx (array/syntax array list flat-list->array e))] + (syntax-parse stx #:literals (:) + [(_ e:expr) + (syntax/loc stx (array/syntax array list unsafe-list->array e))] + [(_ e:expr : T:expr) + (syntax/loc stx (array/syntax array (inst list T) unsafe-list->array e))] [_:id (raise-syntax-error 'array "not allowed as an expression" stx)])) (define-syntax-rule (array-strict arr-expr) diff --git a/collects/math/private/array/array-syntax.rkt b/collects/math/private/array/array-syntax.rkt index 9d3674eed0..f9fa8afe05 100644 --- a/collects/math/private/array/array-syntax.rkt +++ b/collects/math/private/array/array-syntax.rkt @@ -1,6 +1,7 @@ #lang racket/base -(require (for-syntax racket/base)) +(require (for-syntax racket/base) + (only-in typed/racket/base inst Index)) (provide array/syntax) @@ -40,4 +41,4 @@ (with-syntax ([(d ...) ds] [(v ...) (syntax-vector-flatten #'e)]) (syntax/loc stx - (->array (vector d ...) (constr v ...)))))])) + (->array ((inst vector Index) d ...) (constr v ...)))))])) diff --git a/collects/math/private/array/mutable-array.rkt b/collects/math/private/array/mutable-array.rkt index e214d952dc..2bca6df4e3 100644 --- a/collects/math/private/array/mutable-array.rkt +++ b/collects/math/private/array/mutable-array.rkt @@ -5,20 +5,21 @@ (for-syntax racket/base syntax/parse) "array-syntax.rkt" (except-in "typed-mutable-array.rkt" - make-mutable-array)) + vector->array)) (require/untyped-contract (begin (require "typed-mutable-array.rkt")) "typed-mutable-array.rkt" - [make-mutable-array (All (A) ((Vectorof Integer) (Vectorof A) -> (Mutable-Array A)))]) + [vector->array (All (A) (case-> ((Vectorof A) -> (Mutable-Array A)) + ((Vectorof Integer) (Vectorof A) -> (Mutable-Array A))))]) (provide ;; Mutable-Array Mutable-Array mutable-array? mutable-array-data - make-mutable-array - unsafe-mutable-array + vector->array + unsafe-vector->array mutable-array-copy mutable-array ;; Conversion @@ -28,7 +29,7 @@ (define-syntax (mutable-array stx) (syntax-parse stx #:literals (:) [(_ e:expr) - (syntax/loc stx (array/syntax mutable-array vector make-mutable-array e))] + (syntax/loc stx (array/syntax mutable-array vector unsafe-vector->array e))] [(_ e:expr : T:expr) - (syntax/loc stx (array/syntax mutable-array (inst vector T) make-mutable-array e))] + (syntax/loc stx (array/syntax mutable-array (inst vector T) unsafe-vector->array e))] [_:id (raise-syntax-error 'mutable-array "not allowed as an expression" stx)])) diff --git a/collects/math/private/array/typed-array-convert.rkt b/collects/math/private/array/typed-array-convert.rkt index 544170ec65..371a095364 100644 --- a/collects/math/private/array/typed-array-convert.rkt +++ b/collects/math/private/array/typed-array-convert.rkt @@ -11,14 +11,6 @@ ;; Conversion to arrays (make-to-array-functions list*->array vector*->array) -(: list->array (All (A) ((Listof A) -> (Array A)))) -(define (list->array xs) - (vector->array (list->vector xs))) - -(: vector->array (All (A) ((Vectorof A) -> (Array A)))) -(define (vector->array xs) - (unsafe-mutable-array ((inst vector Index) (vector-length xs)) xs)) - (: array->list (All (A) ((Array A) -> (Listof A)))) (define (array->list arr) (vector->list (array->vector arr))) diff --git a/collects/math/private/array/typed-array-struct.rkt b/collects/math/private/array/typed-array-struct.rkt index 565aea7b39..e2f6b1d8d9 100644 --- a/collects/math/private/array/typed-array-struct.rkt +++ b/collects/math/private/array/typed-array-struct.rkt @@ -113,12 +113,25 @@ (unsafe-build-strict-array ds (λ: ([js : Indexes]) (proc (vector->immutable-vector js)))))) -(: flat-list->array (All (A) (In-Indexes (Listof A) -> (Array A)))) -(define (flat-list->array ds lst) - (let ([ds (check-array-shape ds (λ () (raise-argument-error 'array "(Vectorof Index)" ds)))]) - (define vs (list->vector lst)) - (unsafe-build-strict-array - ds (λ: ([js : Indexes]) (unsafe-vector-ref vs (unsafe-array-index->value-index ds js)))))) +(: unsafe-list->array (All (A) (Indexes (Listof A) -> (Array A)))) +(define (unsafe-list->array ds xs) + (define vs (list->vector xs)) + (unsafe-build-strict-array + ds (λ: ([js : Indexes]) (unsafe-vector-ref vs (unsafe-array-index->value-index ds js))))) + +(: list->array (All (A) (case-> ((Listof A) -> (Array A)) + (In-Indexes (Listof A) -> (Array A))))) +(define list->array + (case-lambda + [(xs) (unsafe-list->array ((inst vector Index) (length xs)) xs)] + [(ds xs) + (let* ([ds (check-array-shape + ds (λ () (raise-argument-error 'list->array "(Vectorof Index)" 0 ds xs)))] + [size (array-shape-size ds)] + [n (length xs)]) + (if (= size n) + (unsafe-list->array ds xs) + (raise-argument-error 'list->array (format "List of length ~e" size) 1 ds xs)))])) (: array-lazy (All (A) ((Array A) -> (Array A)))) (define (array-lazy arr) diff --git a/collects/math/private/array/typed-mutable-array.rkt b/collects/math/private/array/typed-mutable-array.rkt index c926bb48ec..6e6c99ee97 100644 --- a/collects/math/private/array/typed-mutable-array.rkt +++ b/collects/math/private/array/typed-mutable-array.rkt @@ -17,28 +17,33 @@ (define mutable-array? Mutable-Array?) (define mutable-array-data Mutable-Array-data) -(: unsafe-mutable-array (All (A) (Indexes (Vectorof A) -> (Mutable-Array A)))) -(define (unsafe-mutable-array ds vs) +(: unsafe-vector->array (All (A) (Indexes (Vectorof A) -> (Mutable-Array A)))) +(define (unsafe-vector->array ds vs) (define proc (make-unsafe-array-proc ds (λ (j) (unsafe-vector-ref vs j)))) (define set-proc (make-unsafe-array-set-proc A ds (λ (j v) (unsafe-vector-set! vs j v)))) (Mutable-Array ds (vector-length vs) (box #t) void proc set-proc vs)) -(: make-mutable-array (All (A) (In-Indexes (Vectorof A) -> (Mutable-Array A)))) -(define (make-mutable-array ds vs) - (let* ([ds (check-array-shape - ds (λ () (raise-argument-error 'make-mutable-array "(Vectorof Index)" 0 ds vs)))] - [size (array-shape-size ds)] - [n (vector-length vs)]) - (cond [(= size n) (unsafe-mutable-array ds vs)] - [else (raise-argument-error 'mutable-array (format "Vector of length ~e" size) 1 ds vs)]))) +(: vector->array (All (A) (case-> ((Vectorof A) -> (Mutable-Array A)) + (In-Indexes (Vectorof A) -> (Mutable-Array A))))) +(define vector->array + (case-lambda + [(vs) (unsafe-vector->array ((inst vector Index) (vector-length vs)) vs)] + [(ds vs) + (let* ([ds (check-array-shape + ds (λ () (raise-argument-error 'vector->array "(Vectorof Index)" 0 ds vs)))] + [size (array-shape-size ds)] + [n (vector-length vs)]) + (if (= size n) + (unsafe-vector->array ds vs) + (raise-argument-error 'vector->array (format "Vector of length ~e" size) 1 ds vs)))])) (: mutable-array-copy (All (A) ((Mutable-Array A) -> (Mutable-Array A)))) (define (mutable-array-copy arr) - (unsafe-mutable-array (array-shape arr) (vector-copy-all (mutable-array-data arr)))) + (unsafe-vector->array (array-shape arr) (vector-copy-all (mutable-array-data arr)))) (: flat-vector->matrix : (All (A) (Index Index (Vectorof A) -> (Array A)))) (define (flat-vector->matrix m n v) - (make-mutable-array (vector m n) v)) + (vector->array (vector m n) v)) ;; =================================================================================================== ;; Conversions @@ -47,4 +52,4 @@ (define (array->mutable-array arr) (define ds (array-shape arr)) (define g (unsafe-array-proc arr)) - (unsafe-mutable-array ds (inline-build-array-data ds (λ (js j) (g js)) A))) + (unsafe-vector->array ds (inline-build-array-data ds (λ (js j) (g js)) A))) diff --git a/collects/math/private/array/untyped-array-convert.rkt b/collects/math/private/array/untyped-array-convert.rkt index 2e7a34975f..4365601d5d 100644 --- a/collects/math/private/array/untyped-array-convert.rkt +++ b/collects/math/private/array/untyped-array-convert.rkt @@ -87,7 +87,7 @@ (cond [(pred? lst) (unsafe-build-strict-array #() (λ (js) lst))] [ds (let ([ds (check-array-shape ds raise-shape-error)]) (define size (array-shape-size ds)) - (unsafe-mutable-array ds (list*->flat-vector lst size pred?)))] + (unsafe-vector->array ds (list*->flat-vector lst size pred?)))] [else (raise-shape-error)])) (: vector*->array (All (A) ((Vectorof* A) ((Vectorof* A) -> Any : A) -> (Array A)))) diff --git a/collects/math/scribblings/math-array.scrbl b/collects/math/scribblings/math-array.scrbl index 3082f4a782..c0f13ba618 100644 --- a/collects/math/scribblings/math-array.scrbl +++ b/collects/math/scribblings/math-array.scrbl @@ -24,9 +24,9 @@ @title[#:tag "arrays" #:style 'toc]{Arrays} @(author-neil) -@bold{Performance Warning:} Most of the array-producing functions exported by -@racketmodname[math/array] run 25-50 times slower in untyped Racket, due to the -overhead of checking higher-order contracts. We are working on it. +@bold{Performance Warning:} Indexing the elements of arrays created in untyped Racket +is currently 25-50 times slower than doing the same in Typed Racket, due to the overhead +of checking higher-order contracts. We are working on it. For now, if you need speed, use the @racketmodname[typed/racket] language. @@ -301,8 +301,8 @@ operations to succeed only if array shapes match exactly: (array* (index-array #(3 3)) (array 10)))] Another option is @hyperlink["http://www.r-project.org"]{R}-style permissive broadcasting, -which allows pointwise operations to @italic{always} succeed, by repeating any axis instead -of stretching just singleton axes: +which allows pointwise operations to @italic{always} succeed, by repeating shorter axes' rows +instead of repeating just singleton axes' rows: @interaction[#:eval typed-eval (define arr10 (array-map number->string (index-array #(10)))) (define arr3 (array-map number->string (index-array #(3)))) @@ -479,12 +479,14 @@ Returns the vector of data that @racket[arr] contains. @section{Construction} -@defform[(array #[#[...] ...])]{ +@defform/subs[(array #[#[...] ...] maybe-type-ann) + [(maybe-type-ann (code:line) (code:line : type))]]{ Creates a @tech{strict} @racket[Array] from nested rows of expressions. The vector syntax @racket[#[...]] delimits rows. These may be nested to any depth, and must have a -rectangular shape. Using square parentheses is not required, but is encouraged to help distinguish -array contents from array shapes and other vectors. +rectangular shape. Using square parentheses is not required, but is encouraged to help visually +distinguish array contents from array indexes and other vectors. +(See the examples for @racket[indexes-array] for an illustration.) @examples[#:eval typed-eval (array 0) @@ -492,13 +494,16 @@ array contents from array shapes and other vectors. (array #[#[1 2 3] #[4 5 6]]) (array #[#[1 2 3] #[4 5]])] As with the @racket[list] constructor, the type chosen for the array is the narrowest type -all the elements can have. Unlike @racket[list], because @racket[array] is syntax, the only way -to change the element type is to annotate the result. +all the elements can have. Unlike @racket[list], because @racket[array] is syntax, instantiating +@racket[array] with the desired element type is a syntax error: @interaction[#:eval typed-eval (list 1 2 3) (array #[1 2 3]) ((inst list Real) 1 2 3) - ((inst array Real) #[1 2 3]) + ((inst array Real) #[1 2 3])] +There are two easy ways to annotate the element type: +@interaction[#:eval typed-eval + (array #[1 2 3] : Real) (ann (array #[1 2 3]) (Array Real))] Annotating should rarely be necessary because the @racket[Array] type is covariant. @@ -509,6 +514,8 @@ Normally, the datums within literal vectors are implicitly quoted. However, when (array #[not okay]) (array #['this 'is 'okay]) (array #['#(an) '#(array) '#(of) '#(vectors)])] + +Another way to create an immutable, strict array from literal data is to use @racket[list->array]. } @defform/subs[(mutable-array #[#[...] ...] maybe-type-ann) @@ -528,6 +535,8 @@ the array's elements: arr (array-set! arr #(0) 10.0) arr] + +Another way to create a mutable array from literal data is to use @racket[vector->array]. } @defproc[(make-array [ds In-Indexes] [value A]) (Array A)]{ @@ -586,16 +595,6 @@ Printing a lazy array computes and caches all of its elements, as does applying @racket[array-strict!] to it. } -@defproc[(make-mutable-array [ds In-Indexes] [vs (Vectorof A)]) (Mutable-Array A)]{ -Returns a mutable array with @tech{shape} @racket[ds] and elements @racket[vs]; assumes -@racket[vs] are in row-major order. If there are too many or too few elements in @racket[vs], -@racket[(make-mutable-array ds vs)] raises an error. -@examples[#:eval typed-eval - (make-mutable-array #(3 3) #(0 1 2 3 4 5 6 7 8)) - (make-mutable-array #() #(singleton)) - (make-mutable-array #(4) #(1 2 3 4 5))] -} - @defproc[(array->mutable-array [arr (Array A)]) (Mutable-Array A)]{ Returns a mutable array with the same elements as @racket[arr]. The result is a copy of @racket[arr], even when @racket[arr] is mutable. @@ -664,37 +663,60 @@ This is used as an argument type to @racket[list*->array] and as the return type Like @racket[(Listof* A)], but for vectors. See @racket[vector*->array] and @racket[array->vector*]. } -@deftogether[(@defproc[(list->array [lst (Listof A)]) (Array A)] +@deftogether[(@defproc*[([(list->array [lst (Listof A)]) (Array A)] + [(list->array [ds In-Indexes] [lst (Listof A)]) (Array A)])] @defproc[(array->list [arr (Array A)]) (Listof A)])]{ -Convert lists to single-axis arrays and back. If @racket[arr] has no axes or more than one axis, -it is (conceptually) flattened before being converted to a list. +Convert lists to @tech{strict}, immutable arrays and back. + +The two-argument variant of @racket[list->array] assumes the elements in @racket[lst] are in +row-major order. + +For @racket[array->list], if @racket[arr] has no axes or more than one axis, it is (conceptually) +flattened before being converted to a list. + @examples[#:eval typed-eval (list->array '(1 2 3)) (list->array '((1 2 3) (4 5))) + (list->array #(2 2) '(1 2 3 4)) (array->list (array #[1 2 3])) (array->list (array 10)) (array->list (array #[#[1 2 3] #[4 5 6]]))] For conversion between nested lists and multidimensional arrays, see @racket[list*->array] and @racket[array->list*]. +For conversion from flat values to mutable arrays, see @racket[vector->array]. } -@deftogether[(@defproc[(vector->array [vec (Vectorof A)]) (Array A)] +@deftogether[(@defproc*[([(vector->array [vec (Vectorof A)]) (Mutable-Array A)] + [(vector->array [ds In-Indexes] [vec (Vectorof A)]) (Mutable-Array A)])] @defproc[(array->vector [arr (Array A)]) (Vectorof A)])]{ Like @racket[list->array] and @racket[array->list], but for vectors. +@examples[#:eval typed-eval + (vector->array #(1 2 3)) + (vector->array #((1 2 3) (4 5))) + (vector->array #(2 2) #(1 2 3 4)) + (array->vector (array #[1 2 3])) + (array->vector (array 10)) + (array->vector (array #[#[1 2 3] #[4 5 6]]))] +For conversion between nested vectors and multidimensional arrays, see @racket[vector*->array] and +@racket[array->vector*]. } @defproc[(list*->array [lsts (Listof* A)] [pred? ((Listof* A) -> Any : A)]) (Array A)]{ -Converts a nested list of elements of type @racket[A] to an array. The predicate @racket[pred?] -identifies elements of type @racket[A]. The shape of @racket[lsts] must be rectangular. +Converts a nested list of elements of type @racket[A] to a @tech{strict} array. +The predicate @racket[pred?] identifies elements of type @racket[A]. +The shape of @racket[lsts] must be rectangular. + @examples[#:eval typed-eval (list*->array 'singleton symbol?) (list*->array '(0 1 2 3) byte?) (list*->array (list (list (list 5) (list 2 3)) (list (list 4.0) (list 1.4 0.2 9.3))) (make-predicate (Listof Nonnegative-Real)))] -The last example demonstrates why a predicate is required. There is no well-typed Typed Racket -function that behaves like @racket[list*->array] but does not require @racket[pred?], because -without it, there is no way to distinguish between rows and elements. + +There is no well-typed Typed Racket function that behaves like @racket[list*->array] but does not +require @racket[pred?]. +Without an element predicate, there is no way to prove to the type checker that +@racket[list*->array]'s implementation correctly distinguishes elements from rows. } @defproc[(array->list* [arr (Array A)]) (Listof* A)]{ @@ -715,9 +737,10 @@ Like @racket[array->list*], but produces nested vectors of elements. } @defproc[(array-list->array [arrs (Listof (Array A))] [axis Integer 0]) (Array A)]{ -Concatenates @racket[arrs] along axis @racket[axis] to form a new array. If the arrays have -different shapes, they are broadcast first. The axis number @racket[axis] must be nonnegative -and @italic{no greater than} the number of axes after broadcasting. +Concatenates @racket[arrs] along axis @racket[axis] to form a new array. +If the arrays have different shapes, they are broadcast first. +The axis number @racket[axis] must be nonnegative and @italic{no greater than} the number of axes in +the highest dimensional array in @racket[arrs]. @examples[#:eval typed-eval (array-list->array (list (array 0) (array 1) (array 2) (array 3))) (array-list->array (list (array 0) (array 1) (array 2) (array 3)) 1) @@ -1756,7 +1779,7 @@ in-unsafe-array-indexes make-unsafe-array-set-proc make-unsafe-array-proc unsafe-build-array -unsafe-mutable-array +unsafe-vector->array unsafe-flarray unsafe-array-transform unsafe-array-axis-reduce diff --git a/collects/math/tests/array-tests.rkt b/collects/math/tests/array-tests.rkt index 948c618910..5118d379d5 100644 --- a/collects/math/tests/array-tests.rkt +++ b/collects/math/tests/array-tests.rkt @@ -48,7 +48,7 @@ (check-equal? (make-indexes-vector 2 3) #(#(0 0) #(0 1) #(0 2) #(1 0) #(1 1) #(1 2) #(2 0) #(2 1) #(2 2))) -(let ([arr (make-mutable-array #(4) #(a b c d))]) +(let ([arr (vector->array #(4) #(a b c d))]) (check-eq? arr (array-strict arr))) (let ([arr (build-array #() (λ (js) 'foo))]) @@ -87,34 +87,34 @@ ;; list*->array (check-equal? (list*->array 1.0 flonum?) - (make-mutable-array #() #(1.0))) + (vector->array #() #(1.0))) (check-equal? (list*->array '[] flonum?) - (make-mutable-array #(0) #())) + (vector->array #(0) #())) (check-equal? (list*->array '[[]] flonum?) - (make-mutable-array #(1 0) #())) + (vector->array #(1 0) #())) (check-equal? (list*->array '[1.0] flonum?) - (make-mutable-array #(1) #(1.0))) + (vector->array #(1) #(1.0))) (check-equal? (list*->array '[[1.0]] flonum?) - (make-mutable-array #(1 1) #(1.0))) + (vector->array #(1 1) #(1.0))) (check-equal? (list*->array '[[[1.0]]] flonum?) - (make-mutable-array #(1 1 1) #(1.0))) + (vector->array #(1 1 1) #(1.0))) (check-equal? (list*->array '() listof-flonum?) - (make-mutable-array #() #(()))) + (vector->array #() #(()))) (check-equal? (list*->array '[()] listof-flonum?) - (make-mutable-array #(1) #(()))) + (vector->array #(1) #(()))) (check-equal? (list*->array '[(1.0) (2.0)] listof-flonum?) - (make-mutable-array #(2) #((1.0) (2.0)))) + (vector->array #(2) #((1.0) (2.0)))) (check-equal? (list*->array '[((1.0)) ((2.0))] listof-flonum?) - (make-mutable-array #(2 1) #((1.0) (2.0)))) + (vector->array #(2 1) #((1.0) (2.0)))) ;; --------------------------------------------------------------------------------------------------- ;; array->list* @@ -156,22 +156,22 @@ ;; vector*->array (check-equal? (vector*->array 1.0 flonum?) - (make-mutable-array #() #(1.0))) + (vector->array #() #(1.0))) (check-equal? ((inst vector*->array Float) #() flonum?) - (make-mutable-array #(0) #())) + (vector->array #(0) #())) (check-equal? ((inst vector*->array Float) #(#()) flonum?) - (make-mutable-array #(1 0) #())) + (vector->array #(1 0) #())) (check-equal? ((inst vector*->array Float) #(1.0) flonum?) - (make-mutable-array #(1) #(1.0))) + (vector->array #(1) #(1.0))) (check-equal? ((inst vector*->array Float) #(#(1.0)) flonum?) - (make-mutable-array #(1 1) #(1.0))) + (vector->array #(1 1) #(1.0))) (check-equal? ((inst vector*->array Float) #(#(#(1.0))) flonum?) - (make-mutable-array #(1 1 1) #(1.0))) + (vector->array #(1 1 1) #(1.0))) ;; --------------------------------------------------------------------------------------------------- ;; array->vector @@ -303,7 +303,7 @@ (check-equal? (array-map (inst cons Float Float) (array #[1.0 2.0]) (array #[10.0 20.0])) - (make-mutable-array #(2) #[(1.0 . 10.0) (2.0 . 20.0)])) + (vector->array #(2) #[(1.0 . 10.0) (2.0 . 20.0)])) ;; --------------------------------------------------------------------------------------------------- ;; Fold