Skip to content

Commit

Permalink
implementation of Array class
Browse files Browse the repository at this point in the history
This adds a new class to the standard library (ARRAY :F :T) allows the
storage of elements of type :T inside of a storage type :F.

The class implements a few instances (which could be expanded to all
reasonable efficient types), and uses the convention of adding an 's'
to the base type (e.g., a storage of Double-Float is DoubleFloats). We
don't keep "legacy" '-' in existing names.

All operations become efficient Common Lisp code, up to inlining.
  • Loading branch information
stylewarning committed Oct 6, 2023
1 parent e3ba1c0 commit a41e501
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
1 change: 1 addition & 0 deletions coalton.asd
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
(:file "result")
(:file "tuple")
(:file "list")
(:file "array")
(:file "vector")
(:file "char")
(:file "string")
Expand Down
110 changes: 110 additions & 0 deletions library/array.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
(coalton-library/utils:defstdlib-package #:coalton-library/array
(:use
#:coalton
#:coalton-library/classes)
(:local-nicknames
(#:c #:coalton-library/math/complex)
(#:a #:coalton-library/math/arith))
(:export
#:Array
#:make
#:size
#:aref
#:set!

#:SingleFloats
#:DoubleFloats
#:ComplexSingleFloats
#:ComplexDoubleFloats))

(in-package #:coalton-library/array)

(named-readtables:in-readtable coalton:coalton)

#+coalton-release
(cl:declaim #.coalton-impl/settings:*coalton-optimize-library*)

;;; Class Implementation
(coalton-toplevel
;; The decision to use a functional dependency was an ergonomic one,
;; not a technical one. If we did not establish this dependency, we
;; would win flexibility (a single storage type can store multiple
;; data types), but we would lose a lot of practical ergonomics
;; (e.g., we would need Proxy types, calls to size would need to be
;; disambiguated, etc.).
;;
;; While we lose some flexibility, we still retain some. For
;; instance, we can have multiple storage types for double floats
;; (think: Lisp arrays, C arrays, GPU arrays, etc.).
(define-class (Array :f :t (:f -> :t))
"Establishes that `:f` can (only) store elements of type `:t`. The **storage type** `:f` implies the **stored type** `:t`.
The storage is expected to be sequential and efficient in random access."
(make (UFix -> :t -> :f))
(size (:f -> UFix))
(aref (:f -> UFix -> :t))
(set! (:f -> UFix -> :t -> Unit))))

;;; Built-In Storage Types
(cl:defmacro %define-unboxed-array (cl-type ct-type coalton-array-type)
`(coalton-toplevel
(repr :native (cl:simple-array ,cl-type (cl:*)))
(define-type ,coalton-array-type)

(define-instance (Array ,coalton-array-type ,ct-type)
(define (make n x)
(lisp ,coalton-array-type (n x)
(cl:make-array n :element-type ',cl-type :initial-element x)))
(define (size a)
(lisp UFix (a)
(cl:length a)))
(define (aref a n)
(lisp ,ct-type (a n)
(cl:aref a n)))
(define (set! a n x)
(lisp Unit (a n x)
(cl:setf (cl:aref a n) x)
Unit)))))

(%define-unboxed-array cl:single-float Single-Float SingleFloats)
(%define-unboxed-array cl:double-float Double-Float DoubleFloats)
(%define-unboxed-array (cl:complex cl:single-float) (c:Complex Single-Float) ComplexSingleFloats)
(%define-unboxed-array (cl:complex cl:double-float) (c:Complex Double-Float) ComplexDoubleFloats)

;;; Examples, to be deleted...
(coalton-toplevel
(define (%sum-array a n i s)
(if (< i n)
(%sum-array a n (a:1+ i) (+ s (aref a i)))
s))

(define (sum-array a)
(%sum-array a (size a) 0 0))

(declare map! (Array :f :t => (:t -> :t) -> :f -> Unit))
(define (map! f a)
(let ((s (size a))
(iter (fn (i)
(when (< i s)
(set! a i (f (aref a i)))
(iter (a:1+ i))))))
(iter 0)))

(declare double! ((Array :f :t) (Num :t) => :f -> Unit))
(define double! (map! (* 2)))

(define (ex1)
(let ((a (the DoubleFloats (make 10 1.0d0))))
(sum-array a)))

(define (ex2)
(let ((a (the ComplexDoubleFloats (make 10 (c:complex 1.0d0 -1.0d0)))))
(double! a)
(sum-array a)))

(monomorphize)
(declare sum-array-df (DoubleFloats -> Double-Float))
(define sum-array-df sum-array))

#+sb-package-locks
(sb-ext:lock-package "COALTON-LIBRARY/ARRAY")
1 change: 1 addition & 0 deletions src/doc/generate-documentation.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
coalton-library/list
coalton-library/result
coalton-library/cell
coalton-library/array
coalton-library/vector
coalton-library/slice
coalton-library/hashtable
Expand Down

0 comments on commit a41e501

Please sign in to comment.